【Maven+SSM】Springmvc的统一处理之拦截器

前言:

拦截器的使用场景:

程序中的所有请求的共同问题。

1、例如上一篇文章的乱码问题。本文最后会讲到乱码问题的解决。

2、例如解决权限验证的问题。本文最后也会提到。

拦截器与过滤器的区别:

过滤器基于Servlet容器,基于回调函数,范围大。

拦截器Interceptor依赖于框架,基于反射,只过滤请求。

正文:

一、写一个拦截器Interceptor

package interceptor;

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

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class TestInterceptor implements HandlerInterceptor{

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("---------preHandle--------");
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("---------postHandle--------");
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("---------afterCompletion--------");
	}

}

其中preHandle返回true说明不中断请求,否则中断请求。


二、注册到SpringMVC。

在springmvc-servlet.xml中配置拦截器

<!-- 注册拦截器 -->
	<mvc:interceptors>
		<bean class="interceptor.TestInterceptor"></bean>	
	</mvc:interceptors>
默认对所有走controller的请求拦截。


三、请求测试:

会按照如下顺序打印:

---------preHandle--------


---------postHandle--------


---------afterCompletion--------

因此,可见,三个方法的调用时机。

preHandle请求被处理之前。

postHandle请求被处理之后。

afterCompletion请求结束之后调用。

四、修改拦截规则:

仅仅针对部分请求拦截。修改在springmvc-servlet.xml中拦截器如下:

	<!-- 注册拦截器 -->
	<mvc:interceptors>
		<mvc:interceptor>
			<!-- 配置拦截规则 -->
			<mvc:mapping path="/*.do"/>	
			<bean class="interceptor.TestInterceptor"></bean>	
		</mvc:interceptor>		
	</mvc:interceptors>
只针对/*.do结尾的路径拦截。可以测试一下。略。

五、通过拦截器修改请求跳转及参数。

跳转页面的请求修改,拦截器如下:让请求处理之后跳转springmvc指定路径下的login.jsp,而不是原来的页面。

package interceptor;

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

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class TestInterceptor implements HandlerInterceptor{

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("---------preHandle--------");
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("---------postHandle--------");
		modelAndView.setViewName("/login");
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("---------afterCompletion--------");
	}

}
此方式仅仅针对原本就是跳转页面的请求有效。如果是responseBody的json返回请求则报错。

同样可通过修改ModelAndView修改传递的参数。例如:

@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("---------postHandle--------");
		modelAndView.setViewName("/login");
		modelAndView.addObject("msg", "我已经被拦截修改了");
	}
这样在页面中就会获得msg这个字段。如果之前有这个字段,则会被拦截器替换。

六、多个拦截器的拦截顺序。

<!-- 注册拦截器 -->
	<mvc:interceptors>
		<!-- <mvc:interceptor>
			配置拦截规则
			<mvc:mapping path="/*.do"/>	
			<bean class="interceptor.TestInterceptor"></bean>	
		</mvc:interceptor>		 -->
		<bean class="interceptor.TestInterceptor"></bean>	
		<bean class="interceptor.OtherInterceptor"></bean>	
	</mvc:interceptors>
执行顺序如何?原因,其实就是一个围绕方法的代理模式。

---------preHandle--------
---------preHandle2--------
略
---------postHandle2--------
---------postHandle--------
略
---------afterCompletion2--------
---------afterCompletion--------


七、拦截器的其他实现方式。

package interceptor;

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

public class WebInterceptor implements WebRequestInterceptor{

	@Override
	public void preHandle(WebRequest request) throws Exception {
		// 区别,没有返回值
		
	}

	@Override
	public void postHandle(WebRequest request, ModelMap model) throws Exception {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void afterCompletion(WebRequest request, Exception ex) throws Exception {
		// TODO Auto-generated method stub
		
	}

}

区别:不能中断请求。


八、通过拦截器对乱码问题的解决。

不仅可以如下处理请求的乱码,也可以处理响应请求的乱码问题。

package interceptor;

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

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class TestInterceptor implements HandlerInterceptor{

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("---------preHandle--------");
		//处理中文请求乱码问题
		request.setCharacterEncoding("UTF-8");
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("---------postHandle--------");
//		modelAndView.setViewName("/login");
//		modelAndView.addObject("msg", "我已经被拦截修改了");
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("---------afterCompletion--------");
	}

}

九、拦截器解决权限验证的问题。

package interceptor;

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

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class OtherInterceptor implements HandlerInterceptor{

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("---------preHandle2--------");
		if (request.getSession().getAttribute("user")==null) {
			//回到登陆页面
			request.getRequestDispatcher("/login.jsp").forward(request, response);;
			return false;
		}else {
			return true;
		}
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("---------postHandle2--------");
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		System.out.println("---------afterCompletion2--------");
	}

}












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值