最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

如何給HttpServletRequest增加消息頭

 更新時(shí)間:2021年06月29日 17:32:58   作者:meihuiziaaaaaa  
這篇文章主要介紹了如何給HttpServletRequest增加消息頭的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

HttpServletRequest增加header

由于在請(qǐng)求中請(qǐng)求域的屬性在請(qǐng)求轉(zhuǎn)發(fā),路由等過(guò)程中,請(qǐng)求域的值會(huì)丟失,在項(xiàng)目項(xiàng)目中使用請(qǐng)求頭來(lái)傳遞信息,但是HttpRequest并沒(méi)有實(shí)現(xiàn)增加請(qǐng)求頭的方法,所以找到他的子類來(lái)實(shí)現(xiàn)

 
class MutableHttpServletRequest extends HttpServletRequestWrapper {
    // holds custom header and value mapping
    private final Map<String, String> customHeaders; 
    public MutableHttpServletRequest(HttpServletRequest request){
        super(request);
        this.customHeaders = new HashMap<String, String>();
    }
    
    public void putHeader(String name, String value){
        this.customHeaders.put(name, value);
    }
 
    public String getHeader(String name) {
        // check the custom headers first
        String headerValue = customHeaders.get(name);
        
        if (headerValue != null){
            return headerValue;
        }
        // else return from into the original wrapped object
        return ((HttpServletRequest) getRequest()).getHeader(name);
    }
 
    public Enumeration<String> getHeaderNames() {
        // create a set of the custom header names
        Set<String> set = new HashSet<String>(customHeaders.keySet());
        
        // now add the headers from the wrapped request object
        @SuppressWarnings("unchecked")
        Enumeration<String> e = ((HttpServletRequest) getRequest()).getHeaderNames();
        while (e.hasMoreElements()) {
            // add the names of the request headers into the list
            String n = e.nextElement();
            set.add(n);
        }
 
        // create an enumeration from the set and return
        return Collections.enumeration(set);
    }
}

使用:

public class SecurityFilter implements javax.servlet.Filter { 
    @Override
    public void destroy() {        
    }
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        MutableHttpServletRequest mutableRequest = new MutableHttpServletRequest(req);
        ...
        mutableRequest.putHeader("x-custom-header", "custom value");
        chain.doFilter(mutableRequest, response);
    }
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {        
    }
}

但是項(xiàng)目中我使用的SpringCloud ZUUL中使用這樣 的方式失?。?/p>

@Component
public class AccessFilter extends ZuulFilter {
    private  Logger log = LoggerFactory.getLogger(AccessFilter.class);
    @Autowired
    private VerificationHelper helper;
    private  BufferedReader reader=null;
    @Autowired
    private KeyAndFrequencyService service;
    @Autowired
    private ZuulTest zuulTest;
    @Autowired
    private PermissionHandler permissionHandler;
    @Override
    public String filterType() {
        //前置過(guò)濾器
        return "pre";
    }
    @Override
    public int filterOrder() {
        //優(yōu)先級(jí),數(shù)字越大,優(yōu)先級(jí)越低
        return 0;
    }
    @Override
    public boolean shouldFilter() {
        //是否執(zhí)行該過(guò)濾器,true代表需要過(guò)濾
        return true;
    }
    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        try {
            permissionHandler.setTokenExpireTime(200000000);
            String type = request.getHeader("type");
            zuulTest.say();
            System.out.println("......................................................");
            if (type == null) {
                System.out.println("......................................................驗(yàn)證1");
                Object object = helper.AccessZuul(request, ctx);
                return object;
            } else {
                System.out.println("......................................................驗(yàn)證2");
                PermissionResult result=permissionHandler.check(request);
                System.out.println(result);
                if(result.isState()){
          
MutableHttpServletRequest  mutRequest=new MutableHttpServletRequest (request);
                     //增加頭部信息
                    DasAccountInfo accountInfo= permissionHandler.GetDasAccountInfoById(Integer.parseInt(result.getUserId()));
                    
                    mutRequest.putHeader("dasAccountInfo", JSON.toJSONString(disablePropertyName()))                   ;RequestContext.getCurrentContext().setRequest(mutRequest);
                    ctx.setSendZuulResponse(true);// 對(duì)該請(qǐng)求進(jìn)行路由
                    ctx.setResponseStatusCode(200);
                    ctx.set("isSuccess", true);
                }else{
                    ctx.setSendZuulResponse(false);// 過(guò)濾該請(qǐng)求,不對(duì)其進(jìn)行路由
                    ctx.setResponseStatusCode(401);// 返回錯(cuò)誤碼
                    ctx.setResponseBody("{\"code\":0,\"result\":\"網(wǎng)關(guān)驗(yàn)證失敗!驗(yàn)證方式為2\"}");// 返回錯(cuò)誤內(nèi)容
                    ctx.set("isSuccess", false);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("網(wǎng)關(guān)報(bào)錯(cuò)?。?!",e.fillInStackTrace());
        }
           return null;
    }

使用zuul網(wǎng)關(guān)的自帶的設(shè)置請(qǐng)求頭的方法,在網(wǎng)關(guān)中設(shè)置的請(qǐng)求頭可以被路由下面的服務(wù)獲取到:

ctx.getZuulRequestHeaders().put("dasAccountInfo", JSON.toJSONString(disablePropertyName()));

修改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)|西?。⊥驴?/strong>具體實(shí)現(xiàn)方式:

新建攔截器類,繼承原有的攔截器,重寫其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);
}

