在jsp servlet中我們通常使用Servlet Filter控制用戶是否登入, 是否有權限轉到某個頁面。在struts2中我們應該會想到他的攔截器(Interceptor), Interceptor在struts2中起著非常重要的作用。 很多struts2中的功能都是使用Interceptor實現的。

需求:簡單的登入界面,讓用戶輸入用戶名、密碼、記住密碼(remember me)。 如果用戶選中remember me的話, 下次就不需要再登入了(使用cookie實現, 用需要點擊logout取消remeber me功能)。 如果用戶起始輸入的地址不是登入頁面的話,在用戶登入之后需要轉到用戶輸入的起始地址。

我們先看看LoginInterceptor.java
Java代碼
  1. package?com.javaeye.dengyin2000.wallet.interceptor; ??
  2. ??
  3. import?java.util.Map; ??
  4. ??
  5. import?javax.servlet.http.Cookie; ??
  6. import?javax.servlet.http.HttpServletRequest; ??
  7. ??
  8. import?org.apache.commons.lang.StringUtils; ??
  9. import?org.apache.struts2.StrutsStatics; ??
  10. ??
  11. import?com.javaeye.dengyin2000.wallet.dao.UserDAO; ??
  12. import?com.javaeye.dengyin2000.wallet.dao.UserNotFoundException; ??
  13. import?com.javaeye.dengyin2000.wallet.domains.User; ??
  14. import?com.opensymphony.xwork2.ActionContext; ??
  15. import?com.opensymphony.xwork2.ActionInvocation; ??
  16. import?com.opensymphony.xwork2.interceptor.AbstractInterceptor; ??
  17. ??
  18. public?class?LoginInterceptor?extends?AbstractInterceptor?{ ??
  19. ????public?static?final?String?USER_SESSION_KEY="wallet.session.user"; ??
  20. ????public?static?final?String?COOKIE_REMEMBERME_KEY="wallet.cookie.rememberme"; ??
  21. ????public?static?final?String?GOING_TO_URL_KEY="GOING_TO"; ??
  22. ???? ??
  23. ????private?UserDAO?userDao; ??
  24. ??
  25. ????@Override??
  26. ????public?String?intercept(ActionInvocation?invocation)?throws?Exception?{ ??
  27. ???????? ??
  28. ????????ActionContext?actionContext?=?invocation.getInvocationContext(); ??
  29. ????????HttpServletRequest?request=?(HttpServletRequest)?actionContext.get(StrutsStatics.HTTP_REQUEST); ??
  30. ???????? ??
  31. ????????Map?session?=?actionContext.getSession(); ??
  32. ????????if?(session?!=?null?&&?session.get(USER_SESSION_KEY)?!=?null){ ??
  33. ????????????return?invocation.invoke(); ??
  34. ????????} ??
  35. ???????? ??
  36. ????????Cookie[]?cookies?=?request.getCookies(); ??
  37. ????????if?(cookies!=null)?{ ??
  38. ????????????for?(Cookie?cookie?:?cookies)?{ ??
  39. ????????????????if?(COOKIE_REMEMBERME_KEY.equals(cookie.getName()))?{ ??
  40. ????????????????????String?value?=?cookie.getValue(); ??
  41. ????????????????????if?(StringUtils.isNotBlank(value))?{ ??
  42. ????????????????????????String[]?split?=?value.split("=="); ??
  43. ????????????????????????String?userName?=?split[0]; ??
  44. ????????????????????????String?password?=?split[1]; ??
  45. ????????????????????????try?{ ??
  46. ????????????????????????????User?user?=?userDao ??
  47. ????????????????????????????????????.attemptLogin(userName,?password); ??
  48. ????????????????????????????session.put(USER_SESSION_KEY,?user); ??
  49. ????????????????????????}?catch?(UserNotFoundException?e)?{ ??
  50. ????????????????????????????setGoingToURL(session,?invocation); ??
  51. ????????????????????????????return?"login"; ??
  52. ????????????????????????} ??
  53. ????????????????????}?else?{ ??
  54. ????????????????????????setGoingToURL(session,?invocation); ??
  55. ????????????????????????return?"login"; ??
  56. ????????????????????} ??
  57. ????????????????????return?invocation.invoke(); ??
  58. ????????????????} ??
  59. ????????????} ??
  60. ????????} ??
  61. ????????setGoingToURL(session,?invocation); ??
  62. ????????return?"login"; ??
  63. ????} ??
  64. ??
  65. ????private?void?setGoingToURL(Map?session,?ActionInvocation?invocation){ ??
  66. ????????String?url?=?""; ??
  67. ????????String?namespace?=?invocation.getProxy().getNamespace(); ??
  68. ????????if?(StringUtils.isNotBlank(namespace)?&&?!namespace.equals("/")){ ??
  69. ????????????url?=?url?+?namespace; ??
  70. ????????} ??
  71. ????????String?actionName?=?invocation.getProxy().getActionName(); ??
  72. ????????if?(StringUtils.isNotBlank(actionName)){ ??
  73. ????????????url?=?url?+?"/"?+?actionName?+?".action"; ??
  74. ????????} ??
  75. ????????session.put(GOING_TO_URL_KEY,?url); ??
  76. ????} ??
  77. ???? ??
  78. ????public?UserDAO?getUserDao()?{ ??
  79. ????????return?userDao; ??
  80. ????} ??
  81. ??
  82. ????public?void?setUserDao(UserDAO?userDao)?{ ??
  83. ????????this.userDao?=?userDao; ??
  84. ????} ??
  85. ??
  86. }??


