java - Jersey - 错误处理的内容协商

标签 java jersey jax-rs content-negotiation

我想允许客户端使用 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/

相关文章:

java - 带有自定义值对象的映射

java - 如何在运行时获取 JUnit 4 中的测试用例名称?

java - Android - 保留 headless fragment

java - JSON 包含 unicode 字符

rest - 使用 jaxrs+apache+eclipse 获取 rest api 时返回 404,静态 index.html 工作正常

java - 找不到提供程序类 : when running Jersey REST service

java - 使用 Java Swing 的 JPanel 内的面板

java - 大数据集的Jersey Streaming输出

java - 如何在 JAX-RS Web 服务中返回 XML 格式的响应?

rest - CORS 原点允许参数维护