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

解讀HttpServletRequestWrapper處理request數(shù)據(jù)流多次讀取問題

 更新時間:2024年10月09日 10:07:26   作者:小旋風(fēng)-java  
在Java Web開發(fā)中,獲取HTTP請求參數(shù)是常見需求,本文詳細討論了通過POST方式獲取參數(shù)的兩種主要方法:使用request.getParameter()適用于application/x-www-form-urlencoded和multipart/form-data內(nèi)容類型;而對于application/json類型的數(shù)據(jù)

本次討論post方式獲取參數(shù),request.getInputStream()獲取一次以后不能第二次獲取,以及request.getParameter()與request.getInputStream()也存在這種情況

一、獲取請求參數(shù)

  • 1、request.getParameter()
  • 2、request.getInputStream()或request.getReader()

二、請求方contentType

1、application/x-www-form-urlencoded

@RequestMapping("/testWwwFrom")
@ResponseBody
public Book testWwwFrom(Book req, HttpServletRequest servletRequest) {
    logger.info("查詢所有1用戶信息" + JSON.toJSONString(req));
    return req;
}

2、multipart/form-data

@RequestMapping("/testFormData")
@ResponseBody
public Book testFormData(Book req, HttpServletRequest servletRequest) {
    logger.info("查詢所有1用戶信息" + JSON.toJSONString(req));
    return req;
}

3、application/json

@RequestMapping("/testJson")
@ResponseBody
public Book testJsonFrom(@RequestBody Book req, HttpServletRequest servletRequest) {
    logger.info("查詢所有1用戶信息" + JSON.toJSONString(req));
?
    return req;
}
  • 1、request.getParameter()對應(yīng)application/x-www-form-urlencoded
  • 2、request.getInputStream()或request.getReader()對應(yīng)application/json

那么現(xiàn)在有一個這樣的需求如果是form表單就獲取formToken然后和緩存的進行CRSF防護

思路根據(jù)上面說的form表單參數(shù)獲取分為2大類。

其中request.getInputStream()獲取一次以后不能第二次獲取,以及request.getParameter()與request.getInputStream()也存在這種情況。

  • 1、application/x-www-form-urlencoded以及multipart/form-data通過request.getParameter()獲取
  • 2、application/json通過request.getInputStream()或request.getReader()獲取,這種要依賴HttpServletRequestWrapper
package com.study.ju.web.interceptor;
?
import org.apache.commons.io.IOUtils;
?
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
?
/**
 * <p>https://blog.csdn.net/kaizhangzhang/article/details/97900961</p>
 *
 * 
 * @version v 0.1 2023/5/29 15:37
 */
public class ResettableServletRequestWrapper extends HttpServletRequestWrapper {
    //保存流中的數(shù)據(jù)
    private byte[] data;
?
    /**
     * Constructs a request object wrapping the given request.
     *
     * @param request
     * @throws IllegalArgumentException if the request is null
     */
    public ResettableServletRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        //從流中獲取數(shù)據(jù)
        data = IOUtils.toByteArray(request.getInputStream());
    }
?
    @Override
    public ServletInputStream getInputStream() throws IOException {
        //在調(diào)用getInputStream函數(shù)時,創(chuàng)建新的流,包含原先數(shù)據(jù)流中的信息,然后返回
        return new NewServletInputStream(new ByteArrayInputStream(data));
    }
?
    class NewServletInputStream extends ServletInputStream{
        private InputStream inputStream;
?
        public NewServletInputStream(InputStream inputStream){
            this.inputStream = inputStream;
        }
?
        @Override
        public int read() throws IOException {
            return inputStream.read();
        }
?
        @Override
        public boolean isFinished() {
            return false;
        }
?
        @Override
        public boolean isReady() {
            return false;
        }
?
        @Override
        public void setReadListener(ReadListener readListener) {
?
        }
    }
    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }
?
?
}
package com.study.ju.web.interceptor;
?
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
?
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;
?
/**
 * <p>form表單提交校驗token</p>
 *
 * 
 * @version v 0.1 2023/5/29 13:45
 */
public class FormSubmitTokenInterceptor implements HandlerInterceptor {
?
?
    private String formSubmitTokenInterceptorUrls = "[\"/testJson\",\"/test/testJson\",\"/test/testWwwFrom\",\"/test/testRequestParam\"]";
?
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestURI = getRequestURI(request);
        if ("POST".equals(request.getMethod().toUpperCase()) && StringUtils.isNotEmpty(formSubmitTokenInterceptorUrls)) {
            List<String> formInterceptorUrls = JSONArray.parseArray(formSubmitTokenInterceptorUrls, String.class);
            if (CollectionUtils.isNotEmpty(formInterceptorUrls)) {
                boolean contains = formInterceptorUrls.stream().anyMatch(e -> e.contains(requestURI));
                if (contains) {
                    String contentType = request.getContentType();
                    System.out.println(contentType);
                    if ("application/json".equalsIgnoreCase(contentType)) {
                        ResettableServletRequestWrapper resettableServletRequestWrapper = new ResettableServletRequestWrapper(request);
                        String bodyParam = IOUtils.toString(resettableServletRequestWrapper.getInputStream());
                        System.out.println(bodyParam);
                        if (StringUtils.isNotEmpty(bodyParam)) {
                            JSONObject jsonObject = JSONObject.parseObject(bodyParam);
                            if (jsonObject.containsKey("formToken")) {
                                String formToken = (String) jsonObject.get("formToken");
                                System.out.println("formToken:"+formToken);
                            }
                        }
?
                    } else {
                        if (StringUtils.isNotEmpty(request.getParameter("formToken"))) {
                            System.out.println("formToken2:"+request.getParameter("formToken"));
                        }
                        System.out.println("name:"+request.getParameter("name"));
                    }
?
?
                }
?
            }
        }
        return true;
    }