首先判斷session中有沒有用戶信息, 如果有的話繼續, 如果沒有的話,檢查cookie中有沒有rememberme的值,如果有的話,用==分割, 取得用戶名密碼進行登入。如果沒有這個用戶的話,記錄下request的action地址然后轉到登入頁面。如果驗證有這個用戶,則繼續下面的interceptor。 如果cookie中沒有信息的話,則記錄request的action地址然后轉到登入頁面。? 以上就是LoginInterceptor的全部代碼。

下面我們看看struts.xml

Java代碼
  1. <?xml?version="1.0"?encoding="UTF-8"?> ??
  2. ??
  3. <!DOCTYPE?struts?PUBLIC? ??
  4. ????"-//Apache?Software?Foundation//DTD?Struts?Configuration?2.0//EN"??
  5. ????"http://struts.apache.org/dtds/struts-2.0.dtd"> ??
  6. ??
  7. <struts> ??
  8. ????<package?name="default"?extends="struts-default"> ??
  9. ????????<interceptors> ??
  10. ????????????<interceptor?name="loginInterceptor"?class="loginInterceptor"></interceptor> ??
  11. ????????????<interceptor-stack?name="loginDefaultStack"> ??
  12. ????????????????<interceptor-ref?name="loginInterceptor"></interceptor-ref> ??
  13. ????????????????<interceptor-ref?name="defaultStack"></interceptor-ref> ??
  14. ????????????</interceptor-stack> ??
  15. ????????</interceptors> ??
  16. ????????<default-interceptor-ref?name="loginDefaultStack"></default-interceptor-ref> ??
  17. ????????<global-results> ??
  18. ????????????<result?name="login"?type="redirect">/login.jsp</result> ??
  19. ????????</global-results>????? ??
  20. ????????<action?name="index"?class="indexAction"> ??
  21. ????????????<result>/index.jsp</result> ??
  22. ????????</action> ??
  23. ????????<action?name="logout"?class="logoutAction"></action> ??
  24. ???????? ??
  25. ????????<action?name="login"?class="loginAction"?method="login"> ??
  26. ????????????<result?type="redirect">${goingToURL}</result> ??
  27. ????????????<result?name="input">/login.jsp</result> ??
  28. ????????????<interceptor-ref?name="defaultStack"></interceptor-ref> ??
  29. ????????</action> ??
  30. ???????? ??
  31. ????????<action?name="register"?class="registerAction"> ??
  32. ????????????<result?type="redirect">/login.jsp</result> ??
  33. ????????????<result?name="input">/register.jsp</result> ??
  34. ????????????<interceptor-ref?name="defaultStack"></interceptor-ref> ??
  35. ????????</action> ??
  36. ????</package> ??
  37. </struts>??


