当前位置: 首页 > 知识库问答 >
问题:

泽西/JAX-RS:在响应标头中返回Content-Llong而不是分块传输编码

费明诚
2023-03-14

我正在使用泽西创建RESTful API资源,并使用响应生成器生成响应。

RESTful资源的示例代码:

public class infoResource{
  @GET
  @Path("service/{id}")
  @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
  public Response getCompany(@PathParam("id")String id) {
      //company is just a POJO.
      Company company = getCompany(id);
      return Response.status(200).entity(company).build();  
  }
}

在响应中,它在响应头中返回分块传输编码。在“Jersey world”中,让它返回内容长度标题而不是响应标题中的传输编码:分块标题的正确方式是什么?

共有3个答案

颜欣怡
2023-03-14

例如,如果您的inputstream是从本地文件系统读取的,只需添加

response.header( "Content-Length", file.length() );

检查完整代码以获得更清晰的解释:

@Path("/files")
public class FileDownloadService {

    private static final String TXT_FILE = "C:\\your file";    
    @GET
    @Path("/txt")
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    public Response getTextFile() throws IOException {
        File file = new File(TXT_FILE);
        FileInputStream inStream = new FileInputStream(file);
        ResponseBuilder response = Response.ok((Object) inStream);
        response.header("Content-Disposition", "attachment; filename=\"filename\"");
        response.header( "Content-Length", file.length() );
        return response.build();
    }  
}

客户端是Apache HttpClient代码。

谭刚毅
2023-03-14

在扩展ResourceConfig的类中,可以设置缓冲区大小。大于此大小的响应将分块,小于此大小的响应将具有内容长度。

public class ApplicationConfig extends ResourceConfig {

  public ApplicationConfig() {
    //your initialization
    property(CommonProperties.OUTBOUND_CONTENT_LENGTH_BUFFER, 2000000); 
  }
}
董俊晖
2023-03-14

选择内容长度或传输编码就是这些容器的选择。这实际上是缓冲区大小的问题。

一种可能的解决方案是提供一个SevletFilter,它缓冲所有编组的字节并设置内容长度头值。

请参阅此页面。

@WebFilter
public class BufferFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) {
    }

    @Override
    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain chain)
        throws IOException, ServletException {

        final ByteArrayOutputStream buffer =
            new ByteArrayOutputStream();

        // prepare a new ServletResponseWrapper
        // which returns the buffer as its getOutputStream();

        chain.doFilter(...)

        // now you know how exactly big is your response.

        final byte[] responseBytes = buffer.toByteArray();
        response.setContentLength(responseBytes.length);
        response.getOutputStream().write(responseBytes);
        response.flush();
    }

    @Override
    public void destroy() {
    }
}
 类似资料:
  • 我正在进行一个示例项目,使用: JAX-RS(泽西2) JSR-303 Bean validaiton 泽西测试测试 Grizzly Http容器 杰克逊2.7.3 在添加@JsonIgnore和@JsonProperty之前,一切都按预期进行,在对对象属性执行bean验证时,我能够毫无问题地运行测试。通常情况下,“password”字段不应用于反序列化,所以我用@JsonIgnore标记了它的g

  • 我有一个正在运行的Web服务,它将被客户端移动应用程序使用。其中一项服务是返回一个JSON对象数组(超过1000个对象),每个对象都有相当大的大小。服务器端的整个计算需要一些时间,这不是一个好的用户体验。所以我希望以块的形式发送数据,例如每个块10个对象,这样这些数据就会占据屏幕,当他滚动时,或者当数据准备好时,屏幕上充满了从最新收到的块中新获取的数据。 我使用Jersey框架并发送一个Java<

  • 我试图将资源的实例注入具有Singleton作用域的JAX-RS应用程序,但当我这样做时,我得到: 警告:在服务器运行时中注册的提供程序com.test.jersey.app.MyResource未实现任何适用于服务器运行时的提供程序接口。由于约束配置问题,将忽略提供程序com.test.jersey.app.MyResource。 我有一个如下的应用程序,它需要一个已经运行的MyResource

  • 我正在迁移一个遗留服务框架,该框架使用java序列化/反射来注册服务,并将它们作为远程endpoint(javabin over http)或本地调用无缝地调用。我已经将远程调用替换为jerseyendpoint。并使用基于hk2 aop的拦截器重新构建了现有框架的部分拦截能力。当远程客户端调用endpoint时,它工作正常。现在,我需要对服务方法的本地调用执行相同的操作,并且能够使用与远程服务方

  • 我使用这个代码来调用泽西客户端的泽西JAX-RS服务。 当响应状态代码为 200 时,此代码工作正常。但对于 200 以外的任何内容,此代码会引发异常。 如何修改此代码,以便根据响应的状态代码执行某些操作?

  • 我使用SpringWebFlux反应式库创建了大量RESTAPIendpoint。我现在面临的问题是,SpringWebFlux返回的响应具有传输编码:分块HTTP头。因为哪个客户端应用程序使用像Axios这样的库(https://github.com/axios/axios)浏览器javascript中基于promise的HTTP客户端失败。如何关闭传输编码:分块? Spring webflux