java 带有 XML 或 JSON 的 JAX-RS(泽西岛)自定义异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3227360/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JAX-RS (Jersey) custom exception with XML or JSON
提问by Oskar
I have a REST service built using Jersey.
我有一个使用 Jersey 构建的 REST 服务。
I want to be able to set the MIME of my custom exception writers depending on the MIME that was sent to the server. application/jsonis returned when json is received, and application/xmlwhen xml is received.
我希望能够根据发送到服务器的 MIME 设置我的自定义异常编写器的 MIME。application/json接收json时返回,接收application/xmlxml时返回。
Now I hard code application/json, but that's making the XML clients left in the dark.
现在我进行了硬编码application/json,但这使 XML 客户端被蒙在鼓里。
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());
}
}
What context can I tap into to get the current requests Content-Type?
我可以利用什么上下文来获取当前请求Content-Type?
Thanks!
谢谢!
Update based on answer
根据答案更新
For anyone else interested in the complete solution:
对于对完整解决方案感兴趣的其他人:
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
}
Together with an ExceptionMapper
与一个 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();
}
}
Where ErrorResponseConverter is a custom JAXB POJO
其中 ErrorResponseConverter 是一个自定义的 JAXB POJO
采纳答案by Bryant Luk
You can try adding a @javax.ws.rs.core.Context javax.ws.rs.core.HttpHeaders field/property to your root resource class, resource method parameter, or to a custom javax.ws.rs.ext.ExceptionMapper and calling HttpHeaders.getMediaType().
您可以尝试将 @javax.ws.rs.core.Context javax.ws.rs.core.HttpHeaders 字段/属性添加到您的根资源类、资源方法参数或自定义 javax.ws.rs.ext.ExceptionMapper并调用 HttpHeaders.getMediaType()。
回答by Domenic D.
headers.getMediaType() responds with the media type of the Entity, not the Accept header. The appropriate way to convert the exception is with the Accept header so your client gets the response in the format they requested. Given the above solution, if your request looks like the following (note JSON accept header, but XML Entity), you will get XML back.
headers.getMediaType() 响应实体的媒体类型,而不是 Accept 标头。转换异常的适当方法是使用 Accept 标头,以便您的客户端以他们请求的格式获取响应。鉴于上述解决方案,如果您的请求如下所示(注意 JSON 接受标头,但 XML 实体),您将返回 XML。
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>
The correct implementation is again, to use the Accept header:
正确的实现是再次使用 Accept 标头:
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();
}