好了,終于見到屬性了

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)文章

  • Java面向?qū)ο筮x擇題總結(jié)歸納

    Java面向?qū)ο筮x擇題總結(jié)歸納

    今天小編就為大家分享一篇關(guān)于Java面向?qū)ο筮x擇題總結(jié)歸納,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-01-01
  • mybatis新增到數(shù)據(jù)庫(kù)后返回當(dāng)前ID問(wèn)題

    mybatis新增到數(shù)據(jù)庫(kù)后返回當(dāng)前ID問(wèn)題

    這篇文章主要介紹了mybatis新增到數(shù)據(jù)庫(kù)后返回當(dāng)前ID問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • RocketMQ發(fā)送事務(wù)消息詳解

    RocketMQ發(fā)送事務(wù)消息詳解

    這篇文章主要介紹了RocketMQ發(fā)送事務(wù)消息詳解,RocketMQ分布式事務(wù)消息不僅可以實(shí)現(xiàn)應(yīng)用之間的解耦,又能保證數(shù)據(jù)的最終一致性,傳統(tǒng)的大事務(wù)可以被拆分為小事務(wù),不僅能提升效率,還不會(huì)因?yàn)槟骋粋€(gè)關(guān)聯(lián)應(yīng)用的不可用導(dǎo)致整體回滾,需要的朋友可以參考下
    2023-09-09
  • 解決MyBatisPlus的updateBatchById()批量修改失效問(wèn)題

    解決MyBatisPlus的updateBatchById()批量修改失效問(wèn)題

    這篇文章主要介紹了解決MyBatisPlus的updateBatchById()批量修改失效問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • mybatis如何獲取剛剛新插入數(shù)據(jù)的主鍵值id

    mybatis如何獲取剛剛新插入數(shù)據(jù)的主鍵值id

    這篇文章主要介紹了mybatis如何獲取剛剛新插入數(shù)據(jù)的主鍵值id問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • java中jvm逃逸問(wèn)題分析

    java中jvm逃逸問(wèn)題分析

    本篇文章給大家詳細(xì)總結(jié)了java中jvm逃逸問(wèn)題的相關(guān)內(nèi)容,有興趣的朋友可以根據(jù)小編一起學(xué)習(xí)下。
    2018-02-02
  • mybatis攔截器與分頁(yè)插件實(shí)例教程

    mybatis攔截器與分頁(yè)插件實(shí)例教程

    Mybatis攔截器常常會(huì)被用來(lái)進(jìn)行分頁(yè)處理。所以下面這篇文章主要給大家介紹了關(guān)于mybatis攔截器與分頁(yè)插件的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用mybatis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • 詳解Android系統(tǒng)中的root權(quán)限獲得原理

    詳解Android系統(tǒng)中的root權(quán)限獲得原理

    這篇文章主要介紹了詳解Android系統(tǒng)中的Root權(quán)限獲得原理,安卓基于Linux,所以原理也相當(dāng)于Linux中的root用戶,需要的朋友可以參考下
    2015-08-08
  • Springboot項(xiàng)目刪除項(xiàng)目同步target文件問(wèn)題解決方案

    Springboot項(xiàng)目刪除項(xiàng)目同步target文件問(wèn)題解決方案

    這篇文章主要介紹了Springboot項(xiàng)目刪除項(xiàng)目同步target文件問(wèn)題解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Java中Springboot集成Kafka實(shí)現(xiàn)消息發(fā)送和接收功能

    Java中Springboot集成Kafka實(shí)現(xiàn)消息發(fā)送和接收功能

    Kafka是一個(gè)高吞吐量的分布式發(fā)布-訂閱消息系統(tǒng),主要用于處理大規(guī)模數(shù)據(jù)流,它由生產(chǎn)者、消費(fèi)者、主題、分區(qū)和代理等組件構(gòu)成,Kafka可以實(shí)現(xiàn)消息隊(duì)列、數(shù)據(jù)存儲(chǔ)和流處理等功能,在Java中,可以使用Spring Boot集成Kafka實(shí)現(xiàn)消息的發(fā)送和接收,感興趣的朋友跟隨小編一起看看吧
    2025-01-01

最新評(píng)論

黄浦区| 宝坻区| 凤山市| 西乌珠穆沁旗| 东平县| 汝城县| 凤庆县| 仁怀市| 友谊县| 长乐市| 皋兰县| 宾阳县| 凤庆县| 三亚市| 五峰| 禹州市| 顺义区| 哈密市| 青冈县| 望江县| 揭西县| 依兰县| 涟水县| 平和县| 莒南县| 满城县| 财经| 额尔古纳市| 祁阳县| 东辽县| 石泉县| 宿松县| 青神县| 石阡县| 冀州市| 敦化市| 水城县| 昌图县| 邻水| 佛学| 八宿县|