㈠ Spring filter和攔截器的區別和執行順序
1.Filter過濾器只過濾jsp文件不過濾action請求解決方案
解決辦法:在web.xml中將filter的配置放在struts2配置的前面。
2.攔截器與Filter的區別
spring的攔截器與Servlet的Filter有相似之處,比如二者都是AOP編程思想的體現,都能實現許可權檢查、日誌記錄等。不同的是:
使用范圍不同:Filter是Servlet規范規定的,只能用於Web程序中。而攔截器既可以用於Web程序,也可以用於Application、Swing程序中。
規范不同:Filter是在Servlet規范中定義的,是Servlet容器支持的。而攔截器是在Spring容器內的,是Spring框架支持的。
使用的資源不同:同其他的代碼塊一樣,攔截器也是一個Spring的組件,歸Spring管理,配置在Spring文件中,因此能使用Spring里的任何資源、對象,例如Service對象、數據源、事務管理等,通過IoC注入到攔截器即可;而Filter則不能。
深度不同:Filter在只在Servlet前後起作用。而攔截器能夠深入到方法前後、異常拋出前後等,因此攔截器的使用具有更大的彈性。所以在Spring構架的程序中,要優先使用攔截器。
實際上Filter和Servlet極其相似,區別只是Filter不能直接對用戶生成響應。實際上Filter里doFilter()方法里的代碼就是從多個Servlet的service()方法里抽取的通用代碼,通過使用Filter可以實現更好的復用。
filter是一個可以復用的代碼片段,可以用來轉換HTTP請求、響應和頭信息。Filter不像Servlet,它不能產生一個請求或者響應,它只是修改對某一資源的請求,或者修改從某一的響應。
JSR中說明的是,按照多個匹配的Filter,是按照其在web.xml中配置的順序來執行的。
所以這也就是,把自己的Filter或者其他的Filter(比如UrlRewrite的Filter)放在Struts的DispatcherFilter的前面的原因。因為,它們需要在請求被Struts2框架處理之前,做一些前置的工作。
當Filter被調用,並且進入了Struts2的DispatcherFilter中後,Struts2會按照在Action中配置的InterceptorStack中的Interceptor的順序,來調用Interceptor。
3.servlet、filter、interceptor的執行順序
@Override
publicvoiddoFilter(ServletRequestservletrequest,
,FilterChainfilterchain)
throwsIOException,ServletException{
System.out.println("infilter1.");
filterchain.doFilter(servletrequest,servletresponse);
System.out.println("outingfilter1");
}
interceptor代碼:
publicStringintercept()throwsException{
System.out.println("inlogininterceptor");
Stringresult=actioninvocation.invoke();
System.out.println("outinglogininterceptor");
returnresult;
}
action代碼:
@Override
publicStringexecute()throwsException{
System.out.println("inloginaciton");
ActionContextcontext=ActionContext.getContext();
Map<String,Object>session=context.getSession();
session.put("userName",userName);
/*HttpServletRequestrequest=ServletActionContext.getRequest();
HttpSessionsession=request.getSession();
session.putValue("userName",userName);*/
System.out.println("outingloginaciton");
returnSUCCESS;
}
jsp代碼:
<scripttype="text/javascript">
functionsubmitForm(){
document.getElementById("form1").submit();
}
</script>
</head>
<body>
ThisisLoginpage.<br>
<formaction="<%=path%>/login2.action"method="post"id="form1"name="form1">
UserName:<inputtype="text"id="userName"name="userName"/><inputtype="button"value="submit"onclick="submitForm()"id="submit1"/>
</form>
</body>
struts.xml
<struts>
<packagename="default"extends="struts-default"namespace="/">
<interceptors>
<interceptorname="MyInterceptor"class="Login.LoginInterceptor"></interceptor>
<interceptor-stackname="myInterceptorStack">
<interceptor-refname="MyInterceptor"/>
<interceptor-refname="defaultStack"/>
</interceptor-stack>
</interceptors>
<actionname="login2"class="Login.LoginAction">
<resultname="success">
/Login/success.jsp
</result>
<interceptor-refname="myInterceptorStack"></interceptor-ref>
</action>
</package>
</struts>
console:
infilter1.
inlogininterceptor
inloginaciton
outingloginaciton
outinglogininterceptor
outingfilter1
3.servlet、filter的執行順序
servlet代碼:
publicvoidinit()throwsServletException{
System.out.println("servlet初始化");
}
publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)
throwsServletException,IOException{
System.out.println("inservlet");
response.setContentType("text/html");
PrintWriterout=response.getWriter();
out.println("<!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN">");
out.println("<HTML>");
out.println("<HEAD><TITLE>AServlet</TITLE></HEAD>");
out.println("<BODY>");
out.print("Thisis");
out.print(this.getClass());
out.println(",usingthePOSTmethod");
out.println("<br>");
Stringx=request.getParameter("x");
Stringy=request.getParameter("y");
out.println("x="+x);
out.println("<br>");
out.println("y="+y);
out.println("<br>");
out.println("</BODY>");
out.println("</HTML>");
out.flush();
out.close();
System.out.println("outingservlet");
}
publicvoiddestroy(){
System.out.println("servlet銷毀");
super.destroy();
}
console:
servlet初始化
infilter1.
inservlet
beforeHttpServletRequest
afterHttpServletRequest
outingservlet
outingfilter1
當tomcat容器停止的時候,輸出:servlet銷毀
㈡ MVC過濾器,怎麼排除某個Action不使用Controller下的過濾器
當ActionInvoker在執行目標Action方法之前,會根據Order和Scope屬性對用於封裝的Filter對象進行排序。然後根據當前ControllerContext和ActionDescriptro創建一個ActionExecutingContext對象,並將其作為參數依次調用所有ActionFilter的OnActionExecuting方法。在這之後真正的目標Action方法被執行,ActionInvoker隨後執行後續的篩選操作。具體來說,它根據當前ControllerContext、ActionDescriptro以及Action方法執行過程中拋出的異常創建一個ActionExecutedContext對象。該ActionExecutedContext的Cancel屬性為False,如果Action方法返回一個ActionResult對象,該對象將會作為該ActionExecutedContext的Result屬性。接下來按照相反的次序依次調用ActionFilter對象的OnActionExecuted方法,執行過程中的ActionFilter可以修改ActionExecutedContext的Result屬性。當整個ActionFilter鏈執行結束之後,ActionExecutedContext的Result屬性返回的ActionResult將會作為對當前請求的響應。右圖基本上反映了連同目標Action在內的整個ActionFilter鏈的執行過程。
㈢ 我寫了一個過濾器 然後跳轉到action裡面從action裡面去值 傳入頁面 出現了異常
public void doFilter(ServletRequest arg0, ServletResponse arg1,
FilterChain arg2) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) arg0;
request.getRequestDispatcher("UserInfoAction.do").forward(arg0, arg1);
arg2.doFilter(arg0, arg1);
}
request.getRequestDispatcher("UserInfoAction.do").forward(arg0, arg1);
裡面的UserInfoAction.do好像不對吧,你應該寫struts裡面的配置路徑path="userInfo"
所以寫為 request.getRequestDispatcher("userInfo.do").forward(arg0, arg1);
|||||||
試試吧,不行的話再說
㈣ 過濾器可以過濾各種請求而攔截器只能在struts里攔截action請求嗎
攔截器不太好,還是使用過濾器吧。許可權控制一般使用頁面來控制,使用方法控制太麻煩了內(頁面進不去就沒容法請求)。針對某種功能時,比如刪除等可以使用攔截器來實現某些特定邏輯(這個也可以用動態代理來替代)。
頁面已經展示了某項,點了卻沒有許可權,這樣的頁面太不友好了。
㈤ MVC4 過濾器使用和怎樣控制全部action和部分action
讓一個中的所有Action都執行這個過濾器就需要對裡面的方法進行重寫
public class LoginController : Controller
{
//
// GET: /Login/
public ActionResult Index()
{
return View();
}
public ActionResult Login()
{
string name = HttpContext.Request["UserName"];
ViewData["name"] = name;
return View();
}
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
//object[] attrs = filterContext.ActionDescriptor.GetCustomAttributes(typeof(NoFilter), true);
//if (attrs.Length == 1)//有NoFilter屬性
//{
// return;
//}
string name = filterContext.HttpContext.Request["UserName"];
if (string.IsNullOrEmpty(name))
{
filterContext.HttpContext.Response.Write("<script>alert('名稱不能為空!');</script>");
filterContext.HttpContext.Response.End();
}
}
}
View Code
這樣每個action在執行前都會先執行這個過濾器。
下面是怎樣讓Index的Action不執行,只是對Login執行。有2種方式實現:
第一種:代碼修改如下:
public class LoginController : Controller
{
//
// GET: /Login/
[NoFilter]
public ActionResult Index()
{
return View();
}
public ActionResult Login()
{
string name = HttpContext.Request["UserName"];
ViewData["name"] = name;
return View();
}
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
//過濾掉標有NoFilter標簽的Action
object[] attrs = filterContext.ActionDescriptor.GetCustomAttributes(typeof(NoFilter), true);
if (attrs.Length == 1)//有NoFilter屬性
{
return;
}
string name = filterContext.HttpContext.Request["UserName"];
if (string.IsNullOrEmpty(name))
{
filterContext.HttpContext.Response.Write("<script>alert('名稱不能為空!');</script>");
filterContext.HttpContext.Response.End();
}
}
}
public class NoFilter : FilterAttribute, IActionFilter
{
public void OnActionExecuting(ActionExecutingContext filterContext)
{
//
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
//
}
}
View Code
第二種:代碼修改如下:
public class LoginController : Controller
{
//
// GET: /Login/
public ActionResult Index()
{
return View();
}
[LoginFilter]
public ActionResult Login()
{
string name = HttpContext.Request["UserName"];
ViewData["name"] = name;
return View();
}
//protected override void OnActionExecuting(ActionExecutingContext filterContext)
//{
// //過濾掉標有NoFilter標簽的Action
// object[] attrs = filterContext.ActionDescriptor.GetCustomAttributes(typeof(NoFilter), true);
// if (attrs.Length == 1)//有NoFilter屬性
// {
// return;
// }
// string name = filterContext.HttpContext.Request["UserName"];
// if (string.IsNullOrEmpty(name))
// {
// filterContext.HttpContext.Response.Write("<script>alert('名稱不能為空!');</script>");
// filterContext.HttpContext.Response.End();
// }
//}
}
public class LoginFilter : FilterAttribute, IActionFilter
{
public void OnActionExecuting(ActionExecutingContext filterContext)
{
string name = filterContext.HttpContext.Request["UserName"];
if (string.IsNullOrEmpty(name))
{
filterContext.HttpContext.Response.Write("<script>alert('名稱不能為空!');</script>");
filterContext.HttpContext.Response.End();
}
}
public void OnActionExecuted(ActionExecutedContext filterContext)
{
//
}
}
View Code
補充:1.自定義過濾器Filter必須繼承FilterAttribute。
2.定義過個過濾器可以定義過濾器執行的先後順序 例如: 在Action上標注:
[NoFilter(Order=2)]
[LoginFilter(Order=1)]
這樣當執行這個Action時候會先執行LoginFilter 再執行NoFilter。