Java >> Java tutorial >  >> Java

Jersey Exception-kortlæggere fungerer ikke, når jackson-deserialisering mislykkes

Jeg testede det med en undtagelsesmapper som nedenfor:

import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

import com.fasterxml.jackson.core.JsonProcessingException;

@Provider
public class JsonProcessingExceptionMapper implements ExceptionMapper<JsonProcessingException>{

        public static class Error {
            public String key;
            public String message;
        }

        @Override
        public Response toResponse(JsonProcessingException exception) {
            Error error = new Error();
            error.key = "bad-json";
            error.message = exception.getMessage();
            return Response.status(Status.BAD_REQUEST).entity(error).build();
        }
}

og det virkede.

Opdatering: ændrede JsonParseException til JsonProcessingException (mere generelt)

Opdatering 2: For at undgå at registrere de uønskede kortlæggere udskiftes

register(org.glassfish.jersey.jackson.JacksonFeature.class);

med

register(com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider.class);

Se på kildekoden til JacksonFeature, og du vil forstå, hvad der sker.


Jeg havde det samme problem, og det forrige svar førte mig til løsningen, men var ikke forgrenet for mig nuværende Jersey (2.22). Først skulle jeg bruge org.glassfish.jersey.spi.ExtendedExceptionMapper som beskrevet i https://jersey.java.net/documentation/latest/representations.html.

Ydermere søger Jersey efter en undtagelsesmapper, som er så tæt som muligt på den kastede undtagelse (fra org.glassfish.jersey.internal.ExceptionMapperFactory ):

for (final ExceptionMapperType mapperType : exceptionMapperTypes) {
        final int d = distance(type, mapperType.exceptionType);
        if (d >= 0 && d <= minDistance) {
            final ExceptionMapper<T> candidate = mapperType.mapper.getService();

            if (isPreferredCandidate(exceptionInstance, candidate, d == minDistance)) {
                mapper = candidate;
                minDistance = d;
                if (d == 0) {
                    // slight optimization: if the distance is 0, it is already the best case, so we can exit
                    return mapper;
                }
            }
        }
    }

Derfor var jeg nødt til at kortlægge præcis undtagelsen og ikke en mere generel undtagelse.

I sidste ende ser min udbyder ud som følger:

@Provider
public final class JsonParseExceptionExceptionHandler implements ExtendedExceptionMapper<JsonParseException> {
    @Override
    public Response toResponse(final JsonParseException exception) {
        exception.printStackTrace();
        return Response.status(Response.Status.BAD_REQUEST).entity("JSON nicht in korrektem Format.").build();
    }

    @Override
    public boolean isMappable(final JsonParseException arg0) {
        return true;
    }
}

Jeg brugte "jackson-jaxrs-json-provider 2.8.8" og JAX-RS 2.0

Applikationsklasse - du skal registrere din ExceptionMapper implementeringsklasse:

@ApplicationPath("pathApplication")
public class ApplicationConfiguration extends Application{


   @Override
   public Set<Class<?>> getClasses() {

      Set<Class<?>> resources = new HashSet<>();
      resources.add(YourJAXRSClass.class);
      resources.add(JsonJacksonEM.class); //ExceptionMapper class implementation
      //others resources that you need...
      return resources; 

   }


}

ExceptionMapper-klasseimplementering:

@Provider
public class JsonJacksonEM implements ExceptionMapper<JsonParseException>{


   @Override
   public Response toResponse(JsonParseException exception) {
      //you can return a Response in the way that you want!
      return Response.ok(new YourObject()).build();
   }


}

Java tag