Springboot 使用過濾器進行加密解密(二)


之前寫過一篇關於過濾器實現加密解密功能的文章,但是在實際開發業務中發現,還是有一些問題的,在此特地說明。

第一:過濾器走兩遍的問題:

1.過濾器上,添加了兩個注解

第一個:@Compent   將此Filter交給Spring容器管理

第二個:@WebFilter通過WebFilter進行Filter聲明,這樣容器在進行部署的時候就會處理該Filter

2.啟動類上添加的注解

@ServletComponentScan  作用:Servlet、Filter、Listener 可以直接通過 @WebServlet、@WebFilter、@WebListener 注解自動注冊(自動掃描帶有過濾器注解的包)

3.問題:項目啟動后,一個請求執行兩次

原因:@Compent 啟動時,會加載Filter.  @ServletComponentScan 也會掃描過濾器。所以會加載兩次

4.解決措施:

去掉過濾器上的@Compent 注解之后,請求過濾一次。

第二:響應結果跟加密結果不一致的問題

1.之前使用的包裝類,不知道為何,加密的結果和最終響應的結果不一致,並且是有規律的少。

各位大神,如果知道為什么的話,麻煩指點一下。

 

2.解決辦法:直接換了一個包裝類,代碼如下:

包裝類代碼:

import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.UnsupportedEncodingException; import javax.servlet.ServletOutputStream; import javax.servlet.WriteListener; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; /** * reponse包裝類,對reponse響應進行處理后,傳給客戶端 * @Author: kiki * @Date: 2018/12/18 */
public class WrapperedResponse extends HttpServletResponseWrapper { private ByteArrayOutputStream buffer = null; private ServletOutputStream out = null; private PrintWriter writer = null; public WrapperedResponse(HttpServletResponse resp) throws IOException { super(resp); buffer = new ByteArrayOutputStream();//真正存儲數據的流
        out = new WrapperedResponse.WapperedOutputStream(buffer); writer = new PrintWriter(new OutputStreamWriter(buffer, this.getCharacterEncoding())); } //重載父類獲取outputstream的方法
 @Override public ServletOutputStream getOutputStream() throws IOException { return out; } //重載父類獲取writer的方法
 @Override public PrintWriter getWriter() throws UnsupportedEncodingException { return writer; } //重載父類獲取flushBuffer的方法
 @Override public void flushBuffer() throws IOException { if (out != null) { out.flush(); } if (writer != null) { writer.flush(); } } @Override public void reset() { buffer.reset(); } public String getContent() throws IOException { flushBuffer();//將out、writer中的數據強制輸出到WapperedResponse的buffer里面,否則取不到數據
        return new String(buffer.toByteArray()); } //內部類,對ServletOutputStream進行包裝
    private class WapperedOutputStream extends ServletOutputStream { private ByteArrayOutputStream bos = null; public WapperedOutputStream(ByteArrayOutputStream stream) throws IOException { bos = stream; } @Override public void write(int b) throws IOException { bos.write(b); } @Override public boolean isReady() { return false; } @Override public void setWriteListener(WriteListener listener) { } } }

 過濾器代碼:

/** * 過濾器攔截請求,實現加密解密功能 * * @Component 將此Filter交給Spring容器管理 * @WebFilter 通過WebFilter進行Filter聲明,這樣容器在進行部署的時候就會處理該Filter * * @author kiki */ @WebFilter(urlPatterns = "/HMService/*", filterName = "dataFilter") public class DataFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub
 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //解密請求 //使用包裝類 對request/response進行修改和響應
            WrapperedRequest wrapRequest = new WrapperedRequest((HttpServletRequest) request, requestBodyMw); WrapperedResponse wrapResponse = new WrapperedResponse((HttpServletResponse) response); chain.doFilter(wrapRequest, wrapResponse); String content = wrapResponse.getContent(); String responseBodyMw = DES3Util.encodeCBC(content); logger.info("【加密返回數據為】 responseBodyMw = {}", responseBodyMw); response.setContentLength(-1); PrintWriter out = response.getWriter(); System.out.println(responseString.length()); out.write(responseBodyMw); out.flush(); out.close(); } catch (Exception e) { e.printStackTrace(); } } @Override public void destroy() { // TODO Auto-generated method stub
 } }

 

修改之后,加密的結果和響應的結果一致。

 

說明:這是個大坑呀,剛開始沒有發現這個問題,返回的是加密的字符串就認為是對的,但是客戶端就是解析不了。我才知道,加密的結果和最終響應的結果不一樣,特此記錄。

 

 

 

 

 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM