欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

在攔截器中讀取request參數(shù),解決在controller中無(wú)法二次讀取的問(wèn)題

 更新時(shí)間:2021年10月26日 11:28:47   作者:張子蘢  
這篇文章主要介紹了在攔截器中讀取request參數(shù),解決在controller中無(wú)法二次讀取的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

攔截器中讀取request參數(shù),在controller中無(wú)法二次讀取

新建類(lèi)

package com.ouyeelbuy.mc.common.base; 
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
 
/**
 * @author robin.zhang
 * @date $
 * @description 解決在request的數(shù)據(jù)流只能讀取一次的問(wèn)題
 */
public class RequestWrapper extends HttpServletRequestWrapper {
    private final String body;
    public RequestWrapper(HttpServletRequest request) {
        super(request);
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        InputStream inputStream = null;
        try {
            inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                char[] charBuffer = new char[128];
                int bytesRead = -1;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            } else {
                stringBuilder.append("");
            }
        } catch (IOException ex) {
 
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                }
                catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        body = stringBuilder.toString();
    }
 
    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
        ServletInputStream servletInputStream = new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }
            @Override
            public boolean isReady() {
                return false;
            }
            @Override
            public void setReadListener(ReadListener readListener) {
            }
            @Override
            public int read() throws IOException {
                return byteArrayInputStream.read();
            }
        };
        return servletInputStream; 
    }
 
    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(this.getInputStream()));
    }
 
    public String getBody() {
        return this.body;
    }
}

添加過(guò)濾器

package com.ouyeelbuy.mc.common.filter;
import com.ouyeelbuy.mc.common.base.RequestWrapper;
import org.springframework.stereotype.Component; 
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
 
/**
 * @author robin.zhang
 * @date $
 * @description 解決request數(shù)據(jù)流只能讀取一次的問(wèn)題
 */
@Component
public class RequestFilter implements Filter{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
 
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        ServletRequest requestWrapper = null;
        if(servletRequest instanceof HttpServletRequest) {
            requestWrapper = new RequestWrapper((HttpServletRequest) servletRequest);
        }
        if(requestWrapper == null) {
            filterChain.doFilter(servletRequest, servletResponse);
        } else {
            filterChain.doFilter(requestWrapper, servletResponse);
        }
    }
 
    @Override
    public void destroy() {
    }
}

然后注冊(cè)這個(gè)過(guò)濾器到spring容器中,問(wèn)題解決!

使用攔截器時(shí),controller中不能再次獲取body中的參數(shù)

報(bào)錯(cuò)信息:從報(bào)錯(cuò)信息可以看出,io流已經(jīng)關(guān)閉。這是由于攔截器讀取了body中的參數(shù)信息,導(dǎo)致controller不能再次讀取。

I/O error while reading input message; nested exception is java.io.IOException: Stream closed

解決辦法

在攔截器讀取到body信息后,再次將內(nèi)容寫(xiě)入

1、獲取body信息

import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;
 
/**
 * 保存流
 */
public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
    private final byte[] body; 
    public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) {
        super(request);
        String sessionStream = getBodyString(request);
        body = sessionStream.getBytes(Charset.forName("UTF-8"));
    }
 
    /**
     * 獲取請(qǐng)求Body
     *
     * @param request
     * @return
     */
    public String getBodyString(final ServletRequest request) {
        StringBuilder sb = new StringBuilder();
        InputStream inputStream = null;
        BufferedReader reader = null;
        try {
            inputStream = cloneInputStream(request.getInputStream());
            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
            String line = "";
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sb.toString();
    }
 
    /**
     * Description: 復(fù)制輸入流</br>
     *
     * @param inputStream
     * @return</br>
     */
    public InputStream cloneInputStream(ServletInputStream inputStream) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len;
        try {
            while ((len = inputStream.read(buffer)) > -1) {
                byteArrayOutputStream.write(buffer, 0, len);
            }
            byteArrayOutputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        InputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        return byteArrayInputStream;
    }
 
    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }
 
    @Override
    public ServletInputStream getInputStream() throws IOException { 
        final ByteArrayInputStream bais = new ByteArrayInputStream(body); 
        return new ServletInputStream() {
 
            @Override
            public int read() throws IOException {
                return bais.read();
            }
 
            @Override
            public boolean isFinished() {
                return false;
            }
 
            @Override
            public boolean isReady() {
                return false;
            }
 
            @Override
            public void setReadListener(ReadListener readListener) {
            }
        };
    }
}

2、重新寫(xiě)入

