亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

關(guān)于Filter中獲取請(qǐng)求體body后再次讀取的問(wèn)題

 更新時(shí)間:2022年03月15日 10:50:58   作者:fayeyiwang  
這篇文章主要介紹了關(guān)于Filter中獲取請(qǐng)求體body后再次讀取的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Filter獲取請(qǐng)求體body再次讀取

工作需要,要將請(qǐng)求和響應(yīng)做一些處理,寫(xiě)一個(gè)filter攔截請(qǐng)求,攔截request中body內(nèi)容后,字符流關(guān)閉,controller取到的請(qǐng)求體內(nèi)容為空。

從Request中獲取輸入流,InputStream只能被讀取一次。

解決方案

給request添加一個(gè)包裝類BodyWrapper,繼承HttpServletRequestWrapper,

先從request中取輸入流,讀取流中的數(shù)據(jù),然后重寫(xiě)getInputStream()和getReader()方法。

chain.doFilter(requestWrapper, response);
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Enumeration;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import com.xera.fsafesso.HttpHelper;
public class BodyWrapper extends HttpServletRequestWrapper {undefined
? ? private final byte[] body;
? ? public BodyWrapper(HttpServletRequest request) throws IOException {undefined
? ? ? ? super(request);
? ? ? ? body = HttpHelper.getBodyString(request).getBytes(Charset.forName("UTF-8"));
? ? }
? ? @Override
? ? public BufferedReader getReader() throws IOException {undefined
? ? ? ? return new BufferedReader(new InputStreamReader(getInputStream()));
? ? }
? ? @Override
? ? public ServletInputStream getInputStream() throws IOException {undefined
? ? ? ? final ByteArrayInputStream bais = new ByteArrayInputStream(body);
? ? ? ? return new ServletInputStream(){undefined
? ? ? ? ? ? @Override
? ? ? ? ? ? public int read() throws IOException {undefined
? ? ? ? ? ? ? ? return bais.read();
? ? ? ? ? ? }
? ? ? ? ? ? @Override
? ? ? ? ? ? public boolean isFinished() {undefined
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
? ? ? ? ? ? @Override
? ? ? ? ? ? public boolean isReady() {undefined
? ? ? ? ? ? ? ? return false;
? ? ? ? ? ? }
? ? ? ? ? ? @Override
? ? ? ? ? ? public void setReadListener(ReadListener arg0) {undefined
? ? ? ? ? ? }
? ? ? ? };
? ? }
? ? @Override
? ? public String getHeader(String name) {undefined
? ? ? ? return super.getHeader(name);
? ? }
? ? @Override
? ? public Enumeration<String> getHeaderNames() {undefined
? ? ? ? return super.getHeaderNames();
? ? }
? ? @Override
? ? public Enumeration<String> getHeaders(String name) {undefined
? ? ? ? return super.getHeaders(name);
? ? }
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import javax.servlet.ServletRequest;
public class HttpHelper {undefined
? ? ?/**
? ? ?* 獲取請(qǐng)求Body
? ? ?* @param request
? ? ?* @return
? ? ?*/
? ? public static String getBodyString(ServletRequest request) {undefined
? ? ? ? StringBuilder sb = new StringBuilder();
? ? ? ? InputStream inputStream = null;
? ? ? ? BufferedReader reader = null;
? ? ? ? try {undefined
? ? ? ? ? ? inputStream = request.getInputStream();
? ? ? ? ? ? reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
? ? ? ? ? ? String line = "";
? ? ? ? ? ? while ((line = reader.readLine()) != null) {undefined
? ? ? ? ? ? ? ? sb.append(line);
? ? ? ? ? ? }
? ? ? ? } catch (IOException e) {undefined
? ? ? ? ? ? e.printStackTrace();
? ? ? ? } finally {undefined
? ? ? ? ? ? if (inputStream != null) {undefined
? ? ? ? ? ? ? ? try {undefined
? ? ? ? ? ? ? ? ? ? inputStream.close();
? ? ? ? ? ? ? ? } catch (IOException e) {undefined
? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? if (reader != null) {undefined
? ? ? ? ? ? ? ? try {undefined
? ? ? ? ? ? ? ? ? ? reader.close();
? ? ? ? ? ? ? ? } catch (IOException e) {undefined
? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return sb.toString();
? ? }
}

Filter中寫(xiě)法如下:

HttpServletRequest httpServletRequest = (HttpServletRequest) request;
? ? ? ? ? ? Map<String, String> requestMap = this.getTypesafeRequestMap(httpServletRequest);
? ? ? ? ? ? requestWrapper = new BodyWrapper(httpServletRequest);
? ? ? ? ? ? String body = HttpHelper.getBodyString(requestWrapper);
? ? ? ? ? ? log.info("loggingFilter---請(qǐng)求路徑 {},請(qǐng)求參數(shù) {},請(qǐng)求體內(nèi)容 {}",httpServletRequest.getRequestURL(),requestMap,body);
? ? ? chain.doFilter(requestWrapper, response);

在使用注解的方式(即@WebFilter)聲明過(guò)濾器時(shí),

需要再main函數(shù)類上添加@ServletComponentScan(basePackages = "此處寫(xiě)明類地址,格式為包名+類名(如com.*) 

Http請(qǐng)求解決body流一旦被讀取了就無(wú)法二次讀取情況

相信大家在工作當(dāng)中,經(jīng)常會(huì)遇到需要處理http請(qǐng)求及響應(yīng)body的場(chǎng)景,這里最大的問(wèn)題應(yīng)該就是body中流以但被讀取就無(wú)法二次讀取了。

解決request請(qǐng)求流只能讀取一次的問(wèn)題

我們編寫(xiě)一個(gè)過(guò)濾器,這樣就可以重寫(xiě)body了

package com.interceptor; 
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
public class MyFilter implements Filter {
    private static String privateKey ;    
    public String getPrivateKey() { 
		return privateKey;
	}
	public void setPrivateKey(String key) {
		privateKey = key;
	}
 
	/**
     *  排除過(guò)濾路徑
     */
    List<String> ignore = Arrays.asList("/xxxx");
    
    /**
     *   前綴排除   如 /static/goods 排除
     */
    List<String> ignorePrefix = Arrays.asList( "/css/", "/pop/", "/js/", "/static/", "/images/", "/favicon.ico");
    
    /**
     *  排除過(guò)濾路徑
     */
    List<String> ignoreSuffix = Arrays.asList("/test");
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    	//過(guò)濾器初始化
    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        // 防止流讀取一次后就沒(méi)有了, 所以需要將流繼續(xù)寫(xiě)出去
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String uri = request.getServletPath();
        response.setContentType("application/json;charset=UTF-8");
        ServletRequest requestWrapper = null;
        if(canIgnore(uri)) {
        	requestWrapper = new MyFilterBodyReaderHttpServletRequestWrapper(request);
        	filterChain.doFilter(requestWrapper, response);
        	return;
        }
    	try {
    		requestWrapper = new MyFilterBodyReaderHttpServletRequestWrapper(request, response, privateKey);
		} catch (Exception e) {
			e.printStackTrace();
			return;
		}
    	filterChain.doFilter(requestWrapper, servletResponse);
    }
 
    @Override
    public void destroy() {
    	//過(guò)濾器銷毀
    }
    
    private boolean canIgnore(String uri) {  
    	
    	logger.info("過(guò)濾器  request  uri : {} ",uri);
        boolean isExcludedPage = false;
        for (String page : ignore) {
            if (uri.equals(page)) {
            	logger.info("請(qǐng)求路徑不需要攔截,忽略該uri : {} ",uri);
                isExcludedPage = true;
                break;
            }
        }
        
        for (String prefix : ignorePrefix) {
            if (uri.startsWith(prefix)) {
            	logger.info("請(qǐng)求路徑前綴[{}],不攔截該uri : {} ", prefix, uri);
                isExcludedPage = true;
                break;
            }
        }
        
        for (String prefix : ignoreSuffix) {
        	if (uri.endsWith(prefix)) {
        		logger.info("請(qǐng)求路徑后綴[{}],不攔截該uri : {} ", prefix, uri);
        		isExcludedPage = true;
        		break;
        	}
        }
        return isExcludedPage;
    }
} 
 
  
package com.interceptor; 
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Map;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSON;
 
/**
* @Description: TODO 過(guò)濾器處理requestbody獲取一次就失效
*/
public class MyFilterBodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
    private final byte[] body;
    /**
     * TODO 重寫(xiě)requestbody
     * @param request
     * @throws IOException
     */
    public MyFilterBodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
    	super(request);
    	String sessionStream = getBodyString(request);
    	body = sessionStream.getBytes(Charset.forName("UTF-8"));
    }
 
    /**
     * TODO 攔截解密,校驗(yàn),重寫(xiě)requestbody
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
	public MyFilterBodyReaderHttpServletRequestWrapper(HttpServletRequest request,HttpServletResponse response, String clientKey, Boolean ignoreCheckSign) throws Exception {
        super(request);
        String sessionStream = getBodyString(request);
        Map paramMap = (Map) JSON.parse(sessionStream);
      /**
        *自己項(xiàng)目中與合作方的加解密內(nèi)容
        *如:String data= (String) paramMap.get("data");
        *    String json=xxxxxutil.decrypt(參數(shù));
      */
        body = json.getBytes(Charset.forName("UTF-8"));
    }
    
    /**
    * TODO 獲取請(qǐng)求Body
    * @param request
    * @return
    * @throws 
    */
    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();
    }
    
    /**
    * TODO 無(wú)參獲取請(qǐng)求Body
    * @return
    * @throws 
    */
    public String getBodyString() {
    	if (body == null) {
            return null;
        }
        String str = new String(body);
        return str;
    }
 
    /**
    * TODO 復(fù)制輸入流
    * @param inputStream
    * @return
    * @throws 
    */
    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) {
            }
        };
    }
} 

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

