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");
}
}
随机推荐
- 0503-autograd实战之线性回归
0503-autograd实战之线性回归 目录 一.用 variable 实现线性回归(autograd 实战) 二.第五章总结 pytorch完整教程目录:https://www.cnblogs.c ...
- 在 Exchange Server 中配置特定于客户端的消息大小限制
在 Exchange Server 中配置特定于客户端的消息大小限制 微软官方详细文档如下: https://learn.microsoft.com/zh-cn/exchange/architectu ...
- 修复一个kubernetes集群
前几天有个朋友把他们的kubernetes集群搞挂了,让我帮忙恢复一下,由于很多现场都没有了,这里提供一下解决思路. 环境问题 该环境有一个master节点,即控制面pod(etcd.schedule ...
- error loading sources list: ('The read operation timed out',)解决办法!!
一.灵魂四问 1.为什么叫rosdepc? rosdepc,c指的是China中国,主要用于和rosdep区分. 2.rosdepc和rosdep功能一致吗? rosdep官方最新版源码直接修改的,小 ...
- JS转义html编码
两个方法: 1.利用用浏览器内部转换器实现html转义: 2.用正则表达式实现html转义: var HtmlUtil = { /*1.用浏览器内部转换器实现html编码(转义)*/ htmlEnco ...
- 部署个SSH蜜罐玩玩,又能增强安全性,又能当电子蛐蛐
前言 最近有个旧服务器的 SSL 证书过期了,每次都申请 SSL 证书太麻烦了,我直接把 swag 方案部署上去. 然后发现这个服务器在安全方面有所疏忽,所以又加固了一下,SSH 部分我想起来之前用过 ...
- cmu15545笔记-Join算法(Join Algorithms)
目录 Overview Nested Loop Join Naïve Block Index Sort-Merge Join Hash Join Simple Hash Join Partition ...
- 接口测试中如何保持session鉴权/会话
当接口使用token鉴权时,可以直接在响应数据中提取token的值,关联到其他接口使用 如果接口使用的是session鉴权,可以使用session=resquests.Session()方法,创建一个 ...
- 厉害了,8.7w人打满分!如果我找 BUG 能像他一样厉害就好了!
你好呀,我是歪歪. 最近在 B 站上看到一个让我觉得"非常哇塞"视频的: https://www.bilibili.com/video/BV1y4421U72G/ 视频的播放量有接 ...
- apisix 转发 路由自动encode导致带中括号的文件下载404
问题:apisix 转发 路由自动encode导致带中括号的文件下载404 原因:因为apisix 解码后tomcat处理会有问题,下载不了 解决方案:请求改写---协议,选择保持原样