反射机制设置header
private void reflectSetHeader(HttpServletRequest request, String key, String value){
Class<? extends HttpServletRequest> requestClass = request.getClass();
try {
Field requestField = requestClass.getDeclaredField("request");
requestField.setAccessible(true);
Object requestObj = requestField.get(request);
Field coyoteRequestField = requestObj.getClass().getDeclaredField("coyoteRequest");
coyoteRequestField.setAccessible(true);
Object coyoteRequestObj = coyoteRequestField.get(requestObj);
Field headersField = coyoteRequestObj.getClass().getDeclaredField("headers");
headersField.setAccessible(true);
MimeHeaders headersObj = (MimeHeaders)headersField.get(coyoteRequestObj);
headersObj.removeHeader(key);
headersObj.addValue(key).setString(value);
} catch (Exception e) {
logger.error("reflect set header {} error {}", key, e);
}
}
Filter中使用
@Component
@Slf4j
public class MyFilter extends OncePerFilter{
@AutoWired
private XxService xxService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
String requestMethod = request.getMethod();
// options 直接放行
if (requestMethod.equals(HttpMethod.OPTIONS.name())) {
filterChain.doFilter(request, response);
}
reflectSetHeader(request, "X-xx", xxService.getXx());
filterChain.doFilter(request, response);
}
private void reflectSetHeader(HttpServletRequest request, String key, String value){
Class<? extends HttpServletRequest> requestClass = request.getClass();
try {
Field requestField = requestClass.getDeclaredField("request");
requestField.setAccessible(true);
Object requestObj = requestField.get(request);
Field coyoteRequestField = requestObj.getClass().getDeclaredField("coyoteRequest");
coyoteRequestField.setAccessible(true);
Object coyoteRequestObj = coyoteRequestField.get(requestObj);
Field headersField = coyoteRequestObj.getClass().getDeclaredField("headers");
headersField.setAccessible(true);
MimeHeaders headersObj = (MimeHeaders)headersField.get(coyoteRequestObj);
headersObj.removeHeader(key);
headersObj.addValue(key).setString(value);
} catch (Exception e) {
logger.error("reflect set header {} error {}", key, e);
}
}
// 供外部调用,获取xx
public static String getXxFromHeaders(){
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
return request.getHeader("X-xx");
}
}
Interceptor使用
@Slf4j
public class MyInterceptor implements HandlerInterceptor {
@AutoWired
private XxService xxService;
@Override
public boolean preHandle(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse, Object handler) throws Exception {
String requestMethod = httpServletRequest.getMethod();
// options 直接放行
if (requestMethod.equals(HttpMethod.OPTIONS.name())) {
return true;
}
reflectSetHeader(request, "X-xx", xxService.getXx());
filterChain.doFilter(request, response);
return true;
}
private void reflectSetHeader(HttpServletRequest request, String key, String value){
Class<? extends HttpServletRequest> requestClass = request.getClass();
try {
Field requestField = requestClass.getDeclaredField("request");
requestField.setAccessible(true);
Object requestObj = requestField.get(request);
Field coyoteRequestField = requestObj.getClass().getDeclaredField("coyoteRequest");
coyoteRequestField.setAccessible(true);
Object coyoteRequestObj = coyoteRequestField.get(requestObj);
Field headersField = coyoteRequestObj.getClass().getDeclaredField("headers");
headersField.setAccessible(true);
MimeHeaders headersObj = (MimeHeaders)headersField.get(coyoteRequestObj);
headersObj.removeHeader(key);
headersObj.addValue(key).setString(value);
} catch (Exception e) {
logger.error("reflect set header {} error {}", key, e);
}
}
// 供外部调用,获取xx
public static String getXxFromHeaders(){
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
return request.getHeader("X-xx");
}
}
- 拦截器需要手动配置
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
// 若要在Interceptor中进行依赖注入,则需要将拦截器注册为一个 Bean
@Bean
public MyInterceptor myInterceptor() {
return new MyInterceptor ();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor()).addPathPatterns("/**");
}
}