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