在jsp servlet中我們通常使用Servlet Filter控制用戶是否登入, 是否有權(quán)限轉(zhuǎn)到某個頁面。在struts2中我們應(yīng)該會想到他的攔截器(Interceptor), Interceptor在struts2中起著非常重要的作用。 很多struts2中的功能都是使用Interceptor實現(xiàn)的。
需求:簡單的登入界面,讓用戶輸入用戶名、密碼、記住密碼(remember me)。 如果用戶選中remember me的話, 下次就不需要再登入了(使用cookie實現(xiàn), 用需要點擊logout取消remeber me功能)。 如果用戶起始輸入的地址不是登入頁面的話,在用戶登入之后需要轉(zhuǎn)到用戶輸入的起始地址。
我們先看看LoginInterceptor.java
- package com.javaeye.dengyin2000.wallet.interceptor;
-
- import java.util.Map;
-
- import javax.servlet.http.Cookie;
- import javax.servlet.http.HttpServletRequest;
-
- import org.apache.commons.lang.StringUtils;
- import org.apache.struts2.StrutsStatics;
-
- import com.javaeye.dengyin2000.wallet.dao.UserDAO;
- import com.javaeye.dengyin2000.wallet.dao.UserNotFoundException;
- import com.javaeye.dengyin2000.wallet.domains.User;
- import com.opensymphony.xwork2.ActionContext;
- import com.opensymphony.xwork2.ActionInvocation;
- import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
-
- public class LoginInterceptor extends AbstractInterceptor {
- public static final String USER_SESSION_KEY="wallet.session.user";
- public static final String COOKIE_REMEMBERME_KEY="wallet.cookie.rememberme";
- public static final String GOING_TO_URL_KEY="GOING_TO";
-
- private UserDAO userDao;
-
- @Override
- public String intercept(ActionInvocation invocation) throws Exception {
-
- ActionContext actionContext = invocation.getInvocationContext();
- HttpServletRequest request= (HttpServletRequest) actionContext.get(StrutsStatics.HTTP_REQUEST);
-
- Map session = actionContext.getSession();
- if (session != null && session.get(USER_SESSION_KEY) != null){
- return invocation.invoke();
- }
-
- Cookie[] cookies = request.getCookies();
- if (cookies!=null) {
- for (Cookie cookie : cookies) {
- if (COOKIE_REMEMBERME_KEY.equals(cookie.getName())) {
- String value = cookie.getValue();
- if (StringUtils.isNotBlank(value)) {
- String[] split = value.split("==");
- String userName = split[0];
- String password = split[1];
- try {
- User user = userDao
- .attemptLogin(userName, password);
- session.put(USER_SESSION_KEY, user);
- } catch (UserNotFoundException e) {
- setGoingToURL(session, invocation);
- return "login";
- }
- } else {
- setGoingToURL(session, invocation);
- return "login";
- }
- return invocation.invoke();
- }
- }
- }
- setGoingToURL(session, invocation);
- return "login";
- }
-
- private void setGoingToURL(Map session, ActionInvocation invocation){
- String url = "";
- String namespace = invocation.getProxy().getNamespace();
- if (StringUtils.isNotBlank(namespace) && !namespace.equals("/")){
- url = url + namespace;
- }
- String actionName = invocation.getProxy().getActionName();
- if (StringUtils.isNotBlank(actionName)){
- url = url + "/" + actionName + ".action";
- }
- session.put(GOING_TO_URL_KEY, url);
- }
-
- public UserDAO getUserDao() {
- return userDao;
- }
-
- public void setUserDao(UserDAO userDao) {
- this.userDao = userDao;
- }
-
- }
package com.javaeye.dengyin2000.wallet.interceptor;import java.util.Map;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServletRequest;import org.apache.commons.lang.StringUtils;import org.apache.struts2.StrutsStatics;import com.javaeye.dengyin2000.wallet.dao.UserDAO;import com.javaeye.dengyin2000.wallet.dao.UserNotFoundException;import com.javaeye.dengyin2000.wallet.domains.User;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionInvocation;import com.opensymphony.xwork2.interceptor.AbstractInterceptor;public class LoginInterceptor extends AbstractInterceptor {public static final String USER_SESSION_KEY="wallet.session.user";public static final String COOKIE_REMEMBERME_KEY="wallet.cookie.rememberme";public static final String GOING_TO_URL_KEY="GOING_TO";private UserDAO userDao;@Overridepublic String intercept(ActionInvocation invocation) throws Exception {ActionContext actionContext = invocation.getInvocationContext();HttpServletRequest request= (HttpServletRequest) actionContext.get(StrutsStatics.HTTP_REQUEST);Map session = actionContext.getSession();if (session != null && session.get(USER_SESSION_KEY) != null){return invocation.invoke();}Cookie[] cookies = request.getCookies();if (cookies!=null) {for (Cookie cookie : cookies) {if (COOKIE_REMEMBERME_KEY.equals(cookie.getName())) {String value = cookie.getValue();if (StringUtils.isNotBlank(value)) {String[] split = value.split("==");String userName = split[0];String password = split[1];try {User user = userDao.attemptLogin(userName, password);session.put(USER_SESSION_KEY, user);} catch (UserNotFoundException e) {setGoingToURL(session, invocation);return "login";}} else {setGoingToURL(session, invocation);return "login";}return invocation.invoke();}}}setGoingToURL(session, invocation);return "login";}private void setGoingToURL(Map session, ActionInvocation invocation){String url = "";String namespace = invocation.getProxy().getNamespace();if (StringUtils.isNotBlank(namespace) && !namespace.equals("/")){url = url + namespace;}String actionName = invocation.getProxy().getActionName();if (StringUtils.isNotBlank(actionName)){url = url + "/" + actionName + ".action";}session.put(GOING_TO_URL_KEY, url);}public UserDAO getUserDao() {return userDao;}public void setUserDao(UserDAO userDao) {this.userDao = userDao;}}
首先判斷session中有沒有用戶信息, 如果有的話繼續(xù), 如果沒有的話,檢查cookie中有沒有rememberme的值,如果有的話,用==分割, 取得用戶名密碼進(jìn)行登入。如果沒有這個用戶的話,記錄下request的action地址然后轉(zhuǎn)到登入頁面。如果驗證有這個用戶,則繼續(xù)下面的interceptor。 如果cookie中沒有信息的話,則記錄request的action地址然后轉(zhuǎn)到登入頁面。 以上就是LoginInterceptor的全部代碼。
下面我們看看struts.xml
- <?xml version="1.0" encoding="UTF-8"?>
-
- <!DOCTYPE struts PUBLIC
- "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
- "http://struts.apache.org/dtds/struts-2.0.dtd">
-
- <struts>
- <package name="default" extends="struts-default">
- <interceptors>
- <interceptor name="loginInterceptor" class="loginInterceptor"></interceptor>
- <interceptor-stack name="loginDefaultStack">
- <interceptor-ref name="loginInterceptor"></interceptor-ref>
- <interceptor-ref name="defaultStack"></interceptor-ref>
- </interceptor-stack>
- </interceptors>
- <default-interceptor-ref name="loginDefaultStack"></default-interceptor-ref>
- <global-results>
- <result name="login" type="redirect">/login.jsp</result>
- </global-results>
- <action name="index" class="indexAction">
- <result>/index.jsp</result>
- </action>
- <action name="logout" class="logoutAction"></action>
-
- <action name="login" class="loginAction" method="login">
- <result type="redirect">${goingToURL}</result>
- <result name="input">/login.jsp</result>
- <interceptor-ref name="defaultStack"></interceptor-ref>
- </action>
-
- <action name="register" class="registerAction">
- <result type="redirect">/login.jsp</result>
- <result name="input">/register.jsp</result>
- <interceptor-ref name="defaultStack"></interceptor-ref>
- </action>
- </package>
- </struts>
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts PUBLIC"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN""http://struts.apache.org/dtds/struts-2.0.dtd"><struts><package name="default" extends="struts-default"><interceptors><interceptor name="loginInterceptor" class="loginInterceptor"></interceptor><interceptor-stack name="loginDefaultStack"><interceptor-ref name="loginInterceptor"></interceptor-ref><interceptor-ref name="defaultStack"></interceptor-ref></interceptor-stack></interceptors><default-interceptor-ref name="loginDefaultStack"></default-interceptor-ref><global-results><result name="login" type="redirect">/login.jsp</result></global-results><action name="index" class="indexAction"><result>/index.jsp</result></action><action name="logout" class="logoutAction"></action><action name="login" class="loginAction" method="login"><result type="redirect">${goingToURL}</result><result name="input">/login.jsp</result><interceptor-ref name="defaultStack"></interceptor-ref></action><action name="register" class="registerAction"><result type="redirect">/login.jsp</result><result name="input">/register.jsp</result><interceptor-ref name="defaultStack"></interceptor-ref></action></package></struts>
我們是使用的默認(rèn)的interceptor stack是loginInterceptor, 如果你需要讓不登入的用戶也能訪問的話,你需要配置你的action使用defaultStack。 我們這里的login, register使用的就是defaultStack。 這里要注意的是success的result是我們用LoginInterceptor設(shè)過來的值。 這樣我們就能夠轉(zhuǎn)到用戶輸入的起始頁面。 下面我們再來看看login.jsp 和 loginAction
- <%@taglib prefix="s" uri="/struts-tags" %>
- <%@ page language="java" contentType="text/html; charset=UTF-8"
- pageEncoding="UTF-8"%>
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <title>Wallet-Login</title>
- </head>
- <body>
- <h2>Login</h2>
- <s:actionmessage/>
- <s:actionerror/>
- <s:form action="login" method="post" validate="false" theme="xhtml">
- <s:textfield name="loginName" label="Username"></s:textfield><br/>
- <s:password name="password" label="Password"></s:password><br/>
- <s:checkbox label="Remember Me" name="rememberMe"></s:checkbox>
- <s:submit value="%{'Login'}"></s:submit>
- </s:form>
- <a href="register.jsp">Register</a>
- </body>
- </html>
<%@taglib prefix="s" uri="/struts-tags" %><%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Wallet-Login</title></head><body><h2>Login</h2><s:actionmessage/><s:actionerror/><s:form action="login" method="post" validate="false" theme="xhtml"><s:textfield name="loginName" label="Username"></s:textfield><br/><s:password name="password" label="Password"></s:password><br/><s:checkbox label="Remember Me" name="rememberMe"></s:checkbox><s:submit value="%{'Login'}"></s:submit></s:form><a href="register.jsp">Register</a></body></html>
- package com.javaeye.dengyin2000.wallet.actions;
-
- import java.util.Map;
-
- import javax.servlet.http.Cookie;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- import org.apache.commons.lang.StringUtils;
- import org.apache.struts2.interceptor.CookiesAware;
- import org.apache.struts2.interceptor.ServletRequestAware;
- import org.apache.struts2.interceptor.ServletResponseAware;
- import org.apache.struts2.interceptor.SessionAware;
-
- import com.javaeye.dengyin2000.wallet.dao.UserDAO;
- import com.javaeye.dengyin2000.wallet.dao.UserNotFoundException;
- import com.javaeye.dengyin2000.wallet.domains.User;
- import com.javaeye.dengyin2000.wallet.interceptor.LoginInterceptor;
- import com.opensymphony.xwork2.ActionSupport;
-
- public class LoginAction extends ActionSupport implements ServletResponseAware, ServletRequestAware, SessionAware, CookiesAware{
-
- private UserDAO userDao;
- private String loginName;
- private String password;
- private boolean rememberMe;
- private HttpServletResponse response;
- private HttpServletRequest request;
- private Map session;
- private Map cookies;
- private String goingToURL;
- public String getGoingToURL() {
- return goingToURL;
- }
- public void setGoingToURL(String goingToURL) {
- this.goingToURL = goingToURL;
- }
- public boolean isRememberMe() {
- return rememberMe;
- }
- public void setRememberMe(boolean rememberMe) {
- this.rememberMe = rememberMe;
- }
- public String getLoginName() {
- return loginName;
- }
- public void setLoginName(String loginName) {
- this.loginName = loginName;
- }
- public String getPassword() {
- return password;
- }
- public void setPassword(String password) {
- this.password = password;
- }
-
-
- public String login()throws Exception{
- try {
- User user = userDao.attemptLogin(loginName, password);
- if (rememberMe){
- Cookie cookie = new Cookie(LoginInterceptor.COOKIE_REMEMBERME_KEY, user.getLoginName() + "==" + user.getPassword());
- cookie.setMaxAge(60 * 60 * 24 * 14);
- response.addCookie(cookie);
- }
- session.put(LoginInterceptor.USER_SESSION_KEY, user);
- String goingToURL = (String) session.get(LoginInterceptor.GOING_TO_URL_KEY);
- if (StringUtils.isNotBlank(goingToURL)){
- setGoingToURL(goingToURL);
- session.remove(LoginInterceptor.GOING_TO_URL_KEY);
- }else{
- setGoingToURL("index.action");
- }
- return SUCCESS;
- } catch (UserNotFoundException e) {
- addActionMessage("user name or password is not corrected.");
- return INPUT;
- }
- }
- public UserDAO getUserDao() {
- return userDao;
- }
- public void setUserDao(UserDAO userDao) {
- this.userDao = userDao;
- }
- public void setServletResponse(HttpServletResponse response) {
- this.response = response;
- }
- public void setServletRequest(HttpServletRequest request) {
- this.request = request;
- }
- public void setSession(Map session) {
- this.session = session;
- }
- public void setCookiesMap(Map cookies) {
- this.cookies = cookies;
- }
- }
package com.javaeye.dengyin2000.wallet.actions;import java.util.Map;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.lang.StringUtils;import org.apache.struts2.interceptor.CookiesAware;import org.apache.struts2.interceptor.ServletRequestAware;import org.apache.struts2.interceptor.ServletResponseAware;import org.apache.struts2.interceptor.SessionAware;import com.javaeye.dengyin2000.wallet.dao.UserDAO;import com.javaeye.dengyin2000.wallet.dao.UserNotFoundException;import com.javaeye.dengyin2000.wallet.domains.User;import com.javaeye.dengyin2000.wallet.interceptor.LoginInterceptor;import com.opensymphony.xwork2.ActionSupport;public class LoginAction extends ActionSupport implements ServletResponseAware, ServletRequestAware, SessionAware, CookiesAware{private UserDAO userDao;private String loginName;private String password;private boolean rememberMe;private HttpServletResponse response;private HttpServletRequest request;private Map session;private Map cookies;private String goingToURL;public String getGoingToURL() {return goingToURL;}public void setGoingToURL(String goingToURL) {this.goingToURL = goingToURL;}public boolean isRememberMe() {return rememberMe;}public void setRememberMe(boolean rememberMe) {this.rememberMe = rememberMe;}public String getLoginName() {return loginName;}public void setLoginName(String loginName) {this.loginName = loginName;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String login()throws Exception{try {User user = userDao.attemptLogin(loginName, password);if (rememberMe){Cookie cookie = new Cookie(LoginInterceptor.COOKIE_REMEMBERME_KEY, user.getLoginName() + "==" + user.getPassword());cookie.setMaxAge(60 * 60 * 24 * 14);response.addCookie(cookie);}session.put(LoginInterceptor.USER_SESSION_KEY, user);String goingToURL = (String) session.get(LoginInterceptor.GOING_TO_URL_KEY);if (StringUtils.isNotBlank(goingToURL)){setGoingToURL(goingToURL);session.remove(LoginInterceptor.GOING_TO_URL_KEY);}else{setGoingToURL("index.action");}return SUCCESS;} catch (UserNotFoundException e) {addActionMessage("user name or password is not corrected.");return INPUT;}}public UserDAO getUserDao() {return userDao;}public void setUserDao(UserDAO userDao) {this.userDao = userDao;}public void setServletResponse(HttpServletResponse response) {this.response = response;}public void setServletRequest(HttpServletRequest request) {this.request = request;}public void setSession(Map session) {this.session = session;}public void setCookiesMap(Map cookies) {this.cookies = cookies;}}
差不多就是這么多代碼了。 最后看看logoutAction
- package com.javaeye.dengyin2000.wallet.actions;
-
- import javax.servlet.http.Cookie;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
-
- import org.apache.struts2.interceptor.ServletRequestAware;
- import org.apache.struts2.interceptor.ServletResponseAware;
-
- import com.javaeye.dengyin2000.wallet.interceptor.LoginInterceptor;
- import com.opensymphony.xwork2.ActionSupport;
-
- public class LogoutAction extends ActionSupport implements ServletRequestAware , ServletResponseAware{
-
- private HttpServletRequest request;
- private HttpServletResponse response;
-
- public String execute() throws Exception{
- HttpSession session = request.getSession(false);
- if (session!=null)
- session.removeAttribute(LoginInterceptor.USER_SESSION_KEY);
-
- Cookie[] cookies = request.getCookies();
- if (cookies!=null) {
- for (Cookie cookie : cookies) {
- if (LoginInterceptor.COOKIE_REMEMBERME_KEY.equals(cookie
- .getName())) {
- cookie.setValue("");
- cookie.setMaxAge(0);
- response.addCookie(cookie);
- return "login";
- }
- }
- }
- return "login";
- }
-
- public void setServletRequest(HttpServletRequest request) {
- this.request = request;
- }
-
- public void setServletResponse(HttpServletResponse response) {
- this.response = response;
- }
-
- }
package com.javaeye.dengyin2000.wallet.actions;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import org.apache.struts2.interceptor.ServletRequestAware;import org.apache.struts2.interceptor.ServletResponseAware;import com.javaeye.dengyin2000.wallet.interceptor.LoginInterceptor;import com.opensymphony.xwork2.ActionSupport;public class LogoutAction extends ActionSupport implements ServletRequestAware , ServletResponseAware{private HttpServletRequest request;private HttpServletResponse response;public String execute() throws Exception{HttpSession session = request.getSession(false);if (session!=null)session.removeAttribute(LoginInterceptor.USER_SESSION_KEY);Cookie[] cookies = request.getCookies();if (cookies!=null) {for (Cookie cookie : cookies) {if (LoginInterceptor.COOKIE_REMEMBERME_KEY.equals(cookie.getName())) {cookie.setValue("");cookie.setMaxAge(0);response.addCookie(cookie);return "login";}}}return "login";}public void setServletRequest(HttpServletRequest request) {this.request = request;}public void setServletResponse(HttpServletResponse response) {this.response = response;}}
這里需要注意的是需要把cookie也清理下。
applicationContext-struts.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <!DOCTYPE beans PUBLIC
- "-//SPRING//DTD BEAN//EN"
- "http://www.springframework.org/dtd/spring-beans.dtd">
-
- <beans>
- <!-- Example of SAF2 action instantiated by Spring -->
- <!-- bean id="helloWorldAction" class="tutorial.HelloWorldAction" singleton="false" />
- -->
- <bean id="indexAction" class="com.javaeye.dengyin2000.wallet.actions.IndexAction" singleton="false"></bean>
- <bean id="loginAction" class="com.javaeye.dengyin2000.wallet.actions.LoginAction" singleton="false">
- <property name="userDao" ref="userDao" />
- </bean>
-
- <bean id="logoutAction" class="com.javaeye.dengyin2000.wallet.actions.LogoutAction" singleton="false"></bean>
-
- <bean id="registerAction" class="com.javaeye.dengyin2000.wallet.actions.RegisterAction" singleton="false"></bean>
-
- <!-- the following is struts2 interceptors -->
- <bean id="loginInterceptor" class="com.javaeye.dengyin2000.wallet.interceptor.LoginInterceptor">
- <property name="userDao" ref="userDao" />
- </bean>
-
- <bean id="userDao" class="com.javaeye.dengyin2000.wallet.dao.UserDAOImpl">
- </bean>
- </beans>