0

I am using Jersey 2.5.1 with Jackson 2.2. for building JSON Rest web services. I kind of got it up and running also with 2 ExceptionMappers but for a "not-json" request the application is not throwing any exception!

  1. ExceptionMapper Will be invoked if e.g. a NullPointerException is thrown

  2. ExceptionMapper Will be invoked if there s a problem with the JSon Mapping

My Problem: 1. Request Body: {} works 2. Request Body: {} with an application side NullPointer invoked the first exception mapper 3. Request Body: "jibberish" does not invoke anything (not caught by any ExceptionMapper) cause no Exception is thrown. Unfortunately the response body is sth like : Unrecognized field "xxx" (class com.sample.MyDto), not marked as ignorable (9 known properties... ....> but I want to customize the error msg since I am always returning a JSon object.

cloudnaut
  • 982
  • 3
  • 13
  • 35
  • Is your mapper `ExceptionMapper`, or do you have them set up only for specific exception types? – Alden Jan 23 '14 at 15:36
  • yes exactly! ExceptionMapper and it s working if an Exception is thrown. Unfortunately the application does not throw a JsonMappingException if I send "jibberish" instead of JSon. Another weird thing is, that it also worked from time to time. I also checked if I have any old jackson jars (e.g. 1.9.) in my classpath but, no. – cloudnaut Jan 23 '14 at 15:47
  • What status code are you getting back with the Unrecognized field "xxx" response? Also you might try registering an additional mapper for `ExceptionMapper`. I know in older versions of jersey there were cases where only `WebApplicationException` mappers were invoked, not generic ones – Alden Jan 23 '14 at 16:04
  • This [answer](https://stackoverflow.com/a/66721295/3303074), solves the problems – Prasanth Rajendran Apr 01 '21 at 07:21

2 Answers2

2

Ok, I solved it. What finally made me think the right way was, that sometimes it worked so it had to be some overwrite class loading issue.

In my ApplicationClass I registered Providers based on packages like this

    @ApplicationPath("resources")
    public class JerseyApplication extends ResourceConfig {
    public JerseyRestApplication() {            
        packages("com.sample", "com.fasterxml.jackson.jaxrs.json");
    }
}

If you look sharp you might see the error! I am putting "com.fasterxml.jackson.jaxrs.json" on the search path because I want to use the JacksonJsonProvider.class. What I did not know is, that in that package there are also some JSonMappers for JSonParseException etc. and those do not log :)

So sometimes the application was loading mine first and sometimes the one from jackson. So I am going to stick with the following now:

@ApplicationPath("resources")
public class JerseyRestApplication extends ResourceConfig {
    public JerseyApplication() {
        register(JacksonJsonProvider.class); // Do it manually

        packages("com.sample");
    }
}

Hope that helps sb :D

pawel
  • 513
  • 8
  • 15
cloudnaut
  • 982
  • 3
  • 13
  • 35
0

I also found sometime coustom ExceptionMapper not work, and it's not always work or not work.

so i debug the jersey's source code .

class: org.glassfish.jersey.server.ServerRuntime, methed:mapException

 ...
 final long timestamp = tracingLogger.timestamp(ServerTraceEvent.EXCEPTION_MAPPING);
 **ExceptionMapper mapper = runtime.exceptionMappers.findMapping(throwable);**
 if (mapper != null) {
      request.getRequestEventBuilder().setExceptionMapper(mapper);
 ...

if the mapper is null, the coustom ExceptionMapper will be not work.

class: org.glassfish.jersey.internal.ExceptionMapperFactory methed: ExceptionMapperFactory

the Exception Mapper :(there two Exception mapping one same Exception: java.lang.Exception)

org.glassfish.jersey.server.mvc.internal.ErrorTemplateExceptionMapper@6473fc2,class java.lang.Exception

...

com.baidu.ssp.web.ws.exception.BaseExceptionMapper@7a84639c,class java.lang.Exception

it's because in MvcFeature:

 @Override
public boolean configure(final FeatureContext context) {
    final Configuration config = context.getConfiguration();

    if (!config.isRegistered(ErrorTemplateExceptionMapper.class)) {
        context.register(ErrorTemplateExceptionMapper.class);
        context.register(new MvcBinder());

        return true;
    }

    return false;
}

the ErrorTemplateExceptionMapper is also add to ExceptionMapper.

so i change my custom MapperException's genericity type : ExceptionMapper to ExceptionMapper

may be my resolution is not fit for you , the main problem is the ExceptionMapper.