您的位置:首页 > 编程语言 > Java开发

关于springMVC中的使用拦截器interceptor问题

2018-02-07 17:04 465 查看

springmvc中的拦截器interceptor的使用

最近在搭建一个前后端分离的后端ssm框架,想要实现一个接口加签验签过程,需要用到spring的拦截器来对请求进行验签处理。所以查找了些资料,总结了下spring中的拦截器intercept。

概述

springMVC中的拦截器是相当有用的,能够在用户进行请求后,进入具体的业务代码controller方法之前,进行相关操作,例如接口验签,判断登录状态,权限控制等等,也可以在处理完controller方法,进行视图渲染前,对返回视图的数据进行处理,也能够对整个请求结束后,进行资源的释放等功能。

一、定义Interceptor实现类

springMVC的拦截器主要通过HandlerInterceptor来实现的。在springMVC中定义一个拦截器interceptor十分简单,可以通过两种方法来实现。

一种是直接实现spring的HandlerInterceptor接口,或者继承spring提供的已经继承了该接口的抽象类HandlerInterceptorAdapter;另一种是要实现Spring的WebRequestInterceptor接口,或者是继承实现了WebRequestInterceptor的类。

(1)实现HandlerInterceptor接口或继承实现该接口的类

HandlerInterceptor中定义了三个方法,有不同的执行顺序:

1、preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

该方法是在客户端发起请求后,进入到具体的方法前进行调用。springMVC中拦截器的调用是链式的,一个应用或一个请求中可以有多个拦截器,会根据在配置文件中的声明顺序来进行处理,当然,每次进入拦截器后,都会先调用prehandle方法。该方法的返回值为boolean类型,只有当返回值未true时,才会执行后续操作,若后面还有拦截器,则继续调用下一个拦截器的prehandle,直到最后一个拦截器的prehandle方法处理完,就会进入对应的controller方法,如果返回false,则会结束请求。所以,可以在该方法中处理一些前置任务,比如接口验签,解密,权限控制等操作。

2、postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)

该方法的执行时间是在执行完controller的方法后,返回到视图渲染前的阶段。所以,该方法能够对返回前端的ModelAndView数
4000
据进行处理。

需要注意的是,当有多个拦截器的时候,posthandle方法的执行顺序和prehandle是相反的,先声明的拦截器的posthandle方法反而会后执行。

3、afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)

该方法的执行时间是在完成请求,也完成了视图渲染后进行调用。和posthandle一样,当有多个拦截器时,也是先声明的后执行规则。该方法因为是在完成请求后执行,所以对请求无法进行操作,一般是用来进行资源的释放等操作。

下面是具体的代码实现

/**
*
*/
package com.charlotte.blog.interceptor;

import java.io.PrintWriter;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
* @author dingjunjie
* @date 2018-02-07 12:51:30
* @desc spring拦截器,继承HandlerInterceptorAdapter抽象类
*/
public class SpingMvcInterceptor extends HandlerInterceptorAdapter {

/**
* springMVC接收到请求,在访问controller前自动执行该方法
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("执行了:preHandle========");
return true;
}

/**
* 在执行完controller方法后,进行视图渲染前自动调用该方法
*/
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("执行了:postHandle=========:");
}

/**
* 在视图渲染完成后,自动调用,主要用于清理数据
*/
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("执行了:afterCompletion====");
}

public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
}
}


(1)实现WebRequestInterceptor接口

WebRequestInterceptor接口中也定义了三个接口,和HandlerInterceptor接口类似,不同的是,这三个方法都有一个共同的参数WebRequest。这个WebRequest 是Spring 定义的一个接口,它里面的方法定义都基本跟HttpServletRequest 一样,在WebRequestInterceptor 中对WebRequest 进行的所有操作都将同步到HttpServletRequest 中,然后在当前请求中一直传递。

1、preHandle(WebRequest arg0)

该方法的执行顺序和HandlerInterceptor的一样,不再赘述。不同的是它没有返回值,而且参数类型为WebRequest。需要注意的是,WebRequest的setAttribute(name, value, scope)方法有三个参数,主要是第三个参数,在WebRequest 的父层接口RequestAttributes 中对它定义了三个常量:

