這是一個Struts2.1.8.1應用,代碼如下
首先是web.xml檔案
<?xml version="1.0" encoding="UTF-8"?><br /><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"<br />xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br />xsi:schemaLocation="http://java.sun.com/xml/ns/javaee<br />http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><br /><filter><br /><filter-name>struts2</filter-name><br /><filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class><br /></filter><br /><filter-mapping><br /><filter-name>struts2</filter-name><br /><url-pattern>/*</url-pattern><br /></filter-mapping><br /><welcome-file-list><br /><welcome-file>anonymity.jsp</welcome-file><br /></welcome-file-list><br /></web-app>
然後是用於提交匿名訪問的頁面anonymity.jsp
<%@ page language="java" pageEncoding="UTF-8"%><br /><%@ taglib prefix="s" uri="/struts-tags"%><br /><%--<br /><%session.setAttribute("user", "玄玉");%><br />--%><br /><s:form action="anonymity" theme="simple"><br />當匿名使用者點擊Submit提交請求時,即Session中沒有使用者的登入資訊時<br/><br />會由於自訂的AuthInterceptor攔截器的生效而自動跳轉到LOGIN頁面<br/><br /><s:submit value="我要匿名訪問"/><br /></s:form>
用於顯示給匿名使用者的anonymityLogin.jsp頁面
<%@ page pageEncoding="UTF-8"%><br /><h2>匿名使用者存取應用時</h2><br /><h2>便自動跳轉至該頁面</h2>
用於顯示給合法使用者的anonymitySuccess.jsp頁面
<%@ page pageEncoding="UTF-8"%><br /><h2>Visit Success</h2>
然後是struts.xml檔案
<?xml version="1.0" encoding="UTF-8" ?><br /><!DOCTYPE struts PUBLIC<br />"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"<br />"http://struts.apache.org/dtds/struts-2.1.dtd"><br /><struts><br /><package name="anonymous" extends="struts-default"><br /><interceptors><br /><interceptor name="auth" class="com.jadyer.interceptor.AuthInterceptor"/><br /></interceptors><br /><!-- 注意:不同包package之間不能互相訪問對方的全域結果。除非兩個包是繼承關係才可以使用父包的global-results --><br /><!-- 於是可以把某些公用的東西放到一個繼承了struts-default的包中,然後大家去繼承這個包,就可以輕鬆實現資訊共用 --><br /><global-results><br /><result name="login" type="redirect">/anonymityLogin.jsp</result><br /></global-results><br /><action name="anonymity" class="com.jadyer.action.AnonymityTestAction"><br /><result name="input">/anonymity.jsp</result><br /><result name="login">/anonymityLogin.jsp</result><br /><result name="success">/anonymitySuccess.jsp</result><br /><interceptor-ref name="auth"/><br /><interceptor-ref name="defaultStack"/><br /></action><br /></package><br /></struts>
然後是在Struts2中自訂的監聽器類MyListener.java
package com.jadyer.listener;</p><p>import com.opensymphony.xwork2.ActionInvocation;<br />import com.opensymphony.xwork2.interceptor.PreResultListener;</p><p>/**<br /> * 實現PreResultListener的自訂監聽器<br /> */<br />public class MyListener implements PreResultListener {<br />public void beforeResult(ActionInvocation invocation, String resultCode) {<br />System.out.println("result : " + resultCode); //resultCode是一個類似於input、success的值<br />}<br />}
然後是在Struts2中自訂的攔截器類AuthInterceptor.java
package com.jadyer.interceptor;</p><p>import java.util.Map;</p><p>import com.jadyer.listener.MyListener;<br />import com.opensymphony.xwork2.Action;<br />import com.opensymphony.xwork2.ActionInvocation;<br />import com.opensymphony.xwork2.interceptor.AbstractInterceptor;</p><p>/**<br /> * 攔截匿名使用者的自訂攔截器<br /> * @see 使用Servlet過濾器可以攔截所有資源或某個目錄,而攔截器則只能攔截某個請求或某一類請求<br /> * @see 所以在開發的時候,應該根據具體情況,選擇使用Servlet過濾器或者自訂Struts2的攔截器<br /> */<br />@SuppressWarnings({"serial", "unchecked"})<br />public class AuthInterceptor extends AbstractInterceptor {<br />public String intercept(ActionInvocation invocation) throws Exception {<br />String result = "input";<br />invocation.addPreResultListener(new MyListener());//註冊監聽器<br />System.out.println("------AuthInterceptor invoked begin------");<br />//這裡getSession之後得到的是一個Map,不是HttpSession<br />//但是這個Map的底層依然是由HttpSession來維護的<br />//當然也可以使用ActionContext.getContext().getSession()擷取Map類型的session<br />Map map = invocation.getInvocationContext().getSession();<br />if (null == map.get("user")) {<br />result = Action.LOGIN; //若使用者未登入,則轉到登入頁面<br />} else {<br />result = invocation.invoke(); //若使用者已經登入,則繼續執行<br />}<br />System.out.println("------AuthInterceptor invoked finish------");<br />return result;<br />}<br />}
最後是用到的Action類
package com.jadyer.action;</p><p>import com.opensymphony.xwork2.ActionSupport;</p><p>/**<br /> * 繼承ActionSupport之後,如果不重寫execute()的話,它預設的會返回"success"<br /> */<br />@SuppressWarnings("serial")<br />public class AnonymityTestAction extends ActionSupport {}
後記:亦可在web.xml中設定<security-constraint>標籤屬性
後記:使得特定資源需要經過Tomcat認證之後方可訪問
後記:範例程式碼如下
<?xml version="1.0" encoding="UTF-8"?><br /><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"<br />xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"<br />xsi:schemaLocation="http://java.sun.com/xml/ns/javaee<br />http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><br /><filter><br /><filter-name>struts2</filter-name><br /><filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class><br /></filter><br /><filter-mapping><br /><filter-name>struts2</filter-name><br /><url-pattern>/*</url-pattern><br /></filter-mapping></p><p><!-- ******【以下是訪問需要Tomcat認證的資源時的配置資訊】****** --></p><p><!-- 也就是類似於我們在http://127.0.0.1:8080/頁面點擊Tomcat Manager時彈出的認證輸入框 --><br /><!-- 如果在認證輸入框中連續輸入三次錯誤的使用者名稱和密碼的話 --><br /><!-- IE瀏覽器就會直接報告HTTP Status 401 - ,即使用者驗證失敗,不允許繼續訪問 --><br /><!-- FF瀏覽器就不會報告任何錯誤,而是一直彈出認證輸入框,供使用者輸入使用者名稱和密碼 --><br /><!-- 除非在Firefox的認證對話方塊,點擊取消按鈕,才會顯示401 Unauthorized提示 --><br /><security-constraint><br /><web-resource-collection><br /><web-resource-name>my website auth</web-resource-name><br /><!-- 指定需要認證的目錄。這裡設定的是對根下面的test下面的所有資訊進行認證 --><br /><!-- 也就是說當訪問struts.xml中命名空間為/test下面的所有資源時都需要認證 --><br /><url-pattern>/test/*</url-pattern><br /><!-- 指定需要認證的訪問方式。這裡設定的是對點擊表單提交或點選連結等方式發送過來的訪問都進行認證 --><br /><http-method>GET</http-method><br /><http-method>POST</http-method><br /></web-resource-collection><br /><auth-constraint><br /><!-- 指定許可權。這裡的許可權名取值自下面的<security-role/>標籤中的<role-name/>值 --><br /><role-name>admin</role-name><br /></auth-constraint><br /></security-constraint></p><p><security-role><br /><!-- 指定哪些組的使用者可以訪問,這裡設定的是只有admin組的使用者可以訪問 --><br /><!-- 我們在Tomcat6.0.20//conf//tomcat-users.xml中的配置資訊如下 --><br /><!-- <user username="jadyer" password="75" roles="admin,manager"/> --><br /><!-- 所以在運行該例子時,在彈出的提示框中需要輸入的使用者名稱和密碼為jadyer和75 --><br /><role-name>admin</role-name><br /></security-role></p><p><login-config><br /><!-- 設定認證方式。共有四種,這裡用的是最簡單的認證方式 --><br /><!-- 這種方式速度最快,但不安全,因為此時使用者名稱和密碼均以明文的形式儲存在Tomcat設定檔中了 --><br /><auth-method>BASIC</auth-method><br /><!-- 這個realm-name的名字可以隨便起,它是顯示給使用者的提示資訊。但遺憾的是好像不能傳遞中文 --><br /><realm-name>Import Data,Please input AdminInfo</realm-name><br /></login-config><br /></web-app></p><p><!--<br />下面是相關的struts.xml配置<br /><?xml version="1.0" encoding="UTF-8"?><br /><!DOCTYPE struts PUBLIC<br /> "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"<br /> "http://struts.apache.org/dtds/struts-2.0.dtd"><br /><struts><br /><package name="security" extends="struts-default" namespace="/test"><br /><action name="security" class="com.jadyer.action.SecurityTestAction"><br /><result>/login.jsp</result><br /></action><br /></package><br /></struts><br />--><br /><!--<br />下面是相關的JSP頁面的存取碼<br /><%@ page pageEncoding="UTF-8"%><br /><br/><br /><br/><br /><input type="button"<br /> value="訪問需要認證的資源"<br /> onclick="javascript:window.location='<%=request.getContextPath()%>/test/security.action';"/><br />-->