如何修改HttpServletRequest中header中的信息
廢話一堆:
由于業(yè)務(wù)有統(tǒng)一的鑒權(quán)系統(tǒng),頁(yè)面請(qǐng)求時(shí)在header中帶過(guò)來(lái)gsid,正常業(yè)務(wù)沒(méi)有問(wèn)題,但是當(dāng)需要下載文件時(shí),前端統(tǒng)一用json解析響應(yīng),當(dāng)響應(yīng)文件時(shí),對(duì)于前端來(lái)說(shuō)不好處理,就決定使用簡(jiǎn)單的get請(qǐng)求下載文件,將gsid通過(guò)url帶過(guò)來(lái),這樣的話后端鑒權(quán)就需要處理,當(dāng)header中沒(méi)有g(shù)sid時(shí),從參數(shù)中取,為了盡可能少的改變公用的業(yè)務(wù)代碼(指sso),就在當(dāng)前項(xiàng)目中自定義權(quán)限攔截器。
總結(jié)一句話
我就是想想header中加?xùn)|西??!
往下看具體實(shí)現(xiàn)方式
新建攔截器類,繼承原有的攔截器,重寫(xiě)其preHandle方法
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
String gsid = request.getHeader("GSID");
if(StringUtils.isBlank(gsid)){
String gsid= request.getParameter("GSID");
//使用反射,將gsid設(shè)置到request中的的header中去
reflectSetparam(request,"GSID",gsid);
log.info("請(qǐng)求連接中的gsid={}",request.getHeader("GSID"));
}
return super.preHandle(request, response, o);
}
說(shuō)明:可以看到在方法中
1、先進(jìn)行header信息判斷,如果header中沒(méi)有GSID,就去請(qǐng)求參數(shù)中拿
gsid= request.getParameter("GSID");2、通過(guò)反射將參數(shù)中的GSID鍵值對(duì)兒:“GSID”:“376645354562335”加入到header中去
話不多少,先上代碼,再解釋:
解釋
/**
* 修改header信息,key-value鍵值對(duì)兒加入到header中
* @param request
* @param key
* @param value
*/
private void reflectSetparam(HttpServletRequest request,String key,String value){
Class<? extends HttpServletRequest> requestClass = request.getClass();
System.out.println("request實(shí)現(xiàn)類="+requestClass.getName());
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);
System.out.println("coyoteRequest實(shí)現(xiàn)類="+o1.getClass().getName());
Field headers = o1.getClass().getDeclaredField("headers");
headers.setAccessible(true);
MimeHeaders o2 = (MimeHeaders)headers.get(o1);
o2.addValue(key).setString(value);
} catch (Exception e) {
e.printStackTrace();
}
}
執(zhí)行打印信息如下:
request實(shí)現(xiàn)類=org.apache.catalina.connector.RequestFacade
coyoteRequest實(shí)現(xiàn)類=org.apache.coyote.Request
看HttpServletRequest的源碼,是個(gè)接口,并且我們獲取header信息的方法是getHeader()方法,按常理其對(duì)象中應(yīng)該有header字段,那么我們就去實(shí)現(xiàn)類中找這個(gè)字段
具體過(guò)程如下
步驟一:先找到具體的Request對(duì)象是哪個(gè)類,根據(jù)打印信息看源碼
進(jìn)入其中找到getHeader()方法,如下
public String getHeader(String name) {
if (this.request == null) {
throw new IllegalStateException(sm.getString("requestFacade.nullRequest"));
} else {
return this.request.getHeader(name);
}
}
然后我們找this.request

這個(gè)request,我們找到它的類型,點(diǎn)擊去

這個(gè)類的全路徑是:org.apache.catalina.connector.Request
這個(gè)類中找getHeader方法
public String getHeader(String name) {
return this.coyoteRequest.getHeader(name);
}找到這個(gè)類中的coyoteRequest
protected org.apache.coyote.Request coyoteRequest;
是這樣的

再找到getHeader()
public String getHeader(String name) {
return this.headers.getHeader(name);
}好了,終于見(jiàn)到屬性了
private final MimeHeaders headers = new MimeHeaders();
找到MineHeaders中的getHeader方法,
public String getHeader(String name) {
MessageBytes mh = this.getValue(name);
return mh != null ? mh.toString() : null;
}看到最終header是一個(gè)MessageBytes對(duì)象,好找到這個(gè)對(duì)象進(jìn)去,發(fā)現(xiàn)只能setValue,那就在MineHeaders中找在哪里實(shí)例化MessageBytes對(duì)象的
找了半天找到在createHeader()方法中實(shí)例化MimeHeaderField對(duì)象,然后這個(gè)對(duì)象實(shí)例化時(shí)會(huì)實(shí)例化MessageBytes對(duì)象

這里有name,value,靠譜
然后再在MimeHeader中找在addValue方法中有調(diào)用,就用這個(gè)試一下吧,然后就是最上面的我自定義的方法,在heade中加入了一個(gè)鍵值對(duì)兒。
測(cè)試請(qǐng)求:
http://127.0.0.1:32100/v1/CustomerRefundRest/exportRefund?gsid=abc114f1bd0d484084e5df3fe1c419b8&refundLongStartDate=1520611199000&refundLongEndDate=1522943999000
測(cè)試打印結(jié)果:


OVER!
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
深入解析Jdk8中Stream流的使用讓你脫離for循環(huán)
這篇文章主要介紹了Jdk8中Stream流的使用,讓你脫離for循環(huán),本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02
springboot與vue詳解實(shí)現(xiàn)短信發(fā)送流程
隨著人工智能的不斷發(fā)展,機(jī)器學(xué)習(xí)這門技術(shù)也越來(lái)越重要,很多人都開(kāi)啟了學(xué)習(xí)機(jī)器學(xué)習(xí),本文就介紹了機(jī)器學(xué)習(xí)的基礎(chǔ)內(nèi)容2022-06-06
Java讀取properties文件連接數(shù)據(jù)庫(kù)的方法示例
這篇文章主要介紹了Java讀取properties文件連接數(shù)據(jù)庫(kù)的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-04-04
一文詳細(xì)解析Java?8?Stream?API中的flatMap方法
這篇文章主要介紹了Java?8?Stream?API中的flatMap方法的相關(guān)資料,flatMap方法是Java?StreamAPI中的重要中間操作,用于將流中的每個(gè)元素轉(zhuǎn)換為一個(gè)新的流,并將多個(gè)流合并為一個(gè)單一的流,常用于處理嵌套集合和一對(duì)多映射,需要的朋友可以參考下2024-12-12
一篇超詳細(xì)的SpringBoot整合MybatisPlus的文章
這篇文章主要介紹了springboot整合Mybatis-plus的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-07-07
Spring事務(wù)失效的各種場(chǎng)景(13種)
本文主要介紹了Spring事務(wù)失效的各種場(chǎng)景,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
使用Springboot注入帶參數(shù)的構(gòu)造函數(shù)實(shí)例
這篇文章主要介紹了使用Springboot注入帶參數(shù)的構(gòu)造函數(shù)實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04
Java 并發(fā)編程之ThreadLocal詳解及實(shí)例
這篇文章主要介紹了Java 并發(fā)編程之ThreadLocal詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-02-02