SCOPE_REQUEST :它的值是0 ,代表只有在request 中可以访问。
SCOPE_SESSION :它的值是1 ,如果环境允许的话它代表的是一个局部的隔离的session,否则就代表普通的session,并且在该session范围内可以访问。
SCOPE_GLOBAL_SESSION :它的值是2 ,如果环境允许的话,它代表的是一个全局共享的session,否则就代表普通的session,并且在该session 范围内可以访问。


2、postHandle(WebRequest arg0, ModelMap arg1)

该方法有两个参数,WebRequest 对象是用于传递整个请求数据的,比如在preHandle 中准备的数据都可以通过WebRequest 来传递和访问;ModelMap 就是Controller 处理之后返回的Model 对象,我们可以通过改变它的属性来改变返回的Model 模型。

3、afterCompletion(WebRequest arg0, Exception arg1)

该方法会在整个请求处理完成,也就是在视图返回并被渲染之后执行。所以在该方法中可以进行资源的释放操作。而WebRequest 参数就可以把我们在preHandle 中准备的资源传递到这里进行释放。Exception 参数表示的是当前请求的异常对象,如果在Controller 中抛出的异常已经被Spring 的异常处理器给处理了的话,那么这个异常对象就是是null 。

下面是具体的代码实现

/**
*
*/
package com.charlotte.blog.interceptor;

import org.springframework.ui.ModelMap;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.context.request.WebRequestInterceptor;

/**
* @author dingjunjie
* @date 2018-02-07 16:26:30
*/
public class WebInterceptor implements WebRequestInterceptor{

/* (non-Javadoc)
* @see org.springframework.web.context.request.WebRequestInterceptor#afterCompletion(org.springframework.web.context.request.WebRequest, java.lang.Exception)
*/
@Override
public void afterCompletion(WebRequest arg0, Exception arg1) throws Exception {
System.out.println(getClass().getSimpleName() + "执行了:afterCompletion");
}

/* (non-Javadoc)
* @see org.springframework.web.context.request.WebRequestInterceptor#postHandle(org.springframework.web.context.request.WebRequest, org.springframework.ui.ModelMap)
*/
@Override
public void postHandle(WebRequest arg0, ModelMap arg1) throws Exception {
System.out.println(getClass().getSimpleName() + "执行了:postHandle");
}

/* (non-Javadoc)
* @see org.springframework.web.context.request.WebRequestInterceptor#preHandle(org.springframework.web.context.request.WebRequest)
*/
@Override
public void preHandle(WebRequest arg0) throws Exception {
System.out.println(getClass().getSimpleName() + "执行了:preHandle");
}

}


二、拦截器配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> 
<!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 -->
<context:component-scan base-package="com.charlotte.blog.controller" />

<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="com.charlotte.sdk.common.beans.MyFastJsonHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json</value>
</list>
</property>
<property name="features">
<array value-type="com.alibaba.fastjson.serializer.SerializerFeature">
<value>DisableCircularReferenceDetect</value>
<!--<value>UseISO8601DateFormat</value>-->
<value>WriteMapNullValue</value>
<value>WriteNullListAsEmpty</value>
<value>WriteNullStringAsEmpty</value>
<value>WriteNullBooleanAsFalse</value>
</array>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>

<!-- springMVC拦截器配置 -->
<mvc:interceptors>
<!-- 直接定义在 mvc:interceptors根下的bean会拦截所有请求-->
<bean class="com.charlotte.blog.interceptor.WebInterceptor"/>
<mvc:interceptor>
<!-- 定义在 mvc:interceptor下的bean会根据mvc:mapping中配置的路径来进行匹配拦截-->
<mvc:mapping path="/**"/>
<bean class="com.charlotte.blog.interceptor.SpingMvcInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>


好,以上就是最简单的拦截器的配置了,当然,还有很多内容可以扩展,但是这些配置也差不多够用了。希望能帮上需要的读者。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: