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);
}
}