【问题标题】:Using jersey, how can I produce json for errors and octet stream for success使用球衣,我如何为错误生成 json 并为成功生成八位字节流
【发布时间】:2020-10-09 23:22:00
【问题描述】:

问题的简短版本:

使用 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)。

【问题讨论】:

    标签: jersey jax-rs


    【解决方案1】:

    您需要提供给接受这两种类型的客户端。这里描述了这个solution

    【讨论】:

      【解决方案2】:

      这可能会起作用,因为您的异常表明它找不到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”标签,我仍然必须明确地将这个类添加到资源配置/“应用程序”类中,但它就像你说的那样工作。我需要添加的是: ArrayList content = new ArrayList(); content.add("应用程序/json"); httpHeaders.replace("Content-Type", Collections.singletonList(content));然后将“自定义错误”转换为json字符串/
      猜你喜欢
      • 2015-01-22
      • 1970-01-01
      • 1970-01-01
      • 2013-12-03
      • 2015-02-20
      • 1970-01-01
      • 2014-01-14
      • 1970-01-01
      • 2012-04-12
      相关资源
      最近更新 更多