我有一个资源:
@GET
@Path("/print-order")
@Produces("application/pdf")
public byte[] printOrder(@QueryParam("id") Long orderId) {
return ...;
}
...可以抛出与用户相关的错误,并且必须显示为HTML页面。所以我实现了ExceptionMapper
,但我不知道如何获取被调用资源的@Produces("application/pdf")
注释的值。
@Provider
public class CustomExceptionMapper implements ExceptionMapper<CustomException> {
@Override
public Response toResponse(CustomException exception) {
if (contentType = "application/pdf")
... html respone
else
... entity response
}
}
我使用JAX-RS 1.x(jsr311)和Jersy 1.12实现,但很想拥有独立于实现的解决方案。
答案 0 :(得分:2)
您可以将不同的上下文对象注入ExceptionMapper
以获取有关其处理的请求的更多信息。根据HTTP的Accept
标题(了解更多here)确定客户期望的内容类型非常方便。
以下示例说明如何使ExceptionMapper
根据API客户端指定(或未指定)的Accept
标头以不同格式进行响应。
@Provider
public class CustomExceptionMapper implements ExceptionMapper<CustomException> {
// Inject headers of the request being processed
@Context
private HttpHeaders headers;
// or even all the request details
@Context
private HttpServletRequest request;
@Override
public Response toResponse(CustomException exception) {
List<MediaType> acceptedTypes = headers.getAcceptableMediaTypes();
if (acceptedTypes.contains(MediaType.APPLICATION_JSON)) {
// respond with entity
} else {
// respond with HTML
}
}
}
但是,您可以实现最初的想法。您可以在资源类中注入HttpServletRequest
,并使用setAttribute()方法在当前请求的上下文中存储application/pdf
字符串。稍后可以使用getAttribute()方法在ExceptionMapper
中获取它。 但除非绝对必要,否则我不建议这样做。它引入了代码组件之间不那么明显的依赖关系。