springboot过滤器中将form表单和body(json)形式的进参拦截修改里面参数内容(重写HttpServletRequestWrapper里边的方法)
一、实现思路
1.进参分为form表单和body形式的json,两种形式分开处理
2.通过包装request,实际调用的是包装之后的request对象
二、代码实现
项目目录:
1.主类DemoApplication
package com.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
@ServletComponentScan
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
2.过滤器EncryptionFilter
package com.demo.filter.request;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.MediaType;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
@WebFilter
public class EncryptionFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
String contentType = request.getContentType();
//body形式(json)
if (contentType.equals(MediaType.APPLICATION_JSON_UTF8_VALUE)
|| contentType.equals(MediaType.APPLICATION_JSON_VALUE)) {
//获取request的body参数
String postContent = getBody(request);
//如果body中存在数据放入HttpServletRequest
if (StringUtils.isNotEmpty(postContent)) {
//参数中放入新的参数
JSONObject jsStr = JSONObject.parseObject(postContent);
jsStr.put("aa", "bb");
postContent = jsStr.toJSONString();
//将参数放入重写的方法中
request = new BodyRequestWrapper(request, postContent);
}
//form表单形式
} else if ((contentType.equals(MediaType.APPLICATION_FORM_URLENCODED_VALUE) || contentType.contains(MediaType.MULTIPART_FORM_DATA_VALUE))
&& !request.getParameterMap().isEmpty()) {
// String body = "{\"name\":\"zhangsan\",\"age\":1,\"gender\":2}";
//重新添加几个数据
Map<String, String[]> parameterMap = new HashMap<>();
parameterMap.put("name", new String[]{"zhangsan"});
parameterMap.put("age", new String[]{"1"});
parameterMap.put("gender", new String[]{"2"});
//将参数放入重写的方法中
request = new ParameterRequestWrapper(request, parameterMap);
}
chain.doFilter(request, response);
}
//获取Request的body数据
private String getBody(ServletRequest request) {
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
InputStream inputStream = null;
try {
inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return stringBuilder.toString();
}
@Override
public void destroy() {
}
}
3.body形式的包装类
package com.demo.filter.request;
import javax.servlet.ReadListener;
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;
//更改body中的值
public class BodyRequestWrapper extends HttpServletRequestWrapper {
// 存放JSON数据主体
private String body;
public BodyRequestWrapper(HttpServletRequest request, String context) {
super(request);
body = context;
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes("UTF-8"));
ServletInputStream servletInputStream = new ServletInputStream() {
@Override
public int read() throws IOException {
return byteArrayInputStream.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener listener) {
}
};
return servletInputStream;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
}
4.form表单形式的包装类
package com.demo.filter.request;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
//form表单形式的赋值
public class ParameterRequestWrapper extends HttpServletRequestWrapper {
private Map<String, String[]> params = new HashMap<String, String[]>();
public ParameterRequestWrapper(HttpServletRequest request) throws IOException {
super(request);
this.params.putAll(request.getParameterMap());
}
/**
* 重载一个构造方法
*
* @param request
* @param extendParams
*/
public ParameterRequestWrapper(HttpServletRequest request, Map<String, String[]> extendParams) throws IOException {
this(request);
addAllParameters(extendParams);
}
@Override
public Enumeration<String> getParameterNames() {
return Collections.enumeration(params.keySet());
}
@Override
public String getParameter(String name) {
String[] values = params.get(name);
if (values == null || values.length == 0) {
return null;
}
return values[0];
}
@Override
public String[] getParameterValues(String name) {
return params.get(name);
}
public void addAllParameters(Map<String, String[]> otherParams) {
for (Map.Entry<String, String[]> entry : otherParams.entrySet()) {
addParameter(entry.getKey(), entry.getValue());
}
}
public void addParameter(String name, Object value) {
if (value != null) {
if (value instanceof String[]) {
params.put(name, (String[]) value);
} else if (value instanceof String) {
params.put(name, new String[]{(String) value});
} else {
params.put(name, new String[]{String.valueOf(value)});
}
}
}
@Override
public Map<String, String[]> getParameterMap() {
return this.params;
}
}
5.TestController
package com.demo.controller;
import com.demo.controller.request.TestRequest;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
@RestController
public class TestController {
//body形式加上@Valid @RequestBody 注解 ,form表单形式去掉
@RequestMapping(value = "/test", method = RequestMethod.POST)
public Object test(@Valid @RequestBody TestRequest request) {
System.out.println("TestController" + request);
return request;
}
}
6.TestRequest实体
package com.demo.controller.request;
import lombok.Data;
@Data
public class TestRequest {
private String name;
private Integer age;
private Integer gender;
private String aa;
}
7.接口
localhost:8080/test
8.请求结果
body形式请求 程序里边把’aa’='bb’加到参数中
form表单形式请求 程序里边将"{“name”:“zhangsan”,“age”:1,“gender”:2}" 加到参数