使用jersey,如何生成错误的json和成功的八位字节流

使用jersey,如何生成错误的json和成功的八位字节流,jersey,jax-rs,Jersey,Jax Rs,问题的简短版本: 使用Jersey,如何在运行时确定@products类型 问题的长版本: 我使用jersy编写了一个REST调用,如下所示: @GET @Path("/getVideo") @Consumes(MediaType.APPLICATION_JSON) @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_JSON}) public Response getAllVideos(@QueryParam

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

问题的长版本: 我使用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
文件,因此
@产生({MediaType.APPLICATION\u OCTET\u STREAM,
)。但是,如果抛出异常,例如提供错误的
videoID
我想返回一个描述异常的
json

它目前的工作方式是,如果提供了有效的ID,它将返回mp4文件中的
200
。但是如果引发异常,它将以
500
响应,并且消息
无法找到类型为com.my.package.Errors$CustomError of media type:application/octet stream
的响应对象的MessageBodyWriter

基于响应的返回类型由请求的
accept
类型确定

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

我该怎么做


(我想我的问题与类似,但我没有使用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();
    }
}
@Provider
@products(MediaType.APPLICATION\u OCTET\u STREAM)//我认为您必须将其保留为OCTET\u STREAM,以便jax rs选择作为有效的消息编写器
公共类CustomErrorBodyWriter实现MessageBodyWriter{
@凌驾
公共布尔值可写(类类型、类型genericType、,
注释[]注释,MediaType(MediaType){
返回类型==CustomError.class;
}
@凌驾
公共长getSize(CustomError CustomError、类类型、类型genericType、,
注释[]注释,MediaType(MediaType){
//JAX-RS 2.0已弃用,Jersey运行时已忽略
返回0;
}
@凌驾
public void writeTo(CustomError CustomError、类类型、类型genericType、注释[]注释、,
MediaType MediaType,多值映射HttpHeader,
OutputStream out)抛出IOException、WebApplicationException{
//操作httpHeaders以使内容类型为application/json
//Translate customError并将其写入OutputStream
Writer Writer=新的PrintWriter(输出);
write(“{”key\“:\”一些随机的json,看看它是否有效\“}”);
writer.flush();
writer.close();
}
}

谢谢,这对我很有效。尽管我有“@provider”标记,但我仍然必须将该类显式地添加到资源配置/“Application”类中,但它就像您所说的那样工作。我需要添加的只是:ArrayList content=new arrarylist();content.add(“Application/json”);httpHeaders.replace(“content Type”,Collections.singletonList(content));然后将“自定义错误”转换为json字符串/