java - restful - rest maven eclipse
JAX-RS(Jersey) excepción personalizada con XML o JSON (2)
Puede intentar agregar un @ javax.ws.rs.core.Context javax.ws.rs.core.HttpHeaders field / property a su clase de recurso raíz, parámetro de método de recursos, o a un javax.ws.rs.ext.ExceptionMapper personalizado y llamando a HttpHeaders.getMediaType ().
Tengo un servicio REST construido usando Jersey.
Quiero poder configurar el MIME de mis escritores de excepciones personalizados en función del MIME que se envió al servidor. application/json
se devuelve cuando se recibe json, y application/xml
cuando se recibe xml.
Ahora tengo la application/json
hard code application/json
, pero eso hace que los clientes XML queden en la oscuridad.
public class MyCustomException extends WebApplicationException {
public MyCustomException(Status status, String message, String reason, int errorCode) {
super(Response.status(status).
entity(new ErrorResponseConverter(message, reason, errorCode)).
type("application/json").build());
}
}
¿En qué contexto puedo acceder para obtener las solicitudes actuales de Content-Type
?
¡Gracias!
Actualización basada en respuesta
Para cualquier persona interesada en la solución completa:
public class MyCustomException extends RuntimeException {
private String reason;
private Status status;
private int errorCode;
public MyCustomException(String message, String reason, Status status, int errorCode) {
super(message);
this.reason = reason;
this.status = status;
this.errorCode = errorCode;
}
//Getters and setters
}
Junto con un ExceptionMapper
@Provider
public class MyCustomExceptionMapper implements ExceptionMapper<MyCustomException> {
@Context
private HttpHeaders headers;
public Response toResponse(MyCustomException e) {
return Response.status(e.getStatus()).
entity(new ErrorResponseConverter(e.getMessage(), e.getReason(), e.getErrorCode())).
type(headers.getMediaType()).
build();
}
}
Donde ErrorResponseConverter es un POJO JAXB personalizado
headers.getMediaType () responde con el tipo de medio de la Entidad, no con el encabezado Aceptar. La forma adecuada de convertir la excepción es con el encabezado Aceptar para que su cliente obtenga la respuesta en el formato que solicitó. Dada la solución anterior, si su solicitud es similar a la siguiente (observe el encabezado de aceptación JSON, pero la entidad XML), obtendrá XML nuevamente.
POST http://localhost:8080/service/giftcard/invoice?draft=true HTTP/1.1 Accept: application/json Authorization: Basic dXNlcjp1c2Vy Content-Type: application/xml User-Agent: Jakarta Commons-HttpClient/3.1 Host: localhost:8080 Proxy-Connection: Keep-Alive Content-Length: 502 <?xml version="1.0" encoding="UTF-8" standalone="yes"?><sample><node1></node1></sample>
La implementación correcta es de nuevo, para usar el encabezado Aceptar:
public Response toResponse(final CustomException e) {
LOGGER.debug("Mapping CustomException with status + /"" + e.getStatus() + "/" and message: /"" + e.getMessage()
+ "/"");
ResponseBuilder rb = Response.status(e.getStatus()).entity(
new ErrorResponseConverter(e.getMessage(), e.getReason(), e.getErrorCode()));
List<MediaType> accepts = headers.getAcceptableMediaTypes();
if (accepts!=null && accepts.size() > 0) {
//just pick the first one
MediaType m = accepts.get(0);
LOGGER.debug("Setting response type to " + m);
rb = rb.type(m);
}
else {
//if not specified, use the entity type
rb = rb.type(headers.getMediaType()); // set the response type to the entity type.
}
return rb.build();
}