使用HttpServletRequestWrapper来修改post请求中的json数据


公司里最近在做一个新的项目,项目中所有的请求都是这样的一个格式。
在这里插入图片描述
因为version版本号在业务里并没有用到,只是一个验证依据,所以就想把它过滤掉。

过滤的效果:
过滤前
{
"version" : "11111111",
"data": {
   "heartbeat_time": 1468471315134
}
}
过滤后
{"heartbeat_time":1468471315134}
具体的实现代码:

1.自定义一个过滤器

@Component
@ServletComponentScan
@WebFilter(urlPatterns = "/north/*", filterName = "httpFilter")//此处的url根据实际情况而定
public class HttpReplaceFilter implements Filter {
    private static final Set<String> ALLOW_PATHS = new HashSet<>(Arrays.asList("/serviceName"));

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        String path = ((HttpServletRequest)request).getRequestURI().substring(((HttpServletRequest) request).getContextPath().length());
        //如果是在ALLOW_PATHS的集合中,那么就允许这种请求直接通过
        if (ALLOW_PATHS.contains(path)){
            filterChain.doFilter(request, response);
        }
        //HttpServletRequest没有提供相关的set方法来修改body,所以需要用修饰类
        ServletRequest requestWrapper = new BodyRequestWrapper((HttpServletRequest) request);

        filterChain.doFilter(requestWrapper, response);
    }

    @Override
    public void destroy() {

    }
}

2.自定义一个Http请求的修饰类

public class BodyRequestWrapper extends HttpServletRequestWrapper {

    private byte[] body;
    public BodyRequestWrapper(HttpServletRequest request) throws IOException {
        super(request);
        StreamUtil.readBytes(request.getReader(), "utf-8");
        //由于request并没有提供现成的获取json字符串的方法,所以我们需要将body中的流转为字符串
        String json = new String(StreamUtil.readBytes(request.getReader(), "utf-8"));
        body = getData(json).getBytes();
    }

    @Override
    public BufferedReader getReader() throws IOException {
        return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    /**
     * 在使用@RequestBody注解的时候,其实框架是调用了getInputStream()方法,所以我们要重写这个方法
     * @return
     * @throws IOException
     */
    @Override
    public ServletInputStream getInputStream() throws IOException {
        final ByteArrayInputStream bais = new ByteArrayInputStream(body);

        return new ServletInputStream() {
            @Override
            public boolean isFinished() {
                return false;
            }

            @Override
            public boolean isReady() {
                return false;
            }

            @Override
            public void setReadListener(ReadListener readListener) {

            }

            @Override
            public int read() throws IOException {
                return bais.read();
            }
        };
    }

    private String getData(String json){
        if (!json.contains("\"data\"")){
            return "";
        }
        ObjectMapper mapper = new ObjectMapper();
        String data = null;
        try {
            JsonNode jsonNode = mapper.readTree(json);
            data = jsonNode.get("data").toString();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return data;
    }
}

以上代码就可以实现将json数据过滤掉了

框架是springboot,还有用到了joda-io依赖包

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
HandlerInterceptorAdapter 是 Spring MVC 提供的拦截器,可以在请求处理之前或之后对请求进行拦截和处理。 下面是一个示例,演示了如何使用 HandlerInterceptorAdapter 对 POST 请求进行拦截并重写 JSON 参数: ```java public class JsonParamInterceptor extends HandlerInterceptorAdapter { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (request.getMethod().equals("POST")) { String contentType = request.getHeader("Content-Type"); if (contentType != null && contentType.contains("application/json")) { // 读取 JSON 参数 String json = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8); JSONObject jsonObj = JSONObject.parseObject(json); // 修改 JSON 参数 jsonObj.put("newKey", "newValue"); // 重写请求参数 String newJson = jsonObj.toJSONString(); request = new CustomHttpServletRequest(request, newJson.getBytes(StandardCharsets.UTF_8)); } } return true; } private static class CustomHttpServletRequest extends HttpServletRequestWrapper { private final byte[] body; public CustomHttpServletRequest(HttpServletRequest request, byte[] body) { super(request); this.body = body; } @Override public ServletInputStream getInputStream() throws IOException { return new ServletInputStreamWrapper(body); } @Override public BufferedReader getReader() throws IOException { return new BufferedReader(new InputStreamReader(getInputStream(), StandardCharsets.UTF_8)); } } private static class ServletInputStreamWrapper extends ServletInputStream { private final ByteArrayInputStream bis; public ServletInputStreamWrapper(byte[] buffer) { this.bis = new ByteArrayInputStream(buffer); } @Override public int read() throws IOException { return bis.read(); } } } ``` 上述代码,我们在 `preHandle` 方法判断请求是否为 POST 请求,并且 Content-Type 是否为 application/json。如果是,就读取 JSON 参数,并且修改的一个字段,最后重写请求参数,然后将修改后的请求继续传递给后续的处理器。 注意,为了重写请求参数,我们需要自定义一个 HttpServletRequestWrapper,并且重写 getInputStream 和 getReader 方法。这样就可以将修改后的请求参数传递给后续的处理器了。 当然,这只是一个简单的示例,实际场景可能需要更复杂的处理逻辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值