我有一个使用Dropwizard实现的服务,我需要将不正确的请求转储到某个地方。
我看到有一个possibility通过注册ExceptionMapper<JerseyViolationException>
来自定义错误消息。但是我需要完整的请求(标题,正文),而不仅仅是ConstraintViolations
。
答案 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.class
或InputStream.class
并将InputStream
转换为字符串。
ContainerRequest request = requestProvider.get();
String body = request.readEntity(String.class);