本文实例讲述了Java中的拦截器、过滤器、监听器用法。分享给大家供大家参考,具体如下:
一、拦截器 :是在面向切面编程的就是在你的service或者一个方法,前调用一个方法,或者在方法后调用一个方法比如动态代理就是拦截器的简单实现,在你调用方 法前打印出字符串(或者做其它业务逻辑的操作),也可以在你调用方法后打印出字符串,甚至在你抛出异常的时候做业务逻辑的操作。
1.Struts2拦截器是在访问某个Action或Action的某个方法,字段之前或之后实施拦截,并且Struts2拦截器是可插拔的,拦截器是AOP的一种实现。
2.拦截器栈(Interceptor Stack)Struts2拦截器栈就是将拦截器按一定的顺序联结成一条链。在访问被拦截的方法或字段时,Struts2拦截器链中的拦截器就会按其之前定义的顺序被调用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
package com.lzw.struts.Interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
public class MyInterceptor extends MethodFilterInterceptor {
private static final long serialVersionUID = -6410044851077844880L;
/**
* 在struts.xml <param name="lzw">struts</param>
*/
private String lzw;
public String getLzw() {
return lzw;
}
public void setLzw(String lzw) {
this .lzw = lzw;
}
@Override
public void destroy() {
System.out.println( "destroy!" );
}
@Override
public void init() {
System.out.println( "init!" );
}
@Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
System.out.println( "MyInterceptor-start" );
System.out.println(lzw);
String result = invocation.invoke();
System.out.println( "MyInterceptor-end" );
return result;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package com.lzw.struts.Interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
public class FirstInterceptor extends MethodFilterInterceptor {
private static final long serialVersionUID = 1L;
@Override
protected String doIntercept(ActionInvocation invocation) throws Exception {
System.out.println( "FirstInterceptor-Start" );
String result = invocation.invoke();
System.out.println( "FirstInterceptor-End" );
return result;
}
}
|
struts.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
<? xml version = "1.0" encoding = "UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
< struts >
<!--开发模式开关,本地可以设为true帮助调试问题,部署到服务器上设为false-->
< constant name = "struts.devMode" value = "false" />
<!--务必配上该属性,否则会导致AOP注入异常-->
< constant name = "struts.objectFactory.spring.autoWire.alwaysRespect" value = "true" />
< constant name = "struts.i18n.encoding" value = "UTF-8" />
< constant name = "struts.multipart.maxSize" value = "1000000000" />
< package name = "strutsLzw" extends = "struts-default" namespace = "/" >
< interceptors >
< interceptor name = "lzwInterceptorA" class = "com.lzw.struts.Interceptor.MyInterceptor" >
< param name = "lzw" >struts</ param >
</ interceptor >
< interceptor name = "lzwInterceptorB" class = "com.lzw.struts.Interceptor.FirstInterceptor" >
</ interceptor >
<!-- 定义自己的拦截器栈 -->
< interceptor-stack name = "myStack" >
< interceptor-ref name = "lzwInterceptorA" ></ interceptor-ref >
< interceptor-ref name = "lzwInterceptorB" ></ interceptor-ref >
< interceptor-ref name = "defaultStack" ></ interceptor-ref >
</ interceptor-stack >
</ interceptors >
<!-- 全局的每个action都会拦截 -->
< default-interceptor-ref name = "myStack" ></ default-interceptor-ref >
<!-- 增加method="lzwTest" 执行LoginAction的lzwTest方法 否则执行execute方法 -->
< action name = "login" class = "com.lzw.struts.action.LoginAction" method = "lzwTest" >
< result name = "success" >/result.jsp</ result >
< result name = "failer" >/error.jsp</ result >
< result name = "input" >/error.jsp</ result >
</ action >
</ package >
</ struts >
|
或者:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<? xml version = "1.0" encoding = "UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
< struts >
< package name = "strutsLzw" extends = "struts-default" >
< interceptors >
< interceptor name = "lzwInterceptor" class = "com.lzw.struts.Interceptor.MyInterceptor" >
< param name = "lzw" >struts</ param >
</ interceptor >
</ interceptors >
<!-- 增加method="lzwTest" 执行LoginAction的lzwTest方法 否则执行execute方法 -->
< action name = "login" class = "com.lzw.struts.action.LoginAction" method = "lzwTest" >
< result name = "success" >/result.jsp</ result >
< result name = "failer" >/error.jsp</ result >
< result name = "input" >/error.jsp</ result >
< interceptor-ref name = "lzwInterceptor" ></ interceptor-ref >
<!--增加defaultStack 否则 验证拦截器不执行,也就是 validate 方法不执行-->
< interceptor-ref name = "defaultStack" ></ interceptor-ref >
</ action >
</ package >
</ struts >
|
web.xml中加入:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
< filter >
< filter-name >struts2</ filter-name >
<!-- 已经过时了<filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class> -->
< filter-class >org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</ filter-class >
< init-param >
< param-name >actionPackages</ param-name >
< param-value >com.lzw.struts.action</ param-value >
</ init-param >
</ filter >
< filter-mapping >
< filter-name >struts2</ filter-name >
< url-pattern >/*</ url-pattern >
</ filter-mapping >
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
package com.lzw.struts.action;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport{
private static final long serialVersionUID = 1L;
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this .username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this .password = password;
}
@Override
public String execute() throws Exception {
System.out.println( "=====execute=====" );
if ( "hello" .equals( this .getUsername().trim()) && "world" .equals( this .getPassword().trim())) {
return "success" ;
} else {
this .addFieldError( "username" , "username or password error" );
return "failer" ;
}
}
@Override
public void validate() {
System.out.println( "=====validate=====" );
if ( null == this .getUsername() || "" .equals( this .getUsername().trim())) {
this .addFieldError( "username" , "username required" );
}
if ( null == this .getPassword() || "" .equals( this .getPassword().trim())) {
this .addFieldError( "password" , "password required" );
}
}
public String lzwTest() {
System.out.println( "======Test====" );
return SUCCESS;
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
<%@ page language= "java" import = "java.util.*" pageEncoding= "ISO-8859-1" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+ "://" +request.getServerName()+ ":" +request.getServerPort()+path+ "/" ;
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" >
<html>
<head>
<base href= "<%=basePath%>" rel= "external nofollow" >
<title>My JSP 'login.jsp' starting page</title>
<meta http-equiv= "pragma" content= "no-cache" >
<meta http-equiv= "cache-control" content= "no-cache" >
<meta http-equiv= "expires" content= "0" >
<meta http-equiv= "keywords" content= "keyword1,keyword2,keyword3" >
<meta http-equiv= "description" content= "This is my page" >
<!--
<link rel= "stylesheet" type= "text/css" href= "styles.css" rel= "external nofollow" >
-->
</head>
<body>
<form action= "login.action" method= "post" >
username:<input type= "text" name= "username" ><br>
password:<input type= "password" name= "password" ><br>
<input type= "submit" value= "submit" >
</form>
</body>
</html>
|
控制台结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
init!
2013 - 10 - 31 13 : 51 : 15 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler [ "http-apr-8080" ]
2013 - 10 - 31 13 : 51 : 15 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler [ "ajp-apr-8009" ]
2013 - 10 - 31 13 : 51 : 15 org.apache.catalina.startup.Catalina start
信息: Server startup in 1699 ms
MyInterceptor-start
struts
FirstInterceptor-Start
=====validate=====
======Test====
FirstInterceptor-End
MyInterceptor-end
|
二、过滤器:是在java web中,你传入的request,response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者struts的 action进行业务逻辑,比如过滤掉非法url(不是login.do的地址请求,如果用户没有登陆都过滤掉),或者在传入servlet或者struts的action前统一设置字符集,或者去除掉一些非法字符。主要为了减轻服务器负载,减少压力
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
package com.lzw.filter.demo;
import 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.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class UserAccessFilter implements Filter{
@Override
public void destroy() {
System.out.println( "destroy!" );
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse)res;
HttpSession session = request.getSession();
if (session.getAttribute( "user" )== null && request.getRequestURI().indexOf( "login.jsp" )==- 1 ){
response.sendRedirect( "login.jsp" );
return ;
}
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig config) throws ServletException {
//ApplicationFilterConfig[name=UserFilter, filterClass=com.lzw.filter.demo.UserAccessFilter]
System.out.println(config.toString());
}
}
|
web.xml 中加入:
1
2
3
4
5
6
7
8
|
< filter >
< filter-name >UserFilter</ filter-name >
< filter-class >com.lzw.filter.demo.UserAccessFilter</ filter-class >
</ filter >
< filter-mapping >
< filter-name >UserFilter</ filter-name >
< url-pattern >/jsp/*</ url-pattern >
</ filter-mapping >
|
1、拦截器是基于java的反射机制的,而过滤器是基于函数回调
2、过滤器依赖与servlet容器,而拦截器不依赖与servlet容器
3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用
4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能
5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次
在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次
执行顺序 :过滤前 - 拦截前 - Action处理 - 拦截后 - 过滤后。
个人认为过滤是一个横向的过程,首先把客户端提交的内容进行过滤(例如未登录用户不能访问内部页面的处理);
过滤通过后,拦截器将检查用户提交数据的验证,做一些前期的数据处理,接着把处理后的数据发给对应的Action;
Action处理完成返回后,拦截器还可以做其他过程,再向上返回到过滤器的后续操作。
三、监听器:Servlet的监听器Listener,它是实现了javax.servlet.ServletContextListener接口的服务器端程序,它也是随web应用的启动而启动,只初始化一次,随web应用的停止而销毁。
主要作用是:做一些初始化的内容添加工作、设置一些基本的内容、比如一些参数或者是一些固定的对象等等。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package com.lzw.filter.demo;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class InitDataListener implements ServletContextListener {
private static ServletContext servletContext;
public static ServletContext getServletContext() {
return servletContext;
}
@Override
public void contextInitialized(ServletContextEvent contextEvent) {
servletContext = contextEvent.getServletContext();
//final ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);
System.out.println( "服务器启动完毕!" );
System.out.println(servletContext);
}
@Override
public void contextDestroyed(ServletContextEvent sce) {}
}
|
web.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<?xml version= "1.0" encoding= "UTF-8" ?>
<web-app xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns= "http://java.sun.com/xml/ns/javaee" xsi:schemaLocation= "http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id= "WebApp_ID" version= "3.0" >
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file> default .html</welcome-file>
<welcome-file> default .htm</welcome-file>
<welcome-file> default .jsp</welcome-file>
</welcome-file-list>
<listener>
<listener- class >com.lzw.filter.demo.InitDataListener</listener- class >
</listener>
</web-app>
|
控制台结果:
1
2
3
4
5
6
7
8
9
10
11
|
信息: Starting service Catalina
2013 - 10 - 31 15 : 13 : 55 org.apache.catalina.core.StandardEngine startInternal
信息: Starting Servlet Engine: Apache Tomcat/ 7.0 . 42
服务器启动完毕!
org.apache.catalina.core.ApplicationContextFacade @7966340c
2013 - 10 - 31 15 : 13 : 56 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler [ "http-apr-8080" ]
2013 - 10 - 31 15 : 13 : 56 org.apache.coyote.AbstractProtocol start
信息: Starting ProtocolHandler [ "ajp-apr-8009" ]
2013 - 10 - 31 15 : 13 : 56 org.apache.catalina.startup.Catalina start
信息: Server startup in 402 ms
|
希望本文所述对大家java程序设计有所帮助。