㈠ 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。