需要實作的功能:判斷使用者是否已登入,未登入使用者禁止通路任何頁面或action,自動跳轉到登入頁面。
過程:因為對過濾器和攔截器都不熟悉,開始兩種方式都問題不斷,後調試通過,貼在這裡留作小結和備忘
過濾器filter實作
配置:web.xml
<filter>
<filter-name>RightFilter</filter-name>
<filter-class>com.***.rights.RightFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>RightFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>RightFilter</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
代碼:
mport java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class RightFilter extends HttpServlet implements Filter {
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) arg1;
HttpServletRequest request=(HttpServletRequest)arg0;
HttpSession session = request.getSession(true);
String usercode = (String) session.getAttribute("usercode");//
String url=request.getRequestURI();
if(usercode==null || usercode.equals(""))
{
//判斷擷取的路徑不為空且不是通路登入頁面或執行登入操作時跳轉
if(url!=null && !url.equals("") && ( url.indexOf("Login")<0 && url.indexOf("login")<0 ))
{
response.sendRedirect("登入路徑");
return ;
}
}
//已認證驗證,使用者通路繼續
arg2.doFilter(arg0, arg1);
return;
}
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
配置中的filter-mapping,定義的是需過濾的請求類型,上面的配置即過濾所有對jsp頁面和action的請求。過濾器的實作與struts2、spring架構無關,在使用者請求被相應前執行,在過濾器中,可使用response.sendRedirect("")等方法
跳轉到需要的連結,如登入頁面、錯誤頁面等,不需要跳轉時,arg2.doFilter(arg0, arg1);即可繼續執行使用者的請求。注意使用filter時避免連續兩次跳轉,否則會報java.lang.IllegalStateException錯誤,具體配置方法網上有,除非必要,不建議使用/*(過濾所有通路)的配置方式,這樣配置,圖檔、js檔案、css檔案等通路都會被過濾
攔截器interceptor實作:
配置:struts.xml
<interceptors>
<!--定義一個名為authority的攔截器-->
<interceptor class="com.***.rights.RightInterceptor" name="rightInterceptor"/>
<!--定義一個包含權限檢查的攔截器棧-->
<interceptor-stack name="mydefault">
<!--配置内建預設攔截器-->
<interceptor-ref name="defaultStack"/>
<!--配置自定義的攔截器-->
<interceptor-ref name="rightInterceptor"/>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="mydefault" />
<!--定義全局Result-->
<global-results>
<result name="login">Login.jsp</result>
<result name="error">/error.jsp </result>
</global-results>
代碼:
import java.util.HashMap;
import java.util.Map;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.opensymphony.xwork2.ActionContext;
public class RightInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation invocation) throws Exception {
//System.out.println("攔截器開始驗證");
try
{
ActionContext actionContext = ActionContext.getContext();
Map<String,Object> session = actionContext.getSession();
String user=session.get("usercode").toString();
//目前使用者session無效且通路的action不是登入action時,執行攔截,跳轉
if((user==null || user.equals("")) && !invocation.getAction().getClass().getName().equals("登入action"))
{
return Action.LOGIN;
}
}
catch(Exception e)
{
e.printStackTrace();
return Action.LOGIN;
}
//System.out.println("攔截器通過驗證");
return invocation.invoke();//執行通路的action
}
}
攔截器由spring管理,隻對action起作用,不能攔截jsp頁面、圖檔等其他資源。攔截器截獲使用者對action的通路,如需要跳轉,隻需如action一樣傳回一個result,spring根據result的配置執行跳轉。如無需跳轉,可調用invocation.invoke();方法來執行使用者請求的action。攔截器在action之前開始,在action完成後結束(如被攔截,action根本不執行)
如不進行處理,過濾器和攔截器都會将正常的登入操作屏蔽,是以過濾器中需要判斷使用者通路的url是否為登入操作或登入頁面,攔截器中需要判斷使用者通路的action是否登入action。(暫未考慮其他區分方法,留問。)
具體配置不加說明,網上很多