使用球衣,如何为错误生成 json 并为成功生成八位字节流
Using jersey, how can I produce json for errors and octet stream for success
问题的简短版本:
使用 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
,那么这应该 return 一个 mp4
文件,因此 @Produces({MediaType.APPLICATION_OCTET_STREAM,
。但是,如果抛出异常,比如一个提供错误的videoID
我想return一个json
描述异常。
它目前的工作方式是,如果提供了有效的 ID,它 return 是一个 200
的 mp4 文件。但如果抛出异常,它会以 500
和消息 Could not find MessageBodyWriter for response object of type: com.my.package.Errors$CustomError of media type: application/octet-stream
.
进行响应
基于 the Jersey documentation 响应的 return 类型由请求的 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();
}
}
你需要的是提供给接受这两种类型的客户。这里描述这个solution.
问题的简短版本:
使用 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
,那么这应该 return 一个 mp4
文件,因此 @Produces({MediaType.APPLICATION_OCTET_STREAM,
。但是,如果抛出异常,比如一个提供错误的videoID
我想return一个json
描述异常。
它目前的工作方式是,如果提供了有效的 ID,它 return 是一个 200
的 mp4 文件。但如果抛出异常,它会以 500
和消息 Could not find MessageBodyWriter for response object of type: com.my.package.Errors$CustomError of media type: application/octet-stream
.
基于 the Jersey documentation 响应的 return 类型由请求的 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();
}
}
你需要的是提供给接受这两种类型的客户。这里描述这个solution.