我有一个使用Grizzly,Jersey,Jackson堆栈的宁静服务。如果我在请求中提供了错误的输入值,例如:随机字符串而不是UUID,则Jackson会抛出无效格式或无法识别的属性异常。出于安全考虑,我为大多数通用异常添加了异常映射器以隐藏异常详细信息。但是对于这种非常具体的情况,如果用户提供错误数据并且反序列化失败,我想提供用户反馈,说明调用失败的原因。
我认为如果我可以将反序列化调用从Jersey包装到Jackson,那么我可以使用适当的数据抛出自定义异常并为我的自定义异常添加一个映射器。
所以,我创建了一个新类,它覆盖了JacksonJaxbJsonProvider并将包装代码添加到readFrom。
@Provider
@Consumes(MediaType.WILDCARD) // NOTE: required to support "non-standard" JSON variants
@Produces(MediaType.WILDCARD)
public class JacksonJaxbJsonProviderOverride extends JacksonJaxbJsonProvider {
private static final Logger logger = LoggerFactory.getLogger(JacksonJaxbJsonProviderOverride.class);
@Override
public Object readFrom(
Class<Object> type,
Type genericType,
Annotation[] annotations,
MediaType mediaType,
MultivaluedMap<String, String> httpHeaders,
InputStream entityStream)
throws IOException {
try {
return super.readFrom(type, genericType, annotations, mediaType, httpHeaders, entityStream);
} catch (Exception ex) {
throw new ObjectDeserializationException(ex.getMessage());
}
}
我还在泽西岛注册了这个课程如下:
// Use our JacksonProducer mapper for serialization/deserialization
JacksonJaxbJsonProviderOverride jaxbJsonProvider = new JacksonJaxbJsonProviderOverride();
jaxbJsonProvider.setMapper(JacksonProducer.getMapperForJaxb());
resourceConfig.register(jaxbJsonProvider);
但是反序列化的要求没有达到覆盖范围。有关为何发生这种情况的任何想法?
com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of java.util.UUID from String value 'foo': not a valid textual representation, problem: UUID has to be represented by the standard 36-char representation
at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@43277af; line: 1, column: 2] (through reference chain: com.oracle.opc.nimbula.foo.models.api.BackupInput["backupConfigurationId"])
at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:55) ~[program-0.3.0-20160226101624.jar:na]
at com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:907) ~[program-0.3.0-20160226101624.jar:na]
at com.fasterxml.jackson.databind.deser.std.FromStringDeserializer.deserialize(FromStringDeserializer.java:136) ~[program-0.3.0-20160226101624.jar:na]
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:520) ~[program-0.3.0-20160226101624.jar:na]
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:95) ~[program-0.3.0-20160226101624.jar:na]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:258) ~[program-0.3.0-20160226101624.jar:na]
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125) ~[program-0.3.0-20160226101624.jar:na]
at com.fasterxml.jackson.databind.ObjectReader._bind(ObjectReader.java:1470) ~[program-0.3.0-20160226101624.jar:na]
at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:912) ~[program-0.3.0-20160226101624.jar:na]
at com.fasterxml.jackson.jaxrs.base.ProviderBase.readFrom(ProviderBase.java:810) ~[program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$lReaderInterceptor.invokeReadFrom(ReaderInterceptorExecutor.java:256) ~[program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$TerminalReaderInterceptor.aroundReadFrom(ReaderInterceptorExecutor.java:235) ~[program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:155) ~[program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.server.internal.MappableExceptionWrapperInterceptor.aroundReadFrom(MappableExceptionWrapperInterceptor.java:74) ~[program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.message.internal.ReaderInterceptorExecutor.proceed(ReaderInterceptorExecutor.java:155) ~[program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.message.internal.MessageBodyFactory.readFrom(MessageBodyFactory.java:1085) ~[program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.message.internal.InboundMessageContext.readEntity(InboundMessageContext.java:874) ~[program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.server.ContainerRequest.readEntity(ContainerRequest.java:271) ~[program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.server.internal.inject.EntityParamValueFactoryProvider$EntityValueFactory.provide(EntityParamValueFactoryProvider.java:96) ~[program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.server.spi.internal.ParamValueFactoryWithSource.provide(ParamValueFactoryWithSource.java:71) ~[program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:94) ~[program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:127) ~[program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourcDispatcherProvider.java:160) ~[program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:99) ~[program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:389) ~[program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:347) ~[program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:102) ~[program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.server.ServerRuntime$2.run(ServerRuntime.java:326) ~[program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:271) [program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.internal.Errors$1.call(Errors.java:267) [program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.internal.Errors.process(Errors.java:315) [program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.internal.Errors.process(Errors.java:297) [program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.internal.Errors.process(Errors.java:267) [program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:317) [program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:305) [program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:1154) [program-0.3.0-20160226101624.jar:na]
at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:384) [program-0.3.0-20160226101624.jar:na]
at org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:224) [program-0.3.0-20160226101624.jar:na]
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.j) [program-0.3.0-20160226101624.jar:na]
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:571) [program-0.3.0-20160226101624.jar:na]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_73]
Caused by: java.lang.NumberFormatException: UUID has to be represented by the standard 36-char representation
at com.fasterxml.jackson.databind.deser.std.UUIDDeserializer._badFormat(UUIDDeserializer.java:75) ~[program-0.3.0-20160226101624.jar:na]
at com.fasterxml.jackson.databind.deser.std.UUIDDeserializer._deserialize(UUIDDeserializer.java:40) ~[program-0.3.0-20160226101624.jar:na]
at com.fasterxml.jackson.databind.deser.std.UUIDDeserializer._deserialize(UUIDDeserializer.java:11) ~[program-0.3.0-20160226101624.jar:na]
at com.fasterxml.jackson.databind.deser.std.FromStringDeserializer.deserialize(FromStringDeserializer.java:122) ~[program-0.3.0-20160226101624.jar:na]
... 38 common frames omitted