java - 使用 Jersey ,如何生成json以获取错误并生成八位字节流以获取成功

问题的简短版本:
使用Jersey,如何在运行时确定@Produces类型?

问题的长版:
我使用jersy编写了一个REST调用,如下所示:

@GET
@Path("/getVideo")
@Consumes(MediaType.APPLICATION_JSON)
@Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON})
public Response getAllVideos(@QueryParam("videoID") Long videoID) throws ApiException, SQLException {
    --some code--
    Response r ...;
    return r;
}


如果用户提供有效的 videoID,则应返回 mp4文件,因此返回 @Produces({MediaType.APPLICATION_OCTET_STREAM,。但是,如果抛出异常,例如提供错误的 videoID,我想返回一个描述该异常的 json

当前的工作方式是,如果提供了有效的ID,它将返回mp4文件的 200。但是,如果引发异常,它将以 500和消息 Could not find MessageBodyWriter for response object of type: com.my.package.Errors$CustomError of media type: application/octet-stream响应。

基于 the Jersey documentation,响应的返回类型由请求的 accept类型确定。

我的问题是,在发送请求时,我事先并不知道我希望返回哪种类型的响应(因为我希望请求能够成功执行)。相反,我想根据是否引发异常在运行时确定响应类型。

我怎样才能做到这一点?

(我认为我的问题类似于 this question,但我没有使用Spring)。

最佳答案

这可能会起作用,因为您的异常表明它找不到CustomError的消息编写器

@Provider
@Produces(MediaType.APPLICATION_OCTET_STREAM) //I think you will have to leave this as octet_stream so jax-rs will pick as valid message writer
public class CustomErrorBodyWriter implements MessageBodyWriter<CustomError> {

    @Override
    public boolean isWriteable(Class<?> type, Type genericType,
                               Annotation[] annotations, MediaType mediaType) {
        return type == CustomError.class;
    }

    @Override
    public long getSize(CustomError customError, Class<?> type, Type genericType,
                        Annotation[] annotations, MediaType mediaType) {
        // deprecated by JAX-RS 2.0 and ignored by Jersey runtime
        return 0;
    }

    @Override
    public void writeTo(CustomError customError, Class<?> type, Type genericType, Annotation[] annotations,
                        MediaType mediaType, MultivaluedMap<String, Object> httpHeaders,
                        OutputStream out) throws IOException, WebApplicationException {

        //manipulate the httpHeaders  to have content-type application/json

        //transalate customError and write it to OutputStream          

        Writer writer = new PrintWriter(out);
        writer.write("{ \"key\" : \"some random json to see if it works\" }");


        writer.flush();
        writer.close();
    }
}