springboot 配置拦截器
1 有这样一个需求
服务端对部分请求URL需要验证身份。如果验证错误,停止请求,按照既定的数据格式返回;如果验证正确,继续执行请求。
2 需要这样做
1. 将指定格式的请求拦截下来;
2. 获取参数,验证参数;
3. 验证不通过,返回既定数据格式。
3 步骤
需要对参数进行逻辑操作,所以需要在拦截器中注入实例,返回的数据是指定格式,所以要重写response
1.定义拦截器,要继承HandlerInterceptorAdapter ,重写“处理请求前”方法,在该方法中进行逻辑验证。
代码如下:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import com.boco.osmp.entities.TokenOriginEntity; import com.boco.osmp.model.TokenModel; import java.io.PrintWriter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * * * @author * */ public class CommonInterceptor extends HandlerInterceptorAdapter { @Autowired private TokenModel tokenModel; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String requestUri = request.getRequestURI(); String contextPath = request.getContextPath(); String url = requestUri.substring(contextPath.length()); if ("GET".equalsIgnoreCase(request.getMethod()) || "POST".equalsIgnoreCase(request.getMethod())) { if (url.contains("/api/")) { String token = request.getHeader("authorization"); String userId = request.getParameter("userId"); if (token != null && userId != null) { String tokenSource = tokenModel.getToken(userId); // 如果token验证不通过,返回已经登录的用户信息 if (!token.equals(tokenSource)) { String p = tokenModel.decryptTokenToResponse(tokenSource, TokenOriginEntity.class); response.setContentType("application/json;charset=utf-8"); PrintWriter writer; writer = response.getWriter(); writer.write(p); return false; } } else { throw new Exception("token或 用户ID不能为空"); } } return true; } else { throw new Exception("不支持的请求类型!"); } } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { super.postHandle(request, response, handler, modelAndView); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { super.afterCompletion(request, response, handler, ex); } @Override public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { super.afterConcurrentHandlingStarted(request, response, handler); } }
拦截器中需要写的是,如果验证错误,需要返回既定格式数据,
是这几行代码实现的
response.setContentType("application/json;charset=utf-8"); //JSON PrintWriter writer; writer = response.getWriter(); writer.write(p); //数据
2. 重写配置文件,添加新增的拦截器
在配置文件中需要实例化一个拦截器,这样才能保证在拦截器中注入的实例有效。
swagger U的默认地址也需要手动添加进去。
代码
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import com.boco.osmp.interceptor.CommonInterceptor; /** * 配置拦截器 * 初始化拦截器,这样在拦截器中可以注入@service * @author */ @EnableWebMvc @Configuration public class WebMvcConfig extends WebMvcConfigurerAdapter { /** * 需要重新该方法,将swagger-ui.html手动加入,否则会请求不到 */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("swagger-ui.html") .addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/"); } @Bean public CommonInterceptor interceptor() { return new CommonInterceptor(); } @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(interceptor()).addPathPatterns("/**"); super.addInterceptors(registry); } }