如何在Java項(xiàng)目中使用過濾器、攔截器和監(jiān)聽器?針對(duì)這個(gè)問題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡單易行的方法。
創(chuàng)新互聯(lián)是一家專注網(wǎng)站建設(shè)、網(wǎng)絡(luò)營銷策劃、成都小程序開發(fā)、電子商務(wù)建設(shè)、網(wǎng)絡(luò)推廣、移動(dòng)互聯(lián)開發(fā)、研究、服務(wù)為一體的技術(shù)型公司。公司成立10多年以來,已經(jīng)為近千家三維植被網(wǎng)各業(yè)的企業(yè)公司提供互聯(lián)網(wǎng)服務(wù)。現(xiàn)在,服務(wù)的近千家客戶與我們一路同行,見證我們的成長;未來,我們一起分享成功的喜悅。
一、攔截器:是在面向切面編程的就是在你的service或者一個(gè)方法,前調(diào)用一個(gè)方法,或者在方法后調(diào)用一個(gè)方法比如動(dòng)態(tài)代理就是攔截器的簡單實(shí)現(xiàn),在你調(diào)用方 法前打印出字符串(或者做其它業(yè)務(wù)邏輯的操作),也可以在你調(diào)用方法后打印出字符串,甚至在你拋出異常的時(shí)候做業(yè)務(wù)邏輯的操作。
1.Struts2攔截器是在訪問某個(gè)Action或Action的某個(gè)方法,字段之前或之后實(shí)施攔截,并且Struts2攔截器是可插拔的,攔截器是AOP的一種實(shí)現(xiàn)。
2.攔截器棧(Interceptor Stack)Struts2攔截器棧就是將攔截器按一定的順序聯(lián)結(jié)成一條鏈。在訪問被攔截的方法或字段時(shí),Struts2攔截器鏈中的攔截器就會(huì)按其之前定義的順序被調(diào)用。
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 struts */ 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; } }
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
<?xml version="1.0" encoding="UTF-8" ?>struts /result.jsp /error.jsp /error.jsp
或者:
<?xml version="1.0" encoding="UTF-8" ?>struts /result.jsp /error.jsp /error.jsp
web.xml中加入:
struts2 org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter actionPackages com.lzw.struts.action struts2 /*
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; } }
<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %>" rel="external nofollow" > My JSP 'login.jsp' starting page
控制臺(tái)結(jié)果:
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提前過濾掉一些信息,或者提前設(shè)置一些參數(shù),然后再傳入servlet或者struts的 action進(jìn)行業(yè)務(wù)邏輯,比如過濾掉非法url(不是login.do的地址請(qǐng)求,如果用戶沒有登陸都過濾掉),或者在傳入servlet或者struts的action前統(tǒng)一設(shè)置字符集,或者去除掉一些非法字符。主要為了減輕服務(wù)器負(fù)載,減少壓力
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 中加入:
UserFilter com.lzw.filter.demo.UserAccessFilter UserFilter /jsp/*
1、攔截器是基于java的反射機(jī)制的,而過濾器是基于函數(shù)回調(diào)
2、過濾器依賴與servlet容器,而攔截器不依賴與servlet容器
3、攔截器只能對(duì)action請(qǐng)求起作用,而過濾器則可以對(duì)幾乎所有的請(qǐng)求起作用
4、攔截器可以訪問action上下文、值棧里的對(duì)象,而過濾器不能
5、在action的生命周期中,攔截器可以多次被調(diào)用,而過濾器只能在容器初始化時(shí)被調(diào)用一次
在action的生命周期中,攔截器可以多次被調(diào)用,而過濾器只能在容器初始化時(shí)被調(diào)用一次
執(zhí)行順序 :過濾前 - 攔截前 - Action處理 - 攔截后 - 過濾后。
個(gè)人認(rèn)為過濾是一個(gè)橫向的過程,首先把客戶端提交的內(nèi)容進(jìn)行過濾(例如未登錄用戶不能訪問內(nèi)部頁面的處理);
過濾通過后,攔截器將檢查用戶提交數(shù)據(jù)的驗(yàn)證,做一些前期的數(shù)據(jù)處理,接著把處理后的數(shù)據(jù)發(fā)給對(duì)應(yīng)的Action;
Action處理完成返回后,攔截器還可以做其他過程,再向上返回到過濾器的后續(xù)操作。
三、監(jiān)聽器:Servlet的監(jiān)聽器Listener,它是實(shí)現(xiàn)了javax.servlet.ServletContextListener接口的服務(wù)器端程序,它也是隨web應(yīng)用的啟動(dòng)而啟動(dòng),只初始化一次,隨web應(yīng)用的停止而銷毀。
主要作用是:做一些初始化的內(nèi)容添加工作、設(shè)置一些基本的內(nèi)容、比如一些參數(shù)或者是一些固定的對(duì)象等等。
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("服務(wù)器啟動(dòng)完畢!"); System.out.println(servletContext); } @Override public void contextDestroyed(ServletContextEvent sce) {} }
web.xml
<?xml version="1.0" encoding="UTF-8"?>index.html index.htm index.jsp default.html default.htm default.jsp com.lzw.filter.demo.InitDataListener
控制臺(tái)結(jié)果:
信息: Starting service Catalina 2013-10-31 15:13:55 org.apache.catalina.core.StandardEngine startInternal 信息: Starting Servlet Engine: Apache Tomcat/7.0.42 服務(wù)器啟動(dòng)完畢! 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
關(guān)于如何在Java項(xiàng)目中使用過濾器、攔截器和監(jiān)聽器問題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。