继承HttpServletRequestWrapper实现修改request请求参数

哈喽,大家好,我是花臂,好久不见。今天教大家如何实现修改到达controller层的参数。为啥要修改请求参数呢?在实际开发中我们的接口参数都是要加密的,也就是接口加密。但是HttpServletRequest没有直接修改请求参数的方法, 所以我们这里需要用到一个类HttpServletRequestWrapper。首先通过一张图了解一下这背后的原理。

可以看到ServlerRequest是一个顶级接口,HttpServlerRequestServletReqeustWrapper分别实现了继承它,然后HttpServletRequestWrapper分别实现和继承了上面两个类,这就是一个典型的装饰模式,如果不了解装饰模式可以先去了解一下。
ServlerRequest就是一个抽象组件的角色
HttpServlerRequest就是一个被装饰者的角色
ServletReqeustWrapper就是装饰类的角色
HttpServletRequestWrapper是一个具体的装饰者的角色

首先,controller层是通过getParameter方法取参数的,而ServletReqeustWrapper装饰者中也是重写了这个方法,所以我们需要自定义一个类去继承HttpServletRequestWrapper这个类然后将参数经过修改之后返回出去。

!maven依赖

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.7.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

!具体装饰者角色

public class Fileter extends HttpServletRequestWrapper {
    public Fileter(HttpServletRequest request) {
        super(request); //执行父类的构造方法,给父类ServletRequestWrapper中的request赋值
        this.params = request.getParameterMap();//将请求参数全部封装到map集合里面
    }

    private Map<String, String[]> params;

    @Override
    public String[] getParameterValues(String name) { //这个方法是根据参数名称获取到所有的参数值,并且将值做修改后返回给request
        String[] strings = params.get(name);
        //这个可以做参数解密操作
        System.out.println("--------------------------修改参数---------------------------" + strings[0]);
        strings[0] = strings[0] + "修改之后的";
        return strings;
    }
}

!Filter过滤器

@Component
public class ModifyParametersFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        Fileter fileter = new Fileter((HttpServletRequest) request); //将HttpServletRequest传给具体装饰者角色
        chain.doFilter(fileter,response);

    }
}

程序运行的时候会走我们自定义的这个过滤器,也就是那个具体装饰者角色,实现接口解密返回到controller层操作。

!controller

@org.springframework.web.bind.annotation.RestController
public class RestController {

    @PostMapping("getList")
    public String ddd(@RequestParam(value = "name", required = true) String name,@RequestParam(value = "age", required = true) String age ,HttpServletRequest request) {
        System.out.println("controller层:" + name);
        return name+"\n"+age;
    }
}

评论区



© [2020] · Powered by Typecho · Theme by Morecho
鄂ICP备20005123号