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();
}
}