SpringCloud(7)—— 国寿i动项目经验之(过滤器Filter技术(请求体二次解密处理技术))
过滤器Filter技术(请求体二次解密处理技术):
对前端App请求进行过滤,在过滤中可以对前端请求体(body)进行二次处理,比如:前端请求的body为加密串、那么就可以在过滤器中对body加密串进行二次解密处理,再进行请求具体接口,处理逻辑如下:

过滤器 MyFilter.java
package com.sinosoft.config; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.Map; /** * 使用注解标注过滤器 * * @author 单红宇(365384722) * @WebFilter将一个实现了javax.servlet.Filter接口的类定义为过滤器 属性filterName声明过滤器的名称, 可选 * 属性urlPatterns指定要过滤 的URL模式,也可使用属性value来声明.(指定要过滤的URL模式是必选属性) * @myblog http://blog.csdn.net/catoop/ * @create 2016年1月6日 */ @WebFilter(filterName = "myFilter", urlPatterns = "/*") public class MyFilter implements Filter { private static final Logger LOGGER = LoggerFactory.getLogger(LogRecordAspect.class); @Override public void init(FilterConfig config) throws ServletException { System.out.println("过滤器初始化"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpServletRequest = (HttpServletRequest) request; // 防止流读取一次后就没有了, 所以需要将流继续写出去 ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(httpServletRequest); String body = HttpHelper.getBodyString(requestWrapper); //如果请求Body为空异常处理 if (StringUtils.isBlank(body)) { // LOGGER.error("非法请求, 没有APP_KEY, APP_SECRET"); chain.doFilter(request, response); return; } //开始处理请求体 try { LOGGER.info("request:" + body); Map<String, Object> parameters = new ObjectMapper().readValue(body.replaceAll(""", "\""), new TypeReference<Map<String, Object>>() { }); Object imReqeustEntityo = parameters.get("imReqeustEntity"); if (imReqeustEntityo == null || "".equals(imReqeustEntityo)) { LOGGER.error("非法请求, 没有设备信息"); } else { Map<String, String> imReqeustEntity = (Map<String, String>) imReqeustEntityo; if (imReqeustEntity == null || "".equals(imReqeustEntity)) { LOGGER.error("非法请求, 没有设备信息"); } LOGGER.info("设备信息为: " + imReqeustEntity.toString()); } chain.doFilter(requestWrapper, response); } catch (Exception e) { chain.doFilter(request, response); } } @Override public void destroy() { System.out.println("过滤器销毁"); } }
BodyReaderHttpServletRequestWrapper.java
package com.sinosoft.config; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.ReadListener; import javax.servlet.ServletInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.Charset; /** * 使用HttpServletRequestWrapper来包装HttpServletRequest * 在BodyReaderHttpServletRequestWrapper中初始化读取request的InputStream数据,以byte[]形式缓存在其中,然后在Filter中将request转换为包装过的request */ public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper { /** * 日志打印 */ private static final Logger LOGGER = LoggerFactory.getLogger(BodyReaderHttpServletRequestWrapper.class); /** * 原加密请求体 */ private final byte[] body; /** * 后解密请求体 */ private final byte[] resetBody; /** * 处理request中的请求 * * @param request * @throws IOException */ public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException { super(request); String rBody = HttpHelper.getBodyString(request); body = rBody.getBytes(Charset.forName("UTF-8")); //判断请求体是否为空 // if (!CommonUtil.isEmpty(rBody)) { // LOGGER.info("开始进行AES解密处理..."); // String aesBody = new String(body, "utf-8"); // LOGGER.info("请求加密报文:" + aesBody); // AES2 aes = new AES2(); // aesBody = aes.decrypt(aesBody); // resetBody = aesBody.getBytes(); // } else { // resetBody = body; // } resetBody = body; } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream())); } /** * 重置request中的inputStream * * @return i * @throws IOException ioe */ @Override public ServletInputStream getInputStream() throws IOException { final ByteArrayInputStream bais = new ByteArrayInputStream(resetBody); 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) { } }; } }
HttpHelper.java
package com.sinosoft.config; import javax.servlet.ServletRequest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.Charset; /** * Created with antnest-platform * User: chenyuan * Date: 12/24/14 * Time: 10:39 AM */ public class HttpHelper { /** * 获取请求Body * * @param request * @return */ public static String getBodyString(ServletRequest request) { StringBuilder sb = new StringBuilder(); InputStream inputStream = null; BufferedReader reader = null; try { inputStream = 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(); } }

浙公网安备 33010602011771号