Springboot如何通过filter修改Header的值
作者:小石潭记丶
这篇文章主要介绍了Springboot如何通过filter修改Header的值问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
Springboot通过filter修改Header的值
import org.apache.tomcat.util.http.MimeHeaders; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.*; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.reflect.Field; import java.util.*; /** * 拦截器配置 */ @Configuration public class FilterConfig { @Bean public FilterRegistrationBean modifyParametersFilter() { FilterRegistrationBean registration = new FilterRegistrationBean(); registration.setFilter(new ModifyParametersFilter()); registration.addUrlPatterns("/*"); // 拦截路径 registration.setName("modifyParametersFilter"); // 拦截器名称 registration.setOrder(1); // 顺序 return registration; } /** * 自定义拦截器 */ class ModifyParametersFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { // 修改请求头 Map<String, String> map = new HashMap<>(); modifyHeaders(map, request); // 修改cookie ModifyHttpServletRequestWrapper requestWrapper = new ModifyHttpServletRequestWrapper(request); String token = request.getHeader("token"); if (token != null && !"".equals(token)) { requestWrapper.putCookie("SHIROSESSIONID", token); } // finish filterChain.doFilter(requestWrapper, response); } } /** * 修改请求头信息 * @param headerses * @param request */ private void modifyHeaders(Map<String, String> headerses, HttpServletRequest request { if (headerses == null || headerses.isEmpty()) { return; } Class<? extends HttpServletRequest> requestClass = request.getClass(); try { Field request1 = requestClass.getDeclaredField("request"); request1.setAccessible(true); Object o = request1.get(request); Field coyoteRequest = o.getClass().getDeclaredField("coyoteRequest"); coyoteRequest.setAccessible(true); Object o1 = coyoteRequest.get(o); Field headers = o1.getClass().getDeclaredField("headers"); headers.setAccessible(true); MimeHeaders o2 = (MimeHeaders)headers.get(o1); for (Map.Entry<String, String> entry : headerses.entrySet()) { o2.removeHeader(entry.getKey()); o2.addValue(entry.getKey()).setString(entry.getValue()); } } catch (Exception e) { e.printStackTrace(); } } /** * 修改cookie信息 */ class ModifyHttpServletRequestWrapper extends HttpServletRequestWrapper { private Map<String, String> mapCookies; ModifyHttpServletRequestWrapper(HttpServletRequest request) { super(request); this.mapCookies = new HashMap<>(); } public void putCookie(String name, String value) { this.mapCookies.put(name, value); } public Cookie[] getCookies() { HttpServletRequest request = (HttpServletRequest) getRequest(); Cookie[] cookies = request.getCookies(); if (mapCookies == null || mapCookies.isEmpty()) { return cookies; } if (cookies == null || cookies.length == 0) { List<Cookie> cookieList = new LinkedList<>(); for (Map.Entry<String, String> entry : mapCookies.entrySet()) { String key = entry.getKey(); if (key != null && !"".equals(key)) { cookieList.add(new Cookie(key, entry.getValue())); } } if (cookieList.isEmpty()) { return cookies; } return cookieList.toArray(new Cookie[cookieList.size()]); } else { List<Cookie> cookieList = new ArrayList<>(Arrays.asList(cookies)); for (Map.Entry<String, String> entry : mapCookies.entrySet()) { String key = entry.getKey(); if (key != null && !"".equals(key)) { for (int i = 0; i < cookieList.size(); i++) { if(cookieList.get(i).getName().equals(key)){ cookieList.remove(i); } } cookieList.add(new Cookie(key, entry.getValue())); } } return cookieList.toArray(new Cookie[cookieList.size()]); }
Springboot获取请求头header里面的信息
项目中后端服务经常需要前端传的请求头里的信息,给大家分享一下:
1、循环获取
/** * 获取判断请求头的参数 * @return */ public static boolean checkHeaderName(){ RequestAttributes ra = RequestContextHolder.getRequestAttributes(); if(Objects.isNull(ra)){ log.info("服务里RequestAttributes对象为空"); return false; } ServletRequestAttributes sra = (ServletRequestAttributes) ra; HttpServletRequest request = sra.getRequest(); Enumeration<String> enumeration = request.getHeaderNames(); while (enumeration.hasMoreElements()) { String name = enumeration.nextElement(); String value = request.getHeader(name); if(name.equals("accept-"+HeaderEnum.language.name()) && value.equals(HeaderEnum.language.head())){ return true; } /** * 或者其他的业务处理 */ } return false; }
2、根据具体的key获取
/** *获取 判断请求头的参数 * @return */ public static boolean checkHeader(){ RequestAttributes ra = RequestContextHolder.getRequestAttributes(); if(Objects.isNull(ra)){ log.info("服务里RequestAttributes对象为空"); return false; } ServletRequestAttributes sra = (ServletRequestAttributes) ra; HttpServletRequest request = sra.getRequest(); String head = request.getHeader("accept-"+HeaderEnum.language.name()); if(head.equals(HeaderEnum.language.head())){ return true; } /** * 或者其他的业务处理 */ return false; }
3、修改请求头信息
只能依靠反射原原理(HttpServletRequest中定义的对Header的操作全是只读,没有修改)。
假设的场景是,需要对请求Header统一添加一个x-request-id,通过这个ID来从日志中定位每一个请求。
import java.io.IOException; import java.lang.reflect.Field; import java.util.UUID; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.catalina.connector.Request; import org.apache.catalina.connector.RequestFacade; import org.apache.tomcat.util.http.MimeHeaders; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.util.ReflectionUtils; @WebFilter(urlPatterns = "/*") @Component @Order(-999) public class RequestIdGenFilter extends HttpFilter { /** * */ private static final long serialVersionUID = 1787347739651657706L; @Override protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException { try { // 从 RequestFacade 中获取 org.apache.catalina.connector.Request Field connectorField = ReflectionUtils.findField(RequestFacade.class, "request", Request.class); connectorField.setAccessible(true); Request connectorRequest = (Request) connectorField.get(req); // 从 org.apache.catalina.connector.Request 中获取 org.apache.coyote.Request Field coyoteField = ReflectionUtils.findField(Request.class, "coyoteRequest", org.apache.coyote.Request.class); coyoteField.setAccessible(true); org.apache.coyote.Request coyoteRequest = (org.apache.coyote.Request) coyoteField.get(connectorRequest); // 从 org.apache.coyote.Request 中获取 MimeHeaders Field mimeHeadersField = ReflectionUtils.findField(org.apache.coyote.Request.class, "headers", MimeHeaders.class); mimeHeadersField.setAccessible(true); MimeHeaders mimeHeaders = (MimeHeaders) mimeHeadersField.get(coyoteRequest); this.mineHeadersHandle(mimeHeaders); } catch (Exception e) { throw new RuntimeException(e); } super.doFilter(req, res, chain); } protected void mineHeadersHandle (MimeHeaders mimeHeaders) { // 添加一个Header,随机生成请求ID mimeHeaders.addValue("x-request-id").setString(UUID.randomUUID().toString());; // 移除一个header mimeHeaders.removeHeader("User-Agent"); } }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。