我們是使用的默認的interceptor stack是loginInterceptor, 如果你需要讓不登入的用戶也能訪問的話,你需要配置你的action使用defaultStack。 我們這里的login, register使用的就是defaultStack。 這里要注意的是success的result是我們用LoginInterceptor設過來的值。 這樣我們就能夠轉到用戶輸入的起始頁面。 下面我們再來看看login.jsp 和 loginAction

Java代碼
  1. <%@taglib?prefix="s"?uri="/struts-tags"?%> ??
  2. <%@?page?language="java"?contentType="text/html;?charset=UTF-8"??
  3. ????pageEncoding="UTF-8"%> ??
  4. <html> ??
  5. <head> ??
  6. ????<meta?http-equiv="Content-Type"?content="text/html;?charset=UTF-8"> ??
  7. ????<title>Wallet-Login</title> ??
  8. </head> ??
  9. <body> ??
  10. <h2>Login</h2>? ??
  11. <s:actionmessage/> ??
  12. <s:actionerror/> ??
  13. <s:form?action="login"?method="post"?validate="false"?theme="xhtml"> ??
  14. <s:textfield?name="loginName"?label="Username"></s:textfield><br/> ??
  15. <s:password?name="password"?label="Password"></s:password><br/> ??
  16. <s:checkbox?label="Remember?Me"?name="rememberMe"></s:checkbox> ??
  17. <s:submit?value="%{'Login'}"></s:submit>? ??
  18. </s:form> ??
  19. <a?href="register.jsp">Register</a> ??
  20. </body> ??
  21. </html>??


