RepeatReadRequestWrapper
package cn.service.web.common.filter; import com.alibaba.fastjson.JSON; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; import org.springframework.mock.web.DelegatingServletInputStream; 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.util.*; /** * 可以重复读Request */ public class RepeatReadRequestWrapper extends HttpServletRequestWrapper { private static final Logger logger = LoggerFactory.getLogger(RepeatReadRequestWrapper.class); private final byte[] bytes; private final Hashtable<String, String[]> parameterMap = new Hashtable<>(); private final ServletInputStream inputStream; private final BufferedReader reader; private final Object lock = new Object(); private boolean isRead = false; /** * * @param request * @throws IOException */ public RepeatReadRequestWrapper(HttpServletRequest request) throws IOException { super(request); bytes = IOUtils.toByteArray(request.getInputStream()); ByteArrayInputStream bais = new ByteArrayInputStream(bytes); inputStream = new DelegatingServletInputStream(bais); reader = new BufferedReader(new InputStreamReader(bais)); } @Override public ServletInputStream getInputStream() { return inputStream; } @Override public BufferedReader getReader() { return reader; } @Override public String getParameter(String name) { String[] values = getParameterMap().get(name); return values == null || values.length == 0 ? null : values[0]; } @Override public Map<String, String[]> getParameterMap() { if(!initParameterMap().isEmpty()){ return parameterMap; } return super.getParameterMap(); } @Override public Enumeration<String> getParameterNames() { if(!initParameterMap().isEmpty()){ parameterMap.keys(); } return super.getParameterNames(); } @Override public String[] getParameterValues(String name) { return getParameterMap().get(name); } public Hashtable<String, String[]> initParameterMap(){ if(!isRead){ synchronized (lock){ if(isRead){ logger.info("parameterMap has inited, when you step into synchronized block"); return parameterMap; } try { /* String text = new String(bytes, getCharacterEncoding()); logger.info("initParameterMap text {}", text); String body = URLDecoder.decode(text, DEFAULT_CHARSET); */ //String body = new String(Base64.getUrlDecoder().decode(bytes), DEFAULT_CHARSET); String body = new String(bytes, getCharacterEncoding()); if(StringUtils.isNotBlank(body)){ if(getContentType().contains(MediaType.APPLICATION_JSON_VALUE)){ Map<String,Object> map = JSON.parseObject(body,Map.class); if(map != null && !map.isEmpty()){ map.entrySet().stream().forEach(entry -> { if(entry.getValue() instanceof JSON){ parameterMap.put(entry.getKey(), new String[]{JSON.toJSONString(entry.getValue())}); } else{ parameterMap.put(entry.getKey(), new String[]{String.valueOf(entry.getValue())}); } }); } } else { HashMap<String, List<String>> param = new HashMap<>(); String[] pairs = body.split("&"); for (String nv : pairs) { String name = nv.split("=")[0]; String val = nv.split("=")[1]; if (param.containsKey(name)) { List<String> value = param.get(name); value.add(val); param.put(name, value); } else { List<String> value = new ArrayList<>(); value.add(val); param.put(name, value); } } Iterator<Map.Entry<String, List<String>>> iterator = param.entrySet().iterator(); while (iterator.hasNext()){ Map.Entry<String, List<String>> next = iterator.next(); parameterMap.put(next.getKey(), next.getValue().toArray(new String[]{})); } } } String queryString = getQueryString(); if(StringUtils.isNotBlank(queryString)){ String[] pair = queryString.split("&"); for (int i = 0; i < pair.length; i++) { String[] kv = pair[i].split("="); if(kv.length>1){ parameterMap.put(kv[0], kv[1].split(",")); } } } } catch (Exception e) { logger.error("initParameterMap error", e); } finally { isRead = true; } } } return parameterMap; } }
package cn.service.web.common.filter; import com.google.common.collect.Lists; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.MediaType; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.List; /** * service优雅停机:统计正在处理的http请求 * <p>Created by xxxx on 17/8/02. */ public class HttpRequestCounterFilter implements Filter { private static Logger logger = LoggerFactory.getLogger(HttpRequestCounterFilter.class); private static final List<MediaType> ignoreRepeatReadList = Lists.newArrayList( MediaType.APPLICATION_FORM_URLENCODED, MediaType.MULTIPART_FORM_DATA); @Override public void init(FilterConfig filterConfig) throws ServletException { logger.debug("cn.fraudmetrix.octopus.service.web.common.filter.HttpRequestCounterFilter.init"); } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { ServletRequest httpRequest = request; HttpServletRequest req = null; if (request instanceof HttpServletRequest){ req = (HttpServletRequest) request; LocalRunningHttpRequestCounter.in(req); if(isRepeatReadRequest(req) && !RequestContextInterceptor.ignoreLoggerURIList.contains(req.getRequestURI())){ httpRequest = new RepeatReadRequestWrapper(req); } /* Map<String, String[]> parameterMap = request.getParameterMap(); StringBuilder sb = new StringBuilder(); for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) { sb.append(entry.getKey()+":"+ StringUtils.join(entry.getValue(),",")).append("\n"); } String taskId = request.getParameter(ApiParamConstants.TASK_ID); String partnerCode = httpRequest.getHeader(HeaderConstants.PARAMS_PARTNER_CODE); String requestURI = httpRequest.getRequestURI(); logger.info("{} HttpServletRequest filter {}\n{}\n{}",taskId, partnerCode, requestURI, sb); */ } try { chain.doFilter(httpRequest, response); } finally { if (req != null) LocalRunningHttpRequestCounter.out(req); } } /** * 是否是支持可重复读的request * @param request * @return */ private boolean isRepeatReadRequest(HttpServletRequest request) { return ignoreRepeatReadList.stream().filter(mediaType -> mediaType.includes(MediaType.parseMediaType(request.getContentType()))).count() == 0; } @Override public void destroy() { logger.debug("destroy"); } }