【Bug】使用Filter替换@RequestBody注解参数中的指定字符无效

项目中前后端交互数据类型使用json字符串,由于显示原因需要对指定字符进行转义处理,以前的处理方式是将HttpServletRequest重新封装,重写getParameter()等取值方法,在重写的取值方法获取到参数值后对该值进行处理。使用Filterrequest对象转换成我们之定义的HttpServletRequest对象。这样当我们使用request对象取值时就会对指定的字符进行处理。

public class XxxHttpServletRequestWrapper extends HttpServletRequestWrapper {

    public XxxHttpServletRequestWrapper(HttpServletRequest servletRequest) {
        super(servletRequest);
    }

    public String getParameter(String parameter) {
        String value = super.getParameter(parameter);
        if (StringUtils.isBlank(value)) {
            return value;
        }
        return filterSpecialCharacter(value);
    }

    //TODO 添加其它取值方法

    private String filterSpecialCharacter(String value) {
        //替换value中的指定字符并返回新的字符串
        return value;
    }
}
public class XxxFilter implements Filter {

    FilterConfig filterConfig = null;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
    }

    @Override
    public void destroy() {
        this.filterConfig = null;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws ServletException, IOException {
            chain.doFilter(new XxxHttpServletRequestWrapper((HttpServletRequest) request), response);
        }
    }
}
<filter>
    <filter-name>XxxFilterfilter-name>
    <filter-class>Xxx.Xxx.XxxFilterfilter-class>
filter>
<filter-mapping>
    <filter-name>XxxFilterfilter-name>
    <url-pattern>/*url-pattern>
filter-mapping>

如上是以前的写法,但在当前项目中却不起作用。

以前项目前后端数据交互是前端直接提交表单数据后端使用对象接收,属性赋值是由Spring内部处理。而本次项目在提交数据到后端时先将数据转换成了JSON字符串,后端接收参数也使用了@RequestBody进行了注解。

猜测是不是SpringJSON字符串转为Java对象时,取值方式和我们平时使用的request.getParameter()不一样。

通过断点跟踪Spring代码可以发现,fastJson获取数据是直接从输入流获取,并未调用request对象的取值方法,所以我们写的XxxHttpServletRequestWrapper类中的方法没有被调用,也就无法实现对值中的指定字符进行替换。

解决方案:
fastJson从输入流中获取到字节数据后,先转成字符串然后再填充到目标类中,我们可以在转成字符串之后填充到目标类之前,加入我们替换指定字符的逻辑代码

你可能感兴趣的:(【Bug】)