Java代碼
  1. package?com.javaeye.dengyin2000.wallet.actions; ??
  2. ??
  3. import?java.util.Map; ??
  4. ??
  5. import?javax.servlet.http.Cookie; ??
  6. import?javax.servlet.http.HttpServletRequest; ??
  7. import?javax.servlet.http.HttpServletResponse; ??
  8. ??
  9. import?org.apache.commons.lang.StringUtils; ??
  10. import?org.apache.struts2.interceptor.CookiesAware; ??
  11. import?org.apache.struts2.interceptor.ServletRequestAware; ??
  12. import?org.apache.struts2.interceptor.ServletResponseAware; ??
  13. import?org.apache.struts2.interceptor.SessionAware; ??
  14. ??
  15. import?com.javaeye.dengyin2000.wallet.dao.UserDAO; ??
  16. import?com.javaeye.dengyin2000.wallet.dao.UserNotFoundException; ??
  17. import?com.javaeye.dengyin2000.wallet.domains.User; ??
  18. import?com.javaeye.dengyin2000.wallet.interceptor.LoginInterceptor; ??
  19. import?com.opensymphony.xwork2.ActionSupport; ??
  20. ??
  21. public?class?LoginAction?extends?ActionSupport?implements?ServletResponseAware,?ServletRequestAware,?SessionAware,?CookiesAware{ ??
  22. ??
  23. ????private?UserDAO?userDao; ??
  24. ????private?String?loginName; ??
  25. ????private?String?password; ??
  26. ????private?boolean?rememberMe; ??
  27. ????private?HttpServletResponse?response; ??
  28. ????private?HttpServletRequest?request; ??
  29. ????private?Map?session; ??
  30. ????private?Map?cookies; ??
  31. ????private?String?goingToURL; ??
  32. ????public?String?getGoingToURL()?{ ??
  33. ????????return?goingToURL; ??
  34. ????} ??
  35. ????public?void?setGoingToURL(String?goingToURL)?{ ??
  36. ????????this.goingToURL?=?goingToURL; ??
  37. ????} ??
  38. ????public?boolean?isRememberMe()?{ ??
  39. ????????return?rememberMe; ??
  40. ????} ??
  41. ????public?void?setRememberMe(boolean?rememberMe)?{ ??
  42. ????????this.rememberMe?=?rememberMe; ??
  43. ????} ??
  44. ????public?String?getLoginName()?{ ??
  45. ????????return?loginName; ??
  46. ????} ??
  47. ????public?void?setLoginName(String?loginName)?{ ??
  48. ????????this.loginName?=?loginName; ??
  49. ????} ??
  50. ????public?String?getPassword()?{ ??
  51. ????????return?password; ??
  52. ????} ??
  53. ????public?void?setPassword(String?password)?{ ??
  54. ????????this.password?=?password; ??
  55. ????} ??
  56. ???? ??
  57. ???? ??
  58. ????public?String?login()throws?Exception{ ??
  59. ????????try?{ ??
  60. ????????????User?user?=?userDao.attemptLogin(loginName,?password); ??
  61. ????????????if?(rememberMe){ ??
  62. ????????????????Cookie?cookie?=?new?Cookie(LoginInterceptor.COOKIE_REMEMBERME_KEY,?user.getLoginName()?+?"=="?+?user.getPassword()); ??
  63. ????????????????cookie.setMaxAge(60?*?60?*?24?*?14); ??
  64. ????????????????response.addCookie(cookie); ??
  65. ????????????} ??
  66. ????????????session.put(LoginInterceptor.USER_SESSION_KEY,?user); ??
  67. ????????????String?goingToURL?=?(String)?session.get(LoginInterceptor.GOING_TO_URL_KEY); ??
  68. ????????????if?(StringUtils.isNotBlank(goingToURL)){ ??
  69. ????????????????setGoingToURL(goingToURL); ??
  70. ????????????????session.remove(LoginInterceptor.GOING_TO_URL_KEY); ??
  71. ????????????}else{ ??
  72. ????????????????setGoingToURL("index.action"); ??
  73. ????????????} ??
  74. ????????????return?SUCCESS; ??
  75. ????????}?catch?(UserNotFoundException?e)?{ ??
  76. ????????????addActionMessage("user?name?or?password?is?not?corrected."); ??
  77. ????????????return?INPUT; ??
  78. ????????} ??
  79. ????} ??
  80. ????public?UserDAO?getUserDao()?{ ??
  81. ????????return?userDao; ??
  82. ????} ??
  83. ????public?void?setUserDao(UserDAO?userDao)?{ ??
  84. ????????this.userDao?=?userDao; ??
  85. ????} ??
  86. ????public?void?setServletResponse(HttpServletResponse?response)?{ ??
  87. ????????this.response?=?response; ??
  88. ????} ??
  89. ????public?void?setServletRequest(HttpServletRequest?request)?{ ??
  90. ????????this.request?=?request; ??
  91. ????} ??
  92. ????public?void?setSession(Map?session)?{ ??
  93. ????????this.session?=?session; ??
  94. ????} ??
  95. ????public?void?setCookiesMap(Map?cookies)?{ ??
  96. ????????this.cookies?=?cookies; ??
  97. ????} ??
  98. }??


差不多就是這么多代碼了。 最后看看logoutAction

