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里面的信息
項(xiàng)目中后端服務(wù)經(jīng)常需要前端傳的請求頭里的信息,給大家分享一下:
1、循環(huán)獲取
/** ? ? ?* 獲取判斷請求頭的參數(shù) ? ? ?* @return ? ? ?*/ ? ? public?static?boolean checkHeaderName(){ ? ? ? ? RequestAttributes ra = RequestContextHolder.getRequestAttributes(); ? ? ? ? if(Objects.isNull(ra)){ ? ? ? ? ? ? log.info("服務(wù)里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; ? ? ? ? ? ? } ? ? ? ? ? ? /** ? ? ? ? ? ? ?* 或者其他的業(yè)務(wù)處理 ? ? ? ? ? ? ?*/ ? ? ? ? } ? ? ? ? return false; ? ? }
2、根據(jù)具體的key獲取
/** ? ? ?*獲取 判斷請求頭的參數(shù) ? ? ?* @return ? ? ?*/ ? ? public static?boolean?checkHeader(){ ? ? ? ? RequestAttributes ra = RequestContextHolder.getRequestAttributes(); ? ? ? ? if(Objects.isNull(ra)){ ? ? ? ? ? ? log.info("服務(wù)里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; ? ? ? ? } ? ? ? ? /** ? ? ? ? ?* 或者其他的業(yè)務(wù)處理 ? ? ? ? ?*/ ? ? ? ? return false; ? ? }
3、修改請求頭信息
只能依靠反射原原理(HttpServletRequest中定義的對Header的操作全是只讀,沒有修改)。
假設(shè)的場景是,需要對請求Header統(tǒng)一添加一個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,隨機(jī)生成請求ID ?? ??? ?mimeHeaders.addValue("x-request-id").setString(UUID.randomUUID().toString());; ?? ??? ?// 移除一個header ?? ??? ?mimeHeaders.removeHeader("User-Agent"); ?? ?} }
總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java實(shí)現(xiàn)統(tǒng)計(jì)在線人數(shù)功能的方法詳解
很多人在筆試或者面試中問到:現(xiàn)在要你實(shí)現(xiàn)一個統(tǒng)計(jì)在線人數(shù)的功能,你該怎么設(shè)計(jì)?不知道的朋友,這篇文章就來告訴你具體實(shí)現(xiàn)方法2022-08-08JAVA項(xiàng)目如何打包部署到Linux服務(wù)器上
本文詳細(xì)介紹了在服務(wù)器上部署環(huán)境包括JDK、MySQL、Tomcat的設(shè)置,以及使用Idea-Maven-SpringBoot進(jìn)行jar包打包部署的流程,內(nèi)容涵蓋了MySQL配置注意事項(xiàng)、pom.xml配置、打包命令等關(guān)鍵步驟,同時,也提供了如何將jar包上傳到Linux服務(wù)器并運(yùn)行的具體方法2024-10-10java實(shí)現(xiàn)單鏈表倒轉(zhuǎn)的方法
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)單鏈表倒轉(zhuǎn)的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05Mybatis中and和循環(huán)or混用操作(or轉(zhuǎn)換成in)
這篇文章主要介紹了Mybatis中and和循環(huán)or混用操作(or轉(zhuǎn)換成in),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07