import org.springframework.core.annotation.Order;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
// 表示執(zhí)行過(guò)濾順序,值越小,越先執(zhí)行
@Order(1)
// 配置需要過(guò)濾的地址
@WebFilter(filterName = "bodyReaderFilter", urlPatterns = "/*")
public class BodyReaderFilter implements Filter {
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
//        System.out.println("--------------過(guò)濾器初始化------------");
    }
 
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//        System.out.println("--------------執(zhí)行過(guò)濾操作------------");
 
        // 防止流讀取一次后就沒(méi)有了, 所以需要將流繼續(xù)寫(xiě)出去
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(httpServletRequest);
        filterChain.doFilter(requestWrapper, servletResponse);
    }
 
    @Override
    public void destroy() {
//        System.out.println("--------------過(guò)濾器銷(xiāo)毀------------");
    } 
}

3、注冊(cè)過(guò)濾器

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
 
@SpringBootApplication
@EnableFeignClients
@EnableDiscoveryClient
// 注冊(cè)過(guò)濾器注解
@ServletComponentScan
public class WebPlatformApplication {
    public static void main(String[] args) {
        SpringApplication.run(WebPlatformApplication.class);
    }
}

添加完成后,運(yùn)行正常!

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

相關(guān)文章

  • java實(shí)現(xiàn)對(duì)對(duì)碰小游戲

    java實(shí)現(xiàn)對(duì)對(duì)碰小游戲

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)對(duì)對(duì)碰小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • 深入理解Java設(shè)計(jì)模式之狀態(tài)模式

    深入理解Java設(shè)計(jì)模式之狀態(tài)模式

    這篇文章主要介紹了JAVA設(shè)計(jì)模式之職責(zé)鏈模式的的相關(guān)資料,文中示例代碼非常詳細(xì),供大家參考和學(xué)習(xí),感興趣的朋友可以了解
    2021-11-11
  • 解決IDEA?2022?Translation?翻譯文檔失敗:?未知錯(cuò)誤的問(wèn)題

    解決IDEA?2022?Translation?翻譯文檔失敗:?未知錯(cuò)誤的問(wèn)題

    這篇文章主要介紹了IDEA?2022?Translation?翻譯文檔失敗:?未知錯(cuò)誤,本文較詳細(xì)的給大家介紹了IDEA?2022?Translation未知錯(cuò)誤翻譯文檔失敗的解決方法,需要的朋友可以參考下
    2022-04-04
  • Java詳解swagger2如何配置使用

    Java詳解swagger2如何配置使用

    編寫(xiě)和維護(hù)接口文檔是每個(gè)程序員的職責(zé),根據(jù)Swagger2可以快速幫助我們編寫(xiě)最新的API接口文檔,再也不用擔(dān)心開(kāi)會(huì)前仍忙于整理各種資料了,間接提升了團(tuán)隊(duì)開(kāi)發(fā)的溝通效率
    2022-06-06
  • Java設(shè)計(jì)模式之策略模式示例詳解

    Java設(shè)計(jì)模式之策略模式示例詳解

    策略模式屬于Java?23種設(shè)計(jì)模式中行為模式之一,該模式定義了一系列算法,并將每個(gè)算法封裝起來(lái),使它們可以相互替換,且算法的變化不會(huì)影響使用算法的客戶(hù)。本文將通過(guò)示例詳細(xì)講解這一模式,需要的可以參考一下
    2022-03-03
  • 深入了解Java核心類(lèi)庫(kù)--BigDecimal和System類(lèi)

    深入了解Java核心類(lèi)庫(kù)--BigDecimal和System類(lèi)

    這篇文章主要為大家詳細(xì)介紹了javaBigDecimal和System類(lèi)定義與使用的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能給你帶來(lái)幫助
    2021-07-07
  • Java常用函數(shù)式接口總結(jié)

    Java常用函數(shù)式接口總結(jié)

    今天給大家?guī)?lái)的是關(guān)于Java的相關(guān)知識(shí),文章圍繞著Java常用函數(shù)式接口展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • java 進(jìn)程是如何在Linux服務(wù)器上進(jìn)行內(nèi)存分配的

    java 進(jìn)程是如何在Linux服務(wù)器上進(jìn)行內(nèi)存分配的

    這篇文章主要介紹了java 進(jìn)程是如何在Linux服務(wù)器上進(jìn)行內(nèi)存分配的,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-11-11
  • Spring Cloud Stream如何實(shí)現(xiàn)服務(wù)之間的通訊

    Spring Cloud Stream如何實(shí)現(xiàn)服務(wù)之間的通訊

    這篇文章主要介紹了Spring Cloud Stream如何實(shí)現(xiàn)服務(wù)之間的通訊,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • Java的Lambda表達(dá)式和Stream流的作用以及示例

    Java的Lambda表達(dá)式和Stream流的作用以及示例

    這篇文章主要介紹了Java的Lambda表達(dá)式和Stream流簡(jiǎn)單示例,Lambda允許把函數(shù)作為一個(gè)方法的參數(shù),使用Lambda表達(dá)式可以寫(xiě)出更簡(jiǎn)潔、更靈活的代碼,而其作為一種更緊湊的代碼風(fēng)格,使Java的語(yǔ)言表達(dá)能力得到了提升,需要的朋友可以參考下
    2023-05-05

最新評(píng)論