Jersey - 内容协商用于错误处理

3

我希望能够让客户通过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头的内容来调用其中一个writer,例如:

  • Accept: application/json -> 调用JacksonJsonProvider
  • Accept: application/vnd-mycompany-error, application/json -> 调用MyBodyWriter

我尝试了不同的方法,但它们都失败了,因为匹配的HttpRule暗示了一个application/json的content type。

我唯一找到的解决方法是将请求头注入到ExceptionMapper中,并在那里显式地设置content type -- 但我不喜欢这种方法。

1个回答

2

Maybe just a workaround, but ...
You could try to use a ContainerResponseFilter, get all accpeted MediaTypes from the ContainerRequestContext and limit the response MediaType by reset the entity with ContainerResponseContext.setEntity.

There might be better solutions!
Used 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 );
        }
        // ...
    }
}

Hope this was helpfull somehow:)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接