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

经过以上步骤即可修改请求域中的方法参数值。

上一篇 下一篇

猜你喜欢

热点阅读