SpringMvc修改Request请求参数并映射到Contro
2020-12-22 本文已影响0人
小宝_6d94
修改Request请求参数需考虑2种情况,文件传输除外:
第一种、请求方法为值类型参数的形式,如int,float等,如:
public void m(int x,int y);
第二种、请求方法为引用类型,这里指能序例化为json的对象,如:
public void m(Object obj);
处理步骤如下
1、创建Request请求包装类,包装类分为两部分
一、针对方法参数为值类型的处理
package com.XXX.mall.search.filter;
import org.apache.commons.io.IOUtils;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.Map;
import java.util.Vector;
public class ChangeRequestWrapper extends HttpServletRequestWrapper{
private Map<String, String[]> parameterMap; // 所有参数的Map集合
public ChangeRequestWrapper(HttpServletRequest request) {
super(request);
parameterMap = request.getParameterMap();
}
// 重写几个HttpServletRequestWrapper中的方法
/**
* 获取所有参数名
*
* @return 返回所有参数名
*/
@Override
public Enumeration<String> getParameterNames() {
Vector<String> vector = new Vector<String>(parameterMap.keySet());
return vector.elements();
}
/**
* 获取指定参数名的值,如果有重复的参数名,则返回第一个的值 接收一般变量 ,如text类型
*
* @param name 指定参数名
* @return 指定参数名的值
*/
@Override
public String getParameter(String name) {
if(parameterMap.containsKey(name)){
String[] results = parameterMap.get(name);
return results[0];
}
return null;
}
/**
* 获取指定参数名的所有值的数组,如:checkbox的所有数据
* 接收数组变量 ,如checkobx类型
*/
@Override
public String[] getParameterValues(String name) {
return parameterMap.get(name);
}
@Override
public Map<String, String[]> getParameterMap() {
return parameterMap;
}
public void setParameterMap(Map<String, String[]> parameterMap) {
this.parameterMap = parameterMap;
}
}
二、方法参数为引用类型的处理
package com.XXX.mall.search.filter;
import org.apache.commons.io.IOUtils;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.Map;
import java.util.Vector;
public class ChangeRequestWrapper extends HttpServletRequestWrapper{
private byte[] body=null;
public ChangeRequestWrapper(HttpServletRequest request) {
try {
loadBody(request);
} catch (IOException e) {
e.printStackTrace();
}
}
private BufferedReader reader;
private ServletInputStream inputStream;
private void loadBody(HttpServletRequest request) throws IOException{
body = IOUtils.toByteArray(request.getInputStream());
inputStream = new RequestCachingInputStream(body);
}
public byte[] getBody() {
return body;
}
public void setBody(byte[] body){
this.body=body;
inputStream = new RequestCachingInputStream(body);
}
@Override
public ServletInputStream getInputStream() throws IOException {
if (inputStream != null) {
ServletInputStream tmp = this.inputStream;
this.inputStream = new RequestCachingInputStream(body);
return tmp;
}
return super.getInputStream();
}
@Override
public BufferedReader getReader() throws IOException {
if (reader == null) {
reader = new BufferedReader(new InputStreamReader(inputStream, getCharacterEncoding()));
}
return reader;
}
public String getBodyContent() throws IOException {
StringBuilder sb = new StringBuilder();
try (InputStream inputStream = getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")))) {
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
private static class RequestCachingInputStream extends ServletInputStream {
private final ByteArrayInputStream inputStream;
public RequestCachingInputStream(byte[] bytes) {
inputStream = new ByteArrayInputStream(bytes);
}
@Override
public int read() throws IOException {
return inputStream.read();
}
@Override
public boolean isFinished() {
return inputStream.available() == 0;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readlistener) {
}
}
}
当前可以将两种情况的处理合并,合并后代码如下:
package com.XXX.mall.search.filter;
import org.apache.commons.io.IOUtils;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.Map;
import java.util.Vector;
public class ChangeRequestWrapper extends HttpServletRequestWrapper{
private byte[] body=null;
private Map<String, String[]> parameterMap; // 所有参数的Map集合
public ChangeRequestWrapper(HttpServletRequest request) {
super(request);
parameterMap = request.getParameterMap();
try {
loadBody(request);
} catch (IOException e) {
e.printStackTrace();
}
}
// 重写几个HttpServletRequestWrapper中的方法
/**
* 获取所有参数名
*
* @return 返回所有参数名
*/
@Override
public Enumeration<String> getParameterNames() {
Vector<String> vector = new Vector<String>(parameterMap.keySet());
return vector.elements();
}
/**
* 获取指定参数名的值,如果有重复的参数名,则返回第一个的值 接收一般变量 ,如text类型
*
* @param name 指定参数名
* @return 指定参数名的值
*/
@Override
public String getParameter(String name) {
if(parameterMap.containsKey(name)){
String[] results = parameterMap.get(name);
return results[0];
}
return null;
}
/**
* 获取指定参数名的所有值的数组,如:checkbox的所有数据
* 接收数组变量 ,如checkobx类型
*/
@Override
public String[] getParameterValues(String name) {
return parameterMap.get(name);
}
@Override
public Map<String, String[]> getParameterMap() {
return parameterMap;
}
public void setParameterMap(Map<String, String[]> parameterMap) {
this.parameterMap = parameterMap;
}
/*******in**************/
private BufferedReader reader;
private ServletInputStream inputStream;
private void loadBody(HttpServletRequest request) throws IOException{
body = IOUtils.toByteArray(request.getInputStream());
inputStream = new RequestCachingInputStream(body);
}
public byte[] getBody() {
return body;
}
public void setBody(byte[] body){
this.body=body;
inputStream = new RequestCachingInputStream(body);
}
@Override
public ServletInputStream getInputStream() throws IOException {
if (inputStream != null) {
ServletInputStream tmp = this.inputStream;
this.inputStream = new RequestCachingInputStream(body);
return tmp;
}
return super.getInputStream();
}
@Override
public BufferedReader getReader() throws IOException {
if (reader == null) {
reader = new BufferedReader(new InputStreamReader(inputStream, getCharacterEncoding()));
}
return reader;
}
public String getBodyContent() throws IOException {
StringBuilder sb = new StringBuilder();
try (InputStream inputStream = getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")))) {
String line;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
private static class RequestCachingInputStream extends ServletInputStream {
private final ByteArrayInputStream inputStream;
public RequestCachingInputStream(byte[] bytes) {
inputStream = new ByteArrayInputStream(bytes);
}
@Override
public int read() throws IOException {
return inputStream.read();
}
@Override
public boolean isFinished() {
return inputStream.available() == 0;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readlistener) {
}
}
}
2、创建过滤器,在过滤器中修改参数值
package com.XXX.mall.search.filter;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.XXX.mall.common.util.AesUtil;
import io.micrometer.core.instrument.util.StringUtils;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class DecryptFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
ChangeRequestWrapper changeRequestWrapper = new ChangeRequestWrapper((HttpServletRequest) servletRequest);
Map<String, String[]> parameterMap = new HashMap<>(changeRequestWrapper.getParameterMap());
//1、值类型参数修改
parameterMap.put("x",1);
parameterMap.put("y",2);
changeRequestWrapper.setParameterMap(parameterMap);
//2、引用类型修改
String jsonData="{\"x\":1,\"y\":2}";
byte[] reqBodyBytes = jsonData.getBytes();
changeRequestWrapper.setBody(reqBodyBytes);
//使用复写后的wrapper
filterChain.doFilter(changeRequestWrapper, servletResponse);
}
@Override
public void destroy() {
}
}
3、配置过滤器,这里使用Springboot配置
package com.XXX.mall.search.config;
import com.XXX.mall.search.filter.DecryptFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new DecryptFilter());
bean.addUrlPatterns("/*");
return bean;
}
}
经过以上步骤即可修改请求域中的方法参数值。