11月27日

ログインしているユーザー情報の取得(続き)

Principalによるユーザー名の取得

コントローラーの引数に Principal を追加すると、Spring が自動的にログイン中のユーザー情報を設定してくれる。

HomeController.java

    @RequestMapping(value = "/home", method = RequestMethod.GET)
    public String home(Model model, Principal p) {
        model.addAttribute("name", p.getName());
        model.addAttribute("title", "成績の検索");
        return "home";
    }

Userインスタンスの取得

Principal から取得できるのは名前だけなので、詳細な情報を取得するには、名前をキーにしてUsersテーブルから取得する必要がある。
Usersテーブルから名前をキーにして取得するために、DAOにメソッド定義 findByName() を追加する。

UserDao.java

    public interface UserDao<T> {
        public List<T> getAll();
        public T findById(long id);
        public T findByName(String name);
        public void add(T data);
        public void update(T data);
        public void delete(T data);
        public void delete(long id);
    }

UserDaoImpl で、検索機能を実装する。

UserDaoImpl.java

public class UserDaoImpl implements UserDao<User> {
    private static EntityManagerFactory factory = Persistence.createEntityManagerFactory("persistenceUnit");

    public List<User> getAll() {
        EntityManager manager = factory.createEntityManager();
        CriteriaBuilder builder = manager.getCriteriaBuilder();
        CriteriaQuery<User> query = builder.createQuery(User.class);
        Root<User> root = query.from(User.class);
        query.select(root);
        List<User> list = null;
        try {
            list = manager.createQuery(query).getResultList();
        } catch (NoResultException e) {
            //
        }
        return list;
    }

    public User findById(long id) {
        EntityManager manager = factory.createEntityManager();
        CriteriaBuilder builder = manager.getCriteriaBuilder();
        CriteriaQuery<User> query = builder.createQuery(User.class);
        Root<User> root = query.from(User.class);
        query.select(root).where(builder.equal(root.get("id"), id));
        User u = null;
        try {
            u = manager.createQuery(query).getSingleResult();
        } catch (NoResultException e) {
            //
        }
        return u;
    }

    public User findByName(String name) {
        EntityManager manager = factory.createEntityManager();
        CriteriaBuilder builder = manager.getCriteriaBuilder();
        CriteriaQuery<User> query = builder.createQuery(User.class);
		Root<User> root = query.from(User.class);
		query.select(root).where(builder.equal(root.get("name"), name));
		User u = null;
		try {
			u = manager.createQuery(query).getSingleResult();
		} catch (NoResultException e) {
			//
		}
		return u;
	}

	public void add(User user) {
    	EntityManager manager = factory.createEntityManager();
    	EntityTransaction transaction = manager.getTransaction();
    	transaction.begin();
    	User u = findById(user.getId());
    	if (u == null) {
    		try {
    			manager.persist(user);
    			transaction.commit();
    		} catch (PersistenceException e) {
    			transaction.rollback();
    		}
        	manager.close();
    	} else {
    		throw new PersistenceException("Duplicate user-id : " + u.getId());
    	}
	}

	public void update(User user) {
    	EntityManager manager = factory.createEntityManager();
    	EntityTransaction transaction = manager.getTransaction();
    	transaction.begin();
        try {
            manager.merge(user);
            transaction.commit();
        } catch (PersistenceException e) {
            transaction.rollback();
        }
        manager.close();
    }

    public void delete(User user) {
        EntityManager manager = factory.createEntityManager();
        EntityTransaction transaction = manager.getTransaction();
        transaction.begin();
        try {
            manager.remove(user);
            transaction.commit();
        } catch (PersistenceException e) {
            transaction.rollback();
        }
        manager.close();
    }

    public void delete(long id) {
        delete(findById(id));
    }

}

コントローラでは、DAOを通してUserを取得し、UserのインスタンスをJSPに渡す。

HomeController.java

    @RequestMapping(value = "/home", method = RequestMethod.GET)
    public String home(Model model, Principal p) {
        UserDao<User> dao = new UserDaoImpl();
        User u = dao.findByName(p.getName());
        model.addAttribute("user", u);
        model.addAttribute("title", "成績の検索");
        return "home";
    }

JSPでは、渡された User のインスタンスから必要な情報を取得するように変更する。

<p>ようこそ ${user.name} さん。</p>

ログインエラーメッセージのカスタマイズ

JSPにエラーメッセージを書き込む方法でよければ、次の方法で可能。

まず spring-securlty.xml で、認証エラーのハンドラを登録する。
defaultFailuerUrl で、パラメータとして error=true を渡せば、JSP側で取得できる。

spring-security.xml

    <sec:http auto-config="true">
        <intercept-url pattern="/**" access="ROLE_USER" />
        <sec:form-login login-page="/login.jsp"
            default-target-url="/home"
            authentication-failure-handler-ref="authenticationFailureHandler" />
        <sec:logout
            logout-url="/logout"
            logout-success-url="/"
            invalidate-session="true"
            delete-cookies="JSESSIONID" />
    </sec:http>

    <beans:bean id="authenticationFailureHandler"
        class="org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler">
        <beans:property name="defaultFailureUrl" value="/login.jsp?error=true"/>
        <beans:property name="useForward" value="true"/>
    </beans:bean>

JSPでは、errorパラメータの有無をチェックしてメッセージを表示する。

login.jsp

<h3>ユーザー名とパスワードを入力してください</h3>

<c:if test="${param.error}">
  <span style="color:#ff0000;">ユーザー名またはパスワードが違います。</span>
</c:if>

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です