ログインしているユーザー情報の取得(続き)
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>