转储不良请求

Dumping bad requests

我有一个使用 Dropwizard 实现的服务,我需要在某处转储不正确的请求。

我看到有一个possibility可以通过注册ExceptionMapper<JerseyViolationException>来自定义错误信息。但我需要完整的请求(标​​题、正文),而不仅仅是 ConstraintViolations.

您可以将 ContainerRequest 注入 ExceptionMapper。不过,您需要将其作为 javax.inject.Provider 注入,以便您可以懒惰地检索它。否则,您将 运行 陷入范围界定问题。

@Provider
public class Mapper implements ExceptionMapper<ConstraintViolationException> {
    
    @Inject
    private javax.inject.Provider<ContainerRequest> requestProvider;

    @Override
    public Response toResponse(ConstraintViolationException ex) {
        ContainerRequest request = requestProvider.get();
    }
}

(这也适用于构造函数参数注入而不是字段注入。)

ContainerRequest中,你可以用getHeaderString()getHeaders()得到headers。如果你想获得 body,你需要做一些 hack,因为在到达映射器时实体流已经被 Jersey 读取了。所以我们需要实现一个ContainerRequestFilter来缓冲实体。

public class EntityBufferingFilter implements ContainerRequestFilter {

    @Override
    public void filter(ContainerRequestContext containerRequestContext) throws IOException {
        ContainerRequest request = (ContainerRequest) containerRequestContext;
        request.bufferEntity();
    }
}

您可能不希望为 所有 请求调用此过滤器(出于性能原因),因此您可能希望使用 DynamicFeature to register the filter just on methods that use bean validation (or use Name Binding).

注册此过滤器后,您可以使用 ContainerRequest#readEntity(Class) 阅读 body。您可以像在客户端使用 Response#readEntity() 一样使用此方法。所以对于 class,如果你想保持它的通用性,你可以使用 String.classInputStream.class 并将 InputStream 转换为字符串。

ContainerRequest request = requestProvider.get();
String body = request.readEntity(String.class);