?
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
?
    }
?
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
?
    }
?
    /**
     * 獲取用戶請求的path,不帶contextPath
     * 如:/index.htm
     */
    public static String getRequestURI(HttpServletRequest request) {
        return StringUtils.replace(request.getRequestURI(), request.getContextPath(), "");
    }
}

web.xml放在前面

<filter>
   <filter-name>requestFilter</filter-name>
   <filter-class>com.study.ju.web.Filter.HttpServletRequestReplacedFilter</filter-class>
</filter>
<filter-mapping>
   <filter-name>requestFilter</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • IDEA項目使用SpringBoot+MyBatis-Plus的方法

    IDEA項目使用SpringBoot+MyBatis-Plus的方法

    這篇文章主要介紹了IDEA項目使用SpringBoot+MyBatis-Plus的方法,本文分步驟通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • Springboot集成Proguard生成混淆jar包方式

    Springboot集成Proguard生成混淆jar包方式

    本文介紹了兩種Java代碼混淆工具:ClassFinal和ProGuard,ClassFinal是一個字節(jié)碼加密工具,但需要額外的加密包,使用復(fù)雜,ProGuard是一款開源的Java代碼混淆工具,可以有效地提高代碼的安全性,但對Spring框架的注解處理不夠完善
    2024-11-11
  • mybatis類型轉(zhuǎn)換器如何實現(xiàn)數(shù)據(jù)加解密

    mybatis類型轉(zhuǎn)換器如何實現(xiàn)數(shù)據(jù)加解密

    這篇文章主要介紹了mybatis類型轉(zhuǎn)換器如何實現(xiàn)數(shù)據(jù)加解密,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java9 Stream Collectors新增功能(小結(jié))

    Java9 Stream Collectors新增功能(小結(jié))

    這篇文章主要介紹了Java9 Stream Collectors新增功能(小結(jié)),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • java和 javaw 及 javaws的區(qū)別解析

    java和 javaw 及 javaws的區(qū)別解析

    這篇文章主要介紹了java和 javaw 及 javaws的區(qū)別解析,本文通過實例給大家詳細介紹,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • 淺談Mybatis Plus的BaseMapper的方法是如何注入的

    淺談Mybatis Plus的BaseMapper的方法是如何注入的

    我們在用的時候經(jīng)常就是生產(chǎn)自定義的Mapper繼承自BaseMapper,那么BaseMapper怎么被注入到mybatis里的,本文就詳細的介紹一下,感興趣的可以了解一下
    2021-09-09
  • Java之JFrame輸出Helloworld實例

    Java之JFrame輸出Helloworld實例

    這篇文章主要介紹了Java之JFrame輸出Helloworld的方法,以輸出Helloworld的實例分析了JFrame的簡單入門技巧,需要的朋友可以參考下
    2015-02-02
  • JavaSE系列基礎(chǔ)包裝類及日歷類詳解

    JavaSE系列基礎(chǔ)包裝類及日歷類詳解

    這篇文章主要介紹的是JavaSE中常用的基礎(chǔ)包裝類以及日歷類的使用詳解,文中的示例代碼簡潔易懂,對我們學(xué)習(xí)JavaSE有一定的幫助,感興趣的小伙伴快來跟隨小編一起學(xué)習(xí)吧
    2021-12-12
  • Java使用正則表達式刪除所有HTML標(biāo)簽的方法示例

    Java使用正則表達式刪除所有HTML標(biāo)簽的方法示例

    這篇文章主要介紹了Java使用正則表達式刪除所有HTML標(biāo)簽的方法,結(jié)合完整實例形式分析了java針對HTML頁面元素script標(biāo)簽、style標(biāo)簽、html標(biāo)簽等的正則匹配相關(guān)操作技巧,需要的朋友可以參考下
    2017-06-06
  • Java中使用開源庫JSoup解析HTML文件實例

    Java中使用開源庫JSoup解析HTML文件實例

    這篇文章主要介紹了Java中使用開源庫JSoup解析HTML文件實例,Jsoup是一個開源的Java庫,它可以用于處理實際應(yīng)用中的HTML,比如常見的HTML格式化就可以用它來實現(xiàn),需要的朋友可以參考下
    2014-09-09

最新評論

浠水县| 新兴县| 错那县| 平和县| 永德县| 乐东| 罗城| 宁武县| 无极县| 勃利县| 海城市| 乌鲁木齐县| 襄垣县| 芒康县| 巨野县| 汤阴县| 珲春市| 泊头市| 屯留县| 西昌市| 金寨县| 台北县| 郸城县| 民和| 眉山市| 吉安县| 陵水| 辉县市| 渭源县| 射洪县| 平定县| 西华县| 横山县| 娄底市| 青海省| 邹平县| 武强县| 泰安市| 乐陵市| 罗平县| 南涧|