Springboot 使用过滤器进行加密解密(二)

以前写过一篇关于过滤器实现加密解密功能的文章,可是在实际开发业务中发现,仍是有一些问题的,在此特意说明。

第一:过滤器走两遍的问题:

1.过滤器上,添加了两个注解java

第一个:@Compent   将此Filter交给Spring容器管理app

第二个:@WebFilter经过WebFilter进行Filter声明,这样容器在进行部署的时候就会处理该Filteride

2.启动类上添加的注解this

@ServletComponentScan  做用:Servlet、Filter、Listener 能够直接经过 @WebServlet、@WebFilter、@WebListener 注解自动注册(自动扫描带有过滤器注解的包)加密

3.问题:项目启动后,一个请求执行两次url

缘由:@Compent 启动时,会加载Filter.  @ServletComponentScan 也会扫描过滤器。因此会加载两次spa

4.解决措施:code

去掉过滤器上的@Compent 注解以后,请求过滤一次。blog

第二:响应结果跟加密结果不一致的问题

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

 

修改以后,加密的结果和响应的结果一致。

 

说明:这是个大坑呀,刚开始没有发现这个问题,返回的是加密的字符串就认为是对的,可是客户端就是解析不了。我才知道,加密的结果和最终响应的结果不同,特此记录。

相关文章
相关标签/搜索