最近有一个需求,对现有的功能中的手机号返回前端的时候是解密显示的,进入到数据库中是加密存储的。因为有手机号的地方比较多,所以准备通过过滤器来进行返回值中手机号的加解密。
1.自定义一个HttpServletResponseWrapper
public class ResponseWrapper extends HttpServletResponseWrapper {
private ByteArrayOutputStream buffer = null;
private ServletOutputStream out = null;
private PrintWriter writer = null;
public ResponseWrapper(HttpServletResponse resp) throws IOException {
super(resp);
buffer = new ByteArrayOutputStream();// 真正存储数据的流
out = new WapperedOutputStream(buffer);
writer = new PrintWriter(new OutputStreamWriter(buffer));
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
return out;
}
@Override
public PrintWriter getWriter() throws UnsupportedEncodingException {
return writer;
}
@Override
public void flushBuffer() throws IOException {
if (out != null) {
out.flush();
}
if (writer != null) {
writer.flush();
}
}
@Override
public void reset() {
buffer.reset();
}
public byte[] getResponseData() throws IOException {
flushBuffer();
return buffer.toByteArray();
}
public String getContent() throws IOException {
flushBuffer();
return buffer.toString();
}
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 void write(byte[] b) throws IOException {
bos.write(b, 0, b.length);
}
@Override
public void write(byte[] b, int off, int len) throws IOException {
bos.write(b, off, len);
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setWriteListener(WriteListener writeListener) {
}
}
}
2.编写一个过滤器
//实现Filter接口
public class ResponseFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)servletRequest;
//获取请求地址
String askUrl = request.getRequestURI();
//处理是ajax请求
if (isAjaxRequest(request)) {
//这个ResponseWrapper是自定义的
ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) servletResponse);
//把ResponseWrapper传递到执行点,执行下去,并获取回响应结果
filterChain.doFilter(servletRequest, responseWrapper);
//获取响应结果的byte
byte[] content = responseWrapper.getResponseData();
//转为str
String str= new String(content);
//对请求结果,解密
//。。。
//这个response需要是同一个请求的
HttpServletResponse response=(HttpServletResponse)servletResponse;
writeResponse(response,200,str);
}
}else{
//不是ajax请求得话,就直接走过过滤器就可以
filterChain.doFilter(servletRequest, servletResponse);
}
}
public static boolean isAjaxRequest(HttpServletRequest request) {
String requestedWith = request.getHeader("x-requested-with");
if (requestedWith != null && requestedWith.equalsIgnoreCase("XMLHttpRequest")) {
return true;
} else {
return false;
}
}
//写回到response
public static void writeResponse(HttpServletResponse response, int status, String json) {
try {
//之前有被拦截器处理过的response,走到这里后会界面显示500
//这个是必须的
response.reset();//很重要
response.setContentType("application/json;charset=UTF-8");
response.setStatus(status);
response.getWriter().write(json);
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.在web.xml中注册过滤器
如果过滤器没有生效,可以检查一下,过滤器的注册是否在struts2的注册之前。如果不是,把过滤器的注册前置
<filter>
<filter-name>ResponseFilter</filter-name>
<filter-class>过滤器的java文件地址</filter-class>
</filter>
<filter-mapping>
<filter-name>ResponseFilter</filter-name>
<url-pattern>*</url-pattern>
</filter-mapping>