我想允许客户端使用 HTTP 内容协商来选择错误响应格式。
例如给定一个端点
@Produces("application/json")
class MyService {
@GET
public String getSomething() {
if (currentTimeMilis() % 2 == 0) throw new MyException();
return "{ hello:\"world\" }";
}
和异常映射器:
class MyExceptionMapper implements ExceptionMapper<MyException> {
@Override
public Response toResponse(MyException ex) {
return status(BAD_REQUEST)
.entity(new MyDto(randomUUID(), ex.getMessage()))
.build();
}
}
并且有两个 body writer,MyBodyWriter
和标准的 JacksonJsonProvider
。
我想根据 Accept header 的内容调用其中一位作者,例如
接受:application/json
-> 调用JacksonJsonProvider
接受:application/vnd-mycompany-error, application/json
-> 调用MyBodyWriter
我尝试过不同的方法,但都失败了,因为匹配的 HttpRule
暗示了 application/json
内容类型。
我发现的唯一解决方法是将请求 header 注入(inject) ExceptionMapper
并在那里明确设置内容类型——但我不喜欢它。
最佳答案
也许只是一种解决方法,但是......
您可以尝试使用 ContainerResponseFilter
,从 ContainerRequestContext
获取所有接受的 MediaType,并通过使用 ContainerResponseContext.setEntity
重置实体来限制响应 MediaType。
可能有更好的解决方案!
二手 Jersey 2.12:
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.List;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.Provider;
import path.to.MyException;
@Provider
public class EntityResponseFilter implements ContainerResponseFilter {
@Override
public void filter( ContainerRequestContext reqc , ContainerResponseContext resc ) throws IOException {
List<MediaType> mediaTypes = reqc.getAcceptableMediaTypes();
MediaType mediaType = new MediaType("application", "vnd-mycompany-error");
if( mediaTypes.contains( mediaType) && resc.getEntity() instanceof MyDao /* or MyDto, or null, or whatever */) {
resc.setEntity( resc.getEntity(), new Annotation[0], mediaType );
}
// ...
}
}
希望这在某种程度上有所帮助:)
关于java - Jersey - 错误处理的内容协商,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25815829/