拦截器是 SpringMVC 中一种对象,能拦截对 Controller 对象的请求
拦截器框架中有系统的拦截器,还有自定义拦截器,实现对请求的预先处理
步骤 :
package com.fancy.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return HandlerInterceptor.super.preHandle(request, response, handler);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
<mvc:interceptors>
<mvc:interceptor>
<mvc: path="url" />
<bean class="拦截器的全限定名称">
mvc:interceptor>
mvc:interceptors>
步骤 :
package com.fancy.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("执行了 preHandle() 方法");
return true;
}
}
preHandle() 方法返回值 为 true 表示 请求能被 Controller 处理,返回值为false 表示请求被截断
注册拦截器时需要加上 @Configuration 注解
package com.fancy.config;
import com.fancy.interceptor.MyInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyAppConfig implements WebMvcConfigurer {
// 注册拦截器对象
@Override
public void addInterceptors(InterceptorRegistry registry) {
// InterceptorRegistry 登记系统中可以使用的拦截器
// 指定拦截的地址
String path [] = {"/user/**"};
String excludePath [] = {"/user/login"};
registry.addInterceptor(new MyInterceptor()).addPathPatterns(path).excludePathPatterns(excludePath);
}
}
addPathPatterns(path) 方法表示拦截路径为path的请求,excludePathPatterns(excludePath) 表示不拦截路径为 excludePath 的请求。 合起来就是 拦截 /user 下的所有请求除了 login
package com.fancy.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class BootController {
@RequestMapping("/user/account")
@ResponseBody
public String queryAccount() {
return "user/account";
}
@RequestMapping("/user/login")
@ResponseBody
public String login() {
return "/user/login";
}
}
ServletRegistrationBean 用来做在 servlet 3.0+ 容器中注册 servlet 的功能,但更具有SpringBean 友好性。
package com.fancy.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.println("使用 Servlet 对象");
out.flush();
out.close();
}
}
第一种方式 :
package com.fancy.config;
import com.fancy.servlet.MyServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Servlet;
import javax.servlet.ServletRegistration;
@Configuration
public class SystemConfig {
@Bean
public ServletRegistrationBean servletRegistrationBean() {
// 第一个参数是 servlet 对象, 第二个参数是 url pattern
ServletRegistrationBean reg = new ServletRegistrationBean(new MyServlet(), "/myservlet");
return reg;
}
}
第二种方式 :
package com.fancy.config;
import com.fancy.servlet.MyServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Servlet;
import javax.servlet.ServletRegistration;
@Configuration
public class SystemConfig {
@Bean
public ServletRegistrationBean servletRegistrationBean() {
ServletRegistrationBean reg = new ServletRegistrationBean(new MyServlet(), "/myservlet");
ServletRegistrationBean bean = new ServletRegistrationBean();
bean.setServlet(new MyServlet());
bean.addUrlMappings("/login", "/test");
return reg;
}
}
Filter 是 Servlet 规范中的过滤器,可以处理请求,对请求的参数,属性进行调整,常常用来处理字符编码。
我们用 FilterRegistrationBean 来注册 Filter 对象。
package com.fancy.Filter;
import javax.servlet.*;
import java.io.IOException;
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("使用了 Servlet 中的 Filter 对象");
//请求继续向下执行
filterChain.doFilter(servletRequest, servletResponse);
}
}
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean reg = new FilterRegistrationBean();
// 使用哪个过滤器
reg.setFilter(new MyFilter());
// 过滤器地址
reg.addUrlPatterns("/user/*");
return reg;
}
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean reg = new FilterRegistrationBean();
// 创建CharacterEncodingFilter
CharacterEncodingFilter filter = new CharacterEncodingFilter();
// 设置 request, response 使用编码值
filter.setEncoding("utf-8");
// 强制request, response 使用 encoding 的值
filter.setForceEncoding(true);
reg.setFilter(filter);
// 请求先使用过滤器处理
reg.addUrlPatterns("/*");
return reg;
}