Springboot如何通過(guò)filter修改Header的值
Springboot通過(guò)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"); // 攔截器名稱(chēng)
registration.setOrder(1); // 順序
return registration;
}
/**
* 自定義攔截器
*/
class ModifyParametersFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
// 修改請(qǐng)求頭
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);
}
}
/**
* 修改請(qǐng)求頭信息
* @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獲取請(qǐng)求頭header里面的信息
項(xiàng)目中后端服務(wù)經(jīng)常需要前端傳的請(qǐng)求頭里的信息,給大家分享一下:
1、循環(huán)獲取
/**
? ? ?* 獲取判斷請(qǐng)求頭的參數(shù)
? ? ?* @return
? ? ?*/
? ? public?static?boolean checkHeaderName(){
? ? ? ? RequestAttributes ra = RequestContextHolder.getRequestAttributes();
? ? ? ? if(Objects.isNull(ra)){
? ? ? ? ? ? log.info("服務(wù)里RequestAttributes對(duì)象為空");
? ? ? ? ? ? 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獲取
/**
? ? ?*獲取 判斷請(qǐng)求頭的參數(shù)
? ? ?* @return
? ? ?*/
? ? public static?boolean?checkHeader(){
? ? ? ? RequestAttributes ra = RequestContextHolder.getRequestAttributes();
? ? ? ? if(Objects.isNull(ra)){
? ? ? ? ? ? log.info("服務(wù)里RequestAttributes對(duì)象為空");
? ? ? ? ? ? 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、修改請(qǐng)求頭信息
只能依靠反射原原理(HttpServletRequest中定義的對(duì)Header的操作全是只讀,沒(méi)有修改)。
假設(shè)的場(chǎng)景是,需要對(duì)請(qǐng)求Header統(tǒng)一添加一個(gè)x-request-id,通過(guò)這個(gè)ID來(lái)從日志中定位每一個(gè)請(qǐng)求。
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) {
?? ??? ?// 添加一個(gè)Header,隨機(jī)生成請(qǐng)求ID
?? ??? ?mimeHeaders.addValue("x-request-id").setString(UUID.randomUUID().toString());;
?? ??? ?// 移除一個(gè)header
?? ??? ?mimeHeaders.removeHeader("User-Agent");
?? ?}
}總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java實(shí)現(xiàn)統(tǒng)計(jì)在線(xiàn)人數(shù)功能的方法詳解
很多人在筆試或者面試中問(wèn)到:現(xiàn)在要你實(shí)現(xiàn)一個(gè)統(tǒng)計(jì)在線(xiàn)人數(shù)的功能,你該怎么設(shè)計(jì)?不知道的朋友,這篇文章就來(lái)告訴你具體實(shí)現(xiàn)方法2022-08-08
JAVA項(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)鍵步驟,同時(shí),也提供了如何將jar包上傳到Linux服務(wù)器并運(yùn)行的具體方法2024-10-10
java實(shí)現(xiàn)單鏈表倒轉(zhuǎn)的方法
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)單鏈表倒轉(zhuǎn)的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
Mybatis中and和循環(huán)or混用操作(or轉(zhuǎn)換成in)
這篇文章主要介紹了Mybatis中and和循環(huán)or混用操作(or轉(zhuǎn)換成in),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
springboot入門(mén)篇HelloWorld(圖文教程)
springboot?springboot是一個(gè)全新的框架,它設(shè)計(jì)的目的簡(jiǎn)化spring項(xiàng)目的初始環(huán)境的搭建和開(kāi)發(fā),下面這篇文章主要給大家介紹了關(guān)于springboot入門(mén)篇HelloWorld的相關(guān)資料,需要的朋友可以參考下2023-12-12

