在JAX-RS中验证PUT、POST方法的空主体请求

3

我想知道在JAX-RS中是否有注释/过滤器/拦截器功能,以便检测PUT或POST方法是否包含空请求体。

目前,我有一个方法,如果请求体为空,可能会抛出NPE异常。

@PUT
@Produces("application/json")
@Consumes("application/json")
@Path("/update/{id}")
public Response updateCustomer(@PathParam("id") final String customerIdStr, final CustomerJson customer) {
    // if request body is empty -> customer == null
    return Response.ok().build();
}

我可以检查客户是否为null。但是,由于我有很多这样的方法,最好有一个过滤器来执行此类验证。

拜托了!

2个回答

1
你是否尝试过使用Bean Validation,在你的CustomerJson方法参数上加上@NotNull注释?

是的,它返回了一个短的堆栈跟踪字符串,但没有能力为其声明ExceptionMapper。 - ZuzEL
嗯,为什么不能为它注册一个ExceptionMapper?你有哪个异常类? - Xavier Coulon
这是一个空指针异常(NPE)。我不想捕获空指针异常。关键是要预测出这个空指针异常,确保在运行时之前修复它。其他的空指针异常应该被抛出以便检测到它们。 - ZuzEL
1
看起来有些不对劲。你应该得到一个MethodValidationConstraintException,而不是NPE(例如,请参见http://howtodoinjava.com/2013/05/30/resteasy-bean-validation-using-hibernate-validator-provider/)。 - Xavier Coulon
抱歉,但我使用的是 Resteasy 3.* - 所以 MethodValidationConstraintException 已被弃用。最终,我在这里找到了一个有用的示例 http://frankruenagel.blogspot.ru/2013/09/resteasy-30-with-hibernate-validator-5.html - 真的很有效。 - ZuzEL

1
拦截器读取HTTP请求体,但我找不到一种将请求体发送进行进一步处理的方法。但是您可以通过Servlet过滤器和HTTP servlet请求包装器实现此操作。
public class EmptyCheckFilter implements javax.servlet.Filter {

  @Override
  public void doFilter(ServletRequest request, ServletResponse response,
      FilterChain chain) throws IOException, ServletException {

    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse res = (HttpServletResponse) response;

    if (req.getMethod().equals("POST") || req.getMethod().equals("PUT")) {
      boolean dirty = false;
      HttpRequestWrapper wrapper = new MyHTTPRequestWrapper(req);
      try {
    // check body is empty by wrapper.getBody() and set dirty = true;
      } catch (Exception e) {
      }
      if (dirty) {
        res.sendError(400, "Invalid input");
      } else
        chain.doFilter(wrapper, response);
    } else
      chain.doFilter(request, response);
  }

  @Override
  public void destroy() {
  }

  @Override
  public void init(FilterConfig arg0) throws ServletException {
  }
}

public class MyHTTPRequestWrapper extends HttpServletRequestWrapper {

  private final String body;

  public MyHTTPRequestWrapper(HttpServletRequest request) throws IOException {
    super(request);
    StringBuilder stringBuilder = new StringBuilder();
    BufferedReader bufferedReader = null;
    try {
      InputStream inputStream = request.getInputStream();
      if (inputStream != null) {
        if (request.getCharacterEncoding() != null)
        bufferedReader = new BufferedReader(new InputStreamReader(inputStream, request.getCharacterEncoding()));
        else
          bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        char[] charBuffer = new char[128];
        int bytesRead = -1;
        while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
          stringBuilder.append(charBuffer, 0, bytesRead);
        }
      } else {
        stringBuilder.append("");
      }
    } catch (IOException ex) {
      throw ex;
    } finally {
      if (bufferedReader != null) {
        try {
          bufferedReader.close();
        } catch (IOException ex) {
          throw ex;
        }
      }
    }
    body = stringBuilder.toString();
  }

  @Override
  public ServletInputStream getInputStream() throws IOException {
    final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
        body.getBytes());
    ServletInputStream servletInputStream = new ServletInputStream() {
      public int read() throws IOException {
        return byteArrayInputStream.read();
      }
    };
    return servletInputStream;
  }

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

  public String getBody() {
    return this.body;
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接