溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么給HttpServletRequest增加消息頭

發布時間:2021-06-30 09:25:38 來源:億速云 閱讀:406 作者:小新 欄目:開發技術

小編給大家分享一下怎么給HttpServletRequest增加消息頭,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

HttpServletRequest增加header

由于在請求中請求域的屬性在請求轉發,路由等過程中,請求域的值會丟失,在項目項目中使用請求頭來傳遞信息,但是HttpRequest并沒有實現增加請求頭的方法,所以找到他的子類來實現

 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 {        
    }
}

但是項目中我使用的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() {
        //前置過濾器
        return "pre";
    }
    @Override
    public int filterOrder() {
        //優先級,數字越大,優先級越低
        return 0;
    }
    @Override
    public boolean shouldFilter() {
        //是否執行該過濾器,true代表需要過濾
        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("......................................................驗證1");
                Object object = helper.AccessZuul(request, ctx);
                return object;
            } else {
                System.out.println("......................................................驗證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);// 對該請求進行路由
                    ctx.setResponseStatusCode(200);
                    ctx.set("isSuccess", true);
                }else{
                    ctx.setSendZuulResponse(false);// 過濾該請求,不對其進行路由
                    ctx.setResponseStatusCode(401);// 返回錯誤碼
                    ctx.setResponseBody("{\"code\":0,\"result\":\"網關驗證失敗!驗證方式為2\"}");// 返回錯誤內容
                    ctx.set("isSuccess", false);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("網關報錯?。?!",e.fillInStackTrace());
        }
           return null;
    }

使用zuul網關的自帶的設置請求頭的方法,在網關中設置的請求頭可以被路由下面的服務獲取到:

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

修改HttpServletRequest中header的信息

廢話一堆:由于業務有統一的鑒權系統,頁面請求時在header中帶過來gsid,正常業務沒有問題,但是當需要下載文件時,前端統一用json解析響應,當響應文件時,對于前端來說不好處理,就決定使用簡單的get請求下載文件,將gsid通過url帶過來,這樣的話后端鑒權就需要處理,當header中沒有gsid時,從參數中取,為了盡可能少的改變公用的業務代碼(指sso),就在當前項目中自定義權限攔截器。

總結一句,我就是想想header中加東西??!往下看具體實現方式:

新建攔截器類,繼承原有的攔截器,重寫其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設置到request中的的header中去
        reflectSetparam(request,"GSID",gsid);
        log.info("請求連接中的gsid={}",request.getHeader("GSID"));
    }
    return super.preHandle(request, response, o);
}

說明:可以看到在方法中,

1、先進行header信息判斷,如果header中沒有GSID,就去請求參數中拿

gsid= request.getParameter("GSID");

2、通過反射將參數中的GSID鍵值對兒:“GSID”:“376645354562335”加入到header中去

話不多少,先上代碼,再解釋:

解釋:

/**
 * 修改header信息,key-value鍵值對兒加入到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實現類="+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實現類="+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();
    }
}

執行打印信息如下:

request實現類=org.apache.catalina.connector.RequestFacade

coyoteRequest實現類=org.apache.coyote.Request

看HttpServletRequest的源碼,是個接口,并且我們獲取header信息的方法是getHeader()方法,按常理其對象中應該有header字段,那么我們就去實現類中找這個字段,具體過程如下

步驟一:先找到具體的Request對象是哪個類,根據打印信息看源碼

進入其中找到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

怎么給HttpServletRequest增加消息頭

這個request,我們找到它的類型,點擊去

怎么給HttpServletRequest增加消息頭

這個類的全路徑是:org.apache.catalina.connector.Request

這個類中找getHeader方法

public String getHeader(String name) {
    return this.coyoteRequest.getHeader(name);
}

找到這個類中的coyoteRequest

protected org.apache.coyote.Request coyoteRequest;

是這樣的

怎么給HttpServletRequest增加消息頭

再找到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是一個MessageBytes對象,好找到這個對象進去,發現只能setValue,那就在MineHeaders中找在哪里實例化MessageBytes對象的

找了半天找到在createHeader()方法中實例化MimeHeaderField對象,然后這個對象實例化時會實例化MessageBytes對象

怎么給HttpServletRequest增加消息頭

這里有name,value,靠譜

然后再在MimeHeader中找在addValue方法中有調用,就用這個試一下吧,然后就是最上面的我自定義的方法,在heade中加入了一個鍵值對兒。

測試請求:

http://127.0.0.1:32100/v1/CustomerRefundRest/exportRefund?gsid=abc114f1bd0d484084e5df3fe1c419b8&refundLongStartDate=1520611199000&refundLongEndDate=1522943999000

測試打印結果:

怎么給HttpServletRequest增加消息頭怎么給HttpServletRequest增加消息頭

以上是“怎么給HttpServletRequest增加消息頭”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女