Java代碼
  1. package?com.javaeye.dengyin2000.wallet.actions; ??
  2. ??
  3. import?javax.servlet.http.Cookie; ??
  4. import?javax.servlet.http.HttpServletRequest; ??
  5. import?javax.servlet.http.HttpServletResponse; ??
  6. import?javax.servlet.http.HttpSession; ??
  7. ??
  8. import?org.apache.struts2.interceptor.ServletRequestAware; ??
  9. import?org.apache.struts2.interceptor.ServletResponseAware; ??
  10. ??
  11. import?com.javaeye.dengyin2000.wallet.interceptor.LoginInterceptor; ??
  12. import?com.opensymphony.xwork2.ActionSupport; ??
  13. ??
  14. public?class?LogoutAction?extends?ActionSupport?implements?ServletRequestAware?,?ServletResponseAware{ ??
  15. ??
  16. ????private?HttpServletRequest?request; ??
  17. ????private?HttpServletResponse?response; ??
  18. ??
  19. ????public?String?execute()?throws?Exception{ ??
  20. ????????HttpSession?session?=?request.getSession(false); ??
  21. ????????if?(session!=null) ??
  22. ????????????session.removeAttribute(LoginInterceptor.USER_SESSION_KEY); ??
  23. ???????? ??
  24. ????????Cookie[]?cookies?=?request.getCookies(); ??
  25. ????????if?(cookies!=null)?{ ??
  26. ????????????for?(Cookie?cookie?:?cookies)?{ ??
  27. ????????????????if?(LoginInterceptor.COOKIE_REMEMBERME_KEY.equals(cookie ??
  28. ????????????????????????.getName()))?{ ??
  29. ????????????????????cookie.setValue(""); ??
  30. ????????????????????cookie.setMaxAge(0); ??
  31. ????????????????????response.addCookie(cookie); ??
  32. ????????????????????return?"login"; ??
  33. ????????????????} ??
  34. ????????????} ??
  35. ????????} ??
  36. ????????return?"login"; ??
  37. ????} ??
  38. ??
  39. ????public?void?setServletRequest(HttpServletRequest?request)?{ ??
  40. ????????this.request?=?request; ??
  41. ????} ??
  42. ??
  43. ????public?void?setServletResponse(HttpServletResponse?response)?{ ??
  44. ????????this.response?=?response; ??
  45. ????} ??
  46. ??
  47. }??


這里需要注意的是需要把cookie也清理下。

applicationContext-struts.xml
Java代碼
  1. <?xml?version="1.0"?encoding="UTF-8"?> ??
  2. <!DOCTYPE?beans?PUBLIC? ??
  3. ????"-//SPRING//DTD?BEAN//EN"? ??
  4. ????"http://www.springframework.org/dtd/spring-beans.dtd"> ??
  5. ???? ??
  6. <beans> ??
  7. ????<!--?Example?of?SAF2?action?instantiated?by?Spring?--> ??
  8. ????<!--?bean?id="helloWorldAction"?class="tutorial.HelloWorldAction"?singleton="false"?/> ??
  9. ?????--> ??
  10. ?????<bean?id="indexAction"?class="com.javaeye.dengyin2000.wallet.actions.IndexAction"?singleton="false"></bean> ??
  11. ?????<bean?id="loginAction"?class="com.javaeye.dengyin2000.wallet.actions.LoginAction"?singleton="false"> ??
  12. ????????<property?name="userDao"?ref="userDao"?/> ??
  13. ?????</bean> ??
  14. ????? ??
  15. ?????<bean?id="logoutAction"?class="com.javaeye.dengyin2000.wallet.actions.LogoutAction"?singleton="false"></bean> ??
  16. ????? ??
  17. ?????<bean?id="registerAction"?class="com.javaeye.dengyin2000.wallet.actions.RegisterAction"?singleton="false"></bean> ??
  18. ????? ??
  19. ?????<!--?the?following?is?struts2?interceptors?--> ??
  20. ?????<bean?id="loginInterceptor"?class="com.javaeye.dengyin2000.wallet.interceptor.LoginInterceptor"> ??
  21. ????????<property?name="userDao"?ref="userDao"?/> ??
  22. ?????</bean> ??
  23. ????? ??
  24. ?????<bean?id="userDao"?class="com.javaeye.dengyin2000.wallet.dao.UserDAOImpl"> ??
  25. ?????</bean> ??
  26. </beans>??