Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

json - Jersey unable to catch any Jackson Exception

For my REST api I'm using jersey and ExceptionMapper to catch global exceptions. It works well all the exception my app throws but I'm unable to catch exception thrown by jackson.

For example one of my endpoint accept an object that contains an enum. If the Json in the request has a value that is not in the enum jersey throw this exception back

Can not construct instance of my.package.MyEnum from String value 'HELLO': value not one of declared Enum instance names: [TEST, TEST2]
at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@5922e236; line: 3, column: 1] (through reference chain: java.util.HashSet[0]->....)

Even though I have created this mapper

@Provider
@Component
public class JacksonExceptionMapper implements ExceptionMapper<JsonMappingException> {
  @Override
  public Response toResponse(JsonMappingException e) {
    ....
  }
}

The code never reach this mapper.

Is there anything we need to do in order to catch these exceptions?

EDIT Note: I have jus tried being less general and instead of JsonMappingException I use InvalidFormatException in this case the mapper is called. But I still don't understand because InvalidFormatException extends JsonMappingException and should be called as well

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Had the same problem.
The problem is that JsonMappingExceptionMapper kicks in before your mapper.

The actual exception is of class com.fasterxml.jackson.databind.exc.InvalidFormatException and the mapper defines com.fasterxml.jackson.jaxrs.base.JsonMappingException, so it's more specific to the exception.
You see, Jersey's exception handler looks to find the most accurate handler (see org.glassfish.jersey.internal.ExceptionMapperFactory#find(java.lang.Class, T)).

To override this behavior, simply disable the mapper from being used:

  1. Using XML: <init-param> <param-name>jersey.config.server.disableAutoDiscovery</param-name> <param-value>true</param-value> </init-param>

  2. Using code: resourceConfig.property(CommonProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true); where resourceConfig is of type org.glassfish.jersey.server.ServerConfig.


You can also write your own specific mapper:

public class MyJsonMappingExceptionMapper implements ExceptionMapper<JsonMappingException>

But I think it's an over kill.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...