场景:有时候需要在拦截器层对请求参数进行处理,get请求容易,不谈,现在说下post请求
注意:如果是用json的方式传递,获取数据时是获取的body流,request的body流只能读取一次
步骤:
1.自定义request类
@Slf4j
public class BodyHttpServletRequestWrapper extends HttpServletRequestWrapper {
//存储请求参数--application/x-www-form-urlencoded、form-data方式
private final List<DataElement> dataList = new ArrayList<>();
public BodyHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
/*
当需要处理json格式时,在这里通过流获取dataInfo,如果是表单提交,这里通过
request.getParameterMap()获取参数并缓存下来,自己举一反三!!
*/
//req2RawString(request);
String dataInfo = request.getParameter("data");
if (StringUtils.isEmpty(dataInfo)){
return;
}
JSONObject jsonObject = JSONObject.parseObject(dataInfo);
Set<String> keySet = jsonObject.keySet();
for (String key : keySet) {
DataElement param = new DataElement();
param.setKey(key);
param.setDataInfo(jsonObject.getString(key));
dataList.add(param);
}
}
@Override
public Enumeration<String> getParameterNames() {
Set<String> keySet = new HashSet<>();
dataList.forEach(dataElement -> {
keySet.add(dataElement.getKey());
});
return Collections.enumeration(keySet);
}
@Override
@Nullable
public String[] getParameterValues(String key) {
String[] parameterValues = new String[1];
AtomicBoolean haveData = new AtomicBoolean(false);
dataList.forEach(dataElement -> {
if (dataElement.getKey().equals(key)) {
parameterValues[0] = dataElement.getDataInfo();
haveData.set(true);
}
});
if (haveData.get()) {
return parameterValues;
} else {
return null;
}
}
/* public static String req2RawString(HttpServletRequest request) {
StringBuilder sb = new StringBuilder();
BufferedReader reader = null;
try {
reader = request.getReader();
String line;
while ((line = reader.readLine()) != null) {
sb.append(line).append('\n');
}
if (sb.length() > 1) {
sb.replace(sb.length() - 1, sb.length(), "");
}
} catch (IOException e) {
log.info("RequestUtil,IOException:" + e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
log.info("RequestUtil,IOException:" + e);
}
}
}
String str = sb.toString();
log.info("Request Result:" + str);
return str;
}*/
/**
用来存储参数的对象---你可以自定义
**/
@Data
private class DataElement implements Serializable {
private String key;
private String dataInfo;
}
}
在控制层进行参数映射时,会调用我们重写的getParameterNames获取所有的key,再通过key调用getParameterValues方法获取对应的值;
2.定义拦截器类,在满足条件的情况下,使用我们自定义的request对象
@Component
@Slf4j
public class HttpServletRequestReplacedFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//满足条件就使用自定义request对象,否则使用方法参数里的
String methodType = request.getMethod().toUpperCase();
if ((("POST".equals(methodType)) || ("DELETE".equals(methodType)) || ("PUT".equals(methodType))) && isBaoWuTransmit(request)) {
ServletRequest requestWrapper = new BodyHttpServletRequestWrapper(request);
filterChain.doFilter(requestWrapper, response);
} else{
filterChain.doFilter(request, response);
}
}
private boolean isBaoWuTransmit(HttpServletRequest request) {
boolean baoWu = false;
Enumeration e = request.getHeaderNames();
while (e.hasMoreElements()) {
String headerName = (String) e.nextElement();
if ("appcode".equals(headerName)){
baoWu = true;
}
}
return baoWu;
}
完毕!!!