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");
}
}

随机推荐

  1. 14 Positional Encoding (为什么 Self-Attention 需要位置编码)

    博客配套视频链接: https://space.bilibili.com/383551518?spm_id_from=333.1007.0.0 b 站直接看 配套 github 链接:https:// ...

  2. Kali Linux 各版本开启ssh 服务

    Kali Linux 各版本开启ssh 服务 2019版kali Linux SSH链接办法 修改kali关于SSH服务默认配置并重启SSH服务,步骤如下: 打开sshd_config文件 leafp ...

  3. 云原生周刊 | 使用 ChatGPT 协助解决 Prometheus 告警

    开源项目推荐 kubernetes-chatgpt-bot 这是一个适用于 Slack 的 ChatGPT 机器人,只要有监控告警发送到 Slack 频道中,你就可以通过机器人向 ChatGPT 咨询 ...

  4. 为你的Windows用户设置无边框半透明头像

    步骤一:锁定头像 Win+R输入gpedit.msc进入组策略编辑器,按图中所示,选择"计算机管理->管理模板->用户账户设定",将里面唯一选项"对所有账户使 ...

  5. vue 父子组件之间传值

    在vue中父子组件传值是必不可少的,大家必须要学会! 首先父组件向子组件传值: 父组件:比如我们传teacher为index,如果我们传值变量可以使用 : 绑定我们在data中定义的变量. 子组件:为 ...

  6. 指针进阶(数组指针 )(C语言)

    1. 数组名的理解 在指针入门中我们在使用指针访问数组的内容时,有这样的代码: int arr[10] = {1,2,3,4,5,6,7,8,9,10}; int *p = &arr[0]; ...

  7. pytest的conftest.py文件讲解

    一.conftest.py的特点 1.可以跨.py文件调用,有多个.py文件调用时,可让conftest.py只调用了一次fixture,或调用多次fixture 2.conftest.py与运行的用 ...

  8. CMU15445学习记录

    写在开头 我已经深刻意识到找工作的不易,因此想要开始恶补计算机基础知识,以此作为起点 由于考研的时候学过408综合,因此试图逃课CSAPP并直接开始CMU,发表此篇用作记录. 关于底层原理 原理 数据 ...

  9. OpenFeign简单使用

    OpenFeign入门 什么是 OpenFeign? OpenFeign是一个远程访问的组件,用于两个微服务之间互相访问的中间件 OpenFeign使用步骤 1.添加OpenFeign的依赖 < ...

  10. 网络与并行计算国际会议IFIP NPC 2024(CCF推荐会议)投稿延期至2024年8月25日

    原地址: https://mp.weixin.qq.com/s/zmg0SDbyDmoNBbJYzDjADA 主页: https://www.npc-conference.com/#/npc2024/ ...