SpringBoot拿到所有Http请求的入参和出参
在web应用中,有各式各样的访问者,这些访问者请求的方式也可能完全出乎所料,对请求的监控是稳定性的一个基本动作,那基于Java构建的Web应用也需要做一些默认的处理。
对所有的Http请求进行监控,有两种方式:
- 基于AOP:但是需要所有的入口有确定的格式**(有规范)**,开发者可能感受差一些
- 基于拦截器:拦截器本身就是Web请求体系的一部分,拦截和业务功能可以解耦,业务专注与业务,做监控专注与监控。
如果说基于拦截器的话,可以怎么处理:
1、首先要配置拦截器
2、拦截器中要能捕获入参
3、打印日志,进行统计
给个例子
Demo
1、配置SpringBoot的框架,可以去start.spring.io/ 下载一个脚手架功能
2、添加一些基本的依赖,也是常用的库,项目中经常用到
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.2-jre</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
3、编写拦截器,及其处理
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import me.aihe.init.util.HttpUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
/**
*/
@Component
@Slf4j
public class HttpInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
try {
String requestURI = request.getRequestURI();
Map<String,Object> paramMap = HttpUtils.getParameterMap(request);
log.info("HttpInterceptor {} {} {}",request.getMethod(),requestURI,JSON.toJSONString(paramMap));
return true;
} catch (Exception e){
log.error("HttpInterceptor preHandle error",e);
}
return true;
}
}
4、获取Http请求入参和出参的工具类
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.http.HttpServletRequest;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@Slf4j
public class HttpUtils {
/**
* 获取请求参数,把请求参数转成Mapd
*
* @param request request对象
* @return 参数集合map
*/
public static Map<String, Object> getParameterMap(HttpServletRequest request) {
try {
Map<String, String[]> parameterMap = request.getParameterMap();
Map<String, Object> returnMap = Maps.newHashMap();
// 默认参数
for (Entry<String, String[]> entry : parameterMap.entrySet()) {
String value = "";
String key = entry.getKey();
Object valueObj = entry.getValue();
if (valueObj == null) {
value = "";
} else if (!(valueObj instanceof String[])) {
value = valueObj.toString();
} else {
String[] values = (String[])valueObj;
for (String temp : values) {
value = temp + ",";
}
value = value.substring(0, value.length() - 1);
}
returnMap.put(key, value);
//post等raw内容 content-type:application/json
}
// PostBody参数
try {
ByteArrayOutputStream bos = getBOS(request.getInputStream());
String ok = bos.toString();
if (StringUtils.isNotEmpty(ok)){
returnMap.putAll(JSON.parseObject(ok));
}
} catch (Exception e) {
log.error("getParameterMap stream error", e);
}
return returnMap;
} catch (Exception e) {
log.error("getParameterMap error", e);
}
return new HashMap<>();
}
private static ByteArrayOutputStream getBOS(InputStream in) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
BufferedInputStream br = new BufferedInputStream(in);
for(int c=0;(c=br.read())!=-1;){
bos.write(c);
}
br.close();
} catch (Exception e) {
log.error("getBOS error",e);
}
return bos;
}
}
5、配置拦截器,使其生效
import me.aihe.init.interceptor.HttpInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
HttpInterceptor httpInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//登录拦截器
//registry
// .addInterceptor(new LoginInterceptor())
// .addPathPatterns("/**").excludePathPatterns(LoginInterceptor.EXCLUDE_PATH_PATTERNS);
registry.addInterceptor(httpInterceptor)
.addPathPatterns("/**");
}
}
效果
关于扩展
这里写的比较粗糙,只是把流程演示了一遍;还可以做的:
- 日志格式的规范化,对日志进行采集监控
- 还可以对入参进行校验,鉴权等
其实就是拦截器可以做的事情,这里都可以实现一些相关功能的拦截器进行处理,只是这个拦截器仅仅打印请求的入参和出参而已。
转载自:https://juejin.cn/post/7101114659712794638