相關(guān)文章

  • Java的Shiro框架認(rèn)證流程詳解

    Java的Shiro框架認(rèn)證流程詳解

    這篇文章主要介紹了Java的Shiro框架認(rèn)證流程詳解,Shiro 是一個(gè)功能強(qiáng)大和易于使用的安全框架,為開(kāi)發(fā)人員提供一個(gè)直觀而全面的解決方案的認(rèn)證,授權(quán),加密,會(huì)話管理四大功能,需要的朋友可以參考下
    2024-01-01
  • Feign調(diào)用全局異常處理解決方案

    Feign調(diào)用全局異常處理解決方案

    這篇文章主要介紹了Feign調(diào)用全局異常處理解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • springboot詳解整合swagger方案

    springboot詳解整合swagger方案

    Swagger是一個(gè)規(guī)范和完整的框架,用于生成、描述、調(diào)用和可視化?Restful?風(fēng)格的?Web?服務(wù)。總體目標(biāo)是使客戶端和文件系統(tǒng)作為服務(wù)器以同樣的速度來(lái)更新。文件的方法、參數(shù)和模型緊密集成到服務(wù)器端的代碼,允許API來(lái)始終保持同步
    2022-07-07
  • 簡(jiǎn)單實(shí)現(xiàn)Servlet文件下載功能

    簡(jiǎn)單實(shí)現(xiàn)Servlet文件下載功能

    這篇文章主要教大家如何簡(jiǎn)單實(shí)現(xiàn)Servlet文件下載功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • SpringBoot+MybatisPlus+代碼生成器整合示例

    SpringBoot+MybatisPlus+代碼生成器整合示例

    這篇文章主要介紹了SpringBoot+MybatisPlus+代碼生成器整合示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • SpringBoot深入分析講解監(jiān)聽(tīng)器模式上

    SpringBoot深入分析講解監(jiān)聽(tīng)器模式上

    監(jiān)聽(tīng)器模式,大家應(yīng)該并不陌生,主要的組成要素包括了事件、監(jiān)聽(tīng)器以及廣播器;當(dāng)事件發(fā)生時(shí),廣播器負(fù)責(zé)將事件傳遞給所有已知的監(jiān)聽(tīng)器,而監(jiān)聽(tīng)器會(huì)對(duì)自己感興趣的事件進(jìn)行處理
    2022-07-07
  • Maven在Java8下如何忽略Javadoc的編譯錯(cuò)誤詳解

    Maven在Java8下如何忽略Javadoc的編譯錯(cuò)誤詳解

    這篇文章主要給大家介紹了關(guān)于Maven在Java8下如何忽略Javadoc的編譯錯(cuò)誤的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • Java實(shí)現(xiàn)斷點(diǎn)續(xù)傳功能的示例代碼

    Java實(shí)現(xiàn)斷點(diǎn)續(xù)傳功能的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用Java語(yǔ)言實(shí)現(xiàn)網(wǎng)絡(luò)資源的斷點(diǎn)續(xù)傳功能,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的可以了解一下
    2022-10-10
  • Java實(shí)現(xiàn)RSA算法的方法詳解

    Java實(shí)現(xiàn)RSA算法的方法詳解

    這篇文章主要介紹了Java實(shí)現(xiàn)RSA算法的方法,結(jié)合實(shí)例形式分析了RSA算法的原理、實(shí)現(xiàn)與使用方法,需要的朋友可以參考下
    2018-03-03
  • 如何使用XPath提取xml文檔數(shù)據(jù)

    如何使用XPath提取xml文檔數(shù)據(jù)

    這篇文章主要介紹了如何使用XPath提取xml文檔數(shù)據(jù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08

最新評(píng)論