倾销不良要求

时间:2018-10-19 14:18:35

标签: rest jersey dropwizard bean-validation

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

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

1 个答案:

答案 0 :(得分:2)

您可以将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()获取标头。如果要获取主体,则需要做一些改动,因为在到达映射器时,Jersey已经读取了实体流。因此,我们需要实现ContainerRequestFilter来缓冲实体。

public class EntityBufferingFilter implements ContainerRequestFilter {

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

您可能不希望为 all 请求调用此过滤器(出于性能原因),因此您可能想使用DynamicFeature仅在使用bean的方法上注册过滤器验证(或使用Name Binding)。

一旦注册了此过滤器,就可以使用ContainerRequest#readEntity(Class)读取正文。您可以像使用客户端Response#readEntity()一样使用此方法。因此,对于该类,如果要保持其通用性,可以使用String.classInputStream.class并将InputStream转换为字符串。

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