Struts2 拦截器: 拦截器与过滤器区别
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                Struts2 拦截器: 拦截器与过滤器区别
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.                        
                                
                            
                            
                            1、首先要明確什么是攔截器、什么是過濾器
1.1 什么是攔截器:
攔截器,在AOP(Aspect-Oriented Programming)中用于在某個(gè)方法或字段被訪問之前,進(jìn)行攔截然后在之前或之后加入某些操作。攔截是AOP的一種實(shí)現(xiàn)策略。
在Webwork的中文文檔的解釋為——攔截器是動(dòng)態(tài)攔截Action調(diào)用的對(duì)象。它提供了一種機(jī)制可以使開發(fā)者可以定義在一個(gè)action執(zhí)行的前后執(zhí)行的代碼,也可以在一個(gè)action執(zhí)行前阻止其執(zhí)行。同時(shí)也是提供了一種可以提取action中可重用的部分的方式。
談到攔截器,還有一個(gè)詞大家應(yīng)該知道——攔截器鏈(Interceptor Chain,在Struts 2中稱為攔截器棧 Interceptor Stack)。攔截器鏈就是將攔截器按一定的順序聯(lián)結(jié)成一條鏈。在訪問被攔截的方法或字段時(shí),攔截器鏈中的攔截器就會(huì)按其之前定義的順序被調(diào)用。
1.2. 攔截器的實(shí)現(xiàn)原理:
大部分時(shí)候,攔截器方法都是通過代理的方式來調(diào)用的。Struts 2的攔截器實(shí)現(xiàn)相對(duì)簡單。當(dāng)請(qǐng)求到達(dá)Struts 2的ServletDispatcher時(shí),Struts 2會(huì)查找配置文件,并根據(jù)其配置實(shí)例化相對(duì)的攔截器對(duì)象,然后串成一個(gè)列表(list),最后一個(gè)一個(gè)地調(diào)用列表中的攔截器。
1.3 什么是過濾器
過濾器是一個(gè)程序,它先于與之相關(guān)的servlet或JSP頁面運(yùn)行在服務(wù)器上。過濾器可附加到一個(gè)或多個(gè)servlet或JSP頁面上,并且可以檢查進(jìn)入這些資源的請(qǐng)求信息。在這之后,過濾器可以作如下的選擇:
①以常規(guī)的方式調(diào)用資源(即,調(diào)用servlet或JSP頁面)。
②利用修改過的請(qǐng)求信息調(diào)用資源。
③調(diào)用資源,但在發(fā)送響應(yīng)到客戶機(jī)前對(duì)其進(jìn)行修改。
④阻止該資源調(diào)用,代之以轉(zhuǎn)到其他的資源,返回一個(gè)特定的狀態(tài)代碼或生成替換輸出。
1.4 Servlet過濾器的基本原理
在Servlet作為過濾器使用時(shí),它可以對(duì)客戶的請(qǐng)求進(jìn)行處理。處理完成后,它會(huì)交給下一個(gè)過濾器處理,這樣,客戶的請(qǐng)求在過濾鏈里逐個(gè)處理,直到請(qǐng)求發(fā)送到目標(biāo)為止。例如,某網(wǎng)站里有提交“修改的注冊(cè)信息”的網(wǎng)頁,當(dāng)用戶填寫完修改信息并提交后,服務(wù)器在進(jìn)行處理時(shí)需要做兩項(xiàng)工作:判斷客戶端的會(huì)話是否有效;對(duì)提交的數(shù)據(jù)進(jìn)行統(tǒng)一編碼。這兩項(xiàng)工作可以在由兩個(gè)過濾器組成的過濾鏈里進(jìn)行處理。當(dāng)過濾器處理成功后,把提交的數(shù)據(jù)發(fā)送到最終目標(biāo);如果過濾器處理不成功,將把視圖派發(fā)到指定的錯(cuò)誤頁面。
2、攔截器與過濾器的區(qū)別 :
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)用一次
攔截器的代碼實(shí)現(xiàn)(以struts2為例):
1、在xml文件中如何定義攔截器
<interceptors>
<interceptor name="filterIPInterceptor"
class="com.xxxx.web.FilterIPActionInterceptor" />
<interceptor-stack name="filterIPStack">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="filterIPInterceptor" />
</interceptor-stack>
</interceptors>
2、怎么遍別寫自定義攔截器
public class FilterIPActionInterceptor extends AbstractInterceptor
{
/** 日志控制. */
private final Log log = LogFactory.getLog(getClass());
/**
* @see com.opensymphony.xwork2.interceptor.AbstractInterceptor#intercept(com.opensymphony.xwork2.ActionInvocation)
*/
@Override
@SuppressWarnings("unchecked")
public String intercept(ActionInvocation invocation) throws Exception
{
String result = null;
// 獲得當(dāng)前方法名.
String methodName = invocation.getInvocationContext().getName();
String currIp = null;
try
{
if (invocation.getAction() instanceof PortletAction)
{
PortletAction action = (PortletAction) invocation.getAction();
currIp = action.getRequest().getRemoteAddr();
}
String ip = ApplicationResource.getHotValue("ALLOW_CACHE_IP");
if (StringUtils.isBlank(ip) || StringUtils.isBlank(currIp))
{
log.error("允許刷新的IP不存在或當(dāng)前請(qǐng)求的IP非法.");
throw new NoAllowIPException();
}
else
{
String[] ips = ip.split(",");
boolean errorIp = true;
for (String s : ips)
{
if (s.equals(currIp))
errorIp = false;
}
// 判斷IP
if (errorIp)
throw new NoAllowIPException();
}
result = invocation.invoke();//調(diào)用被攔截的方法
}
catch (Exception e)
{
log.error("異常類名:" + invocation.getAction().getClass());
log.error("異常方法:" + methodName, e);
throw e;
}
return result;
}
}
3、怎么編寫過濾器
1、在web.xml里面配置自定義的攔截器
<filter>
<filter-name>Redirect Filter</filter-name>
<filter-class>com.xx.filter.RedirectFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Redirect Filter</filter-name>
<url-pattern>/xx/xx/*</url-pattern>
</filter-mapping>
2、如何編寫自定義的攔截器
public class RedirectFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
// 獲取URL
Long startTime = null;
if (log.isDebugEnabled())
{
startTime = System.currentTimeMillis();
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
String url = httpRequest.getRequestURL().toString();
if (url == null || url.trim().length() == 0) {
return;
}
if (url.indexOf(luceneCreateMapping) != -1
|| url.indexOf(luceneSearchMapping) != -1) {
doFilterForxxx(request, response, url);
} else {
doxxxx(request, response, url);
}
if (log.isDebugEnabled())
{
long endTime = System.currentTimeMillis();
Thread currentThread = Thread.currentThread();
String threadName = currentThread.getName();
log.debug("[" + threadName + "]" + "< "
+ this.getClass().getName() + " " + url + " "
+ (endTime - startTime) + " ms");
}
// 激活下一個(gè)Filter
filterChain.doFilter(request, response);
}
}
轉(zhuǎn)載自https://zhidao.baidu.com/question/583953960492530045.html
                        
                        
                        1.1 什么是攔截器:
攔截器,在AOP(Aspect-Oriented Programming)中用于在某個(gè)方法或字段被訪問之前,進(jìn)行攔截然后在之前或之后加入某些操作。攔截是AOP的一種實(shí)現(xiàn)策略。
在Webwork的中文文檔的解釋為——攔截器是動(dòng)態(tài)攔截Action調(diào)用的對(duì)象。它提供了一種機(jī)制可以使開發(fā)者可以定義在一個(gè)action執(zhí)行的前后執(zhí)行的代碼,也可以在一個(gè)action執(zhí)行前阻止其執(zhí)行。同時(shí)也是提供了一種可以提取action中可重用的部分的方式。
談到攔截器,還有一個(gè)詞大家應(yīng)該知道——攔截器鏈(Interceptor Chain,在Struts 2中稱為攔截器棧 Interceptor Stack)。攔截器鏈就是將攔截器按一定的順序聯(lián)結(jié)成一條鏈。在訪問被攔截的方法或字段時(shí),攔截器鏈中的攔截器就會(huì)按其之前定義的順序被調(diào)用。
1.2. 攔截器的實(shí)現(xiàn)原理:
大部分時(shí)候,攔截器方法都是通過代理的方式來調(diào)用的。Struts 2的攔截器實(shí)現(xiàn)相對(duì)簡單。當(dāng)請(qǐng)求到達(dá)Struts 2的ServletDispatcher時(shí),Struts 2會(huì)查找配置文件,并根據(jù)其配置實(shí)例化相對(duì)的攔截器對(duì)象,然后串成一個(gè)列表(list),最后一個(gè)一個(gè)地調(diào)用列表中的攔截器。
1.3 什么是過濾器
過濾器是一個(gè)程序,它先于與之相關(guān)的servlet或JSP頁面運(yùn)行在服務(wù)器上。過濾器可附加到一個(gè)或多個(gè)servlet或JSP頁面上,并且可以檢查進(jìn)入這些資源的請(qǐng)求信息。在這之后,過濾器可以作如下的選擇:
①以常規(guī)的方式調(diào)用資源(即,調(diào)用servlet或JSP頁面)。
②利用修改過的請(qǐng)求信息調(diào)用資源。
③調(diào)用資源,但在發(fā)送響應(yīng)到客戶機(jī)前對(duì)其進(jìn)行修改。
④阻止該資源調(diào)用,代之以轉(zhuǎn)到其他的資源,返回一個(gè)特定的狀態(tài)代碼或生成替換輸出。
1.4 Servlet過濾器的基本原理
在Servlet作為過濾器使用時(shí),它可以對(duì)客戶的請(qǐng)求進(jìn)行處理。處理完成后,它會(huì)交給下一個(gè)過濾器處理,這樣,客戶的請(qǐng)求在過濾鏈里逐個(gè)處理,直到請(qǐng)求發(fā)送到目標(biāo)為止。例如,某網(wǎng)站里有提交“修改的注冊(cè)信息”的網(wǎng)頁,當(dāng)用戶填寫完修改信息并提交后,服務(wù)器在進(jìn)行處理時(shí)需要做兩項(xiàng)工作:判斷客戶端的會(huì)話是否有效;對(duì)提交的數(shù)據(jù)進(jìn)行統(tǒng)一編碼。這兩項(xiàng)工作可以在由兩個(gè)過濾器組成的過濾鏈里進(jìn)行處理。當(dāng)過濾器處理成功后,把提交的數(shù)據(jù)發(fā)送到最終目標(biāo);如果過濾器處理不成功,將把視圖派發(fā)到指定的錯(cuò)誤頁面。
2、攔截器與過濾器的區(qū)別 :
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)用一次
攔截器的代碼實(shí)現(xiàn)(以struts2為例):
1、在xml文件中如何定義攔截器
<interceptors>
<interceptor name="filterIPInterceptor"
class="com.xxxx.web.FilterIPActionInterceptor" />
<interceptor-stack name="filterIPStack">
<interceptor-ref name="defaultStack" />
<interceptor-ref name="filterIPInterceptor" />
</interceptor-stack>
</interceptors>
2、怎么遍別寫自定義攔截器
public class FilterIPActionInterceptor extends AbstractInterceptor
{
/** 日志控制. */
private final Log log = LogFactory.getLog(getClass());
/**
* @see com.opensymphony.xwork2.interceptor.AbstractInterceptor#intercept(com.opensymphony.xwork2.ActionInvocation)
*/
@Override
@SuppressWarnings("unchecked")
public String intercept(ActionInvocation invocation) throws Exception
{
String result = null;
// 獲得當(dāng)前方法名.
String methodName = invocation.getInvocationContext().getName();
String currIp = null;
try
{
if (invocation.getAction() instanceof PortletAction)
{
PortletAction action = (PortletAction) invocation.getAction();
currIp = action.getRequest().getRemoteAddr();
}
String ip = ApplicationResource.getHotValue("ALLOW_CACHE_IP");
if (StringUtils.isBlank(ip) || StringUtils.isBlank(currIp))
{
log.error("允許刷新的IP不存在或當(dāng)前請(qǐng)求的IP非法.");
throw new NoAllowIPException();
}
else
{
String[] ips = ip.split(",");
boolean errorIp = true;
for (String s : ips)
{
if (s.equals(currIp))
errorIp = false;
}
// 判斷IP
if (errorIp)
throw new NoAllowIPException();
}
result = invocation.invoke();//調(diào)用被攔截的方法
}
catch (Exception e)
{
log.error("異常類名:" + invocation.getAction().getClass());
log.error("異常方法:" + methodName, e);
throw e;
}
return result;
}
}
3、怎么編寫過濾器
1、在web.xml里面配置自定義的攔截器
<filter>
<filter-name>Redirect Filter</filter-name>
<filter-class>com.xx.filter.RedirectFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Redirect Filter</filter-name>
<url-pattern>/xx/xx/*</url-pattern>
</filter-mapping>
2、如何編寫自定義的攔截器
public class RedirectFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain) throws IOException, ServletException {
// 獲取URL
Long startTime = null;
if (log.isDebugEnabled())
{
startTime = System.currentTimeMillis();
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
String url = httpRequest.getRequestURL().toString();
if (url == null || url.trim().length() == 0) {
return;
}
if (url.indexOf(luceneCreateMapping) != -1
|| url.indexOf(luceneSearchMapping) != -1) {
doFilterForxxx(request, response, url);
} else {
doxxxx(request, response, url);
}
if (log.isDebugEnabled())
{
long endTime = System.currentTimeMillis();
Thread currentThread = Thread.currentThread();
String threadName = currentThread.getName();
log.debug("[" + threadName + "]" + "< "
+ this.getClass().getName() + " " + url + " "
+ (endTime - startTime) + " ms");
}
// 激活下一個(gè)Filter
filterChain.doFilter(request, response);
}
}
轉(zhuǎn)載自https://zhidao.baidu.com/question/583953960492530045.html
轉(zhuǎn)載于:https://www.cnblogs.com/sobright/p/6618859.html
總結(jié)
以上是生活随笔為你收集整理的Struts2 拦截器: 拦截器与过滤器区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: springboot 1.5.2 集成k
- 下一篇: iwebAx产品家族之iweb SNS
