我正在使用Jersey创建RESTful API资源,并使用ResponseBuilder
来生成响应。
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();
}
}
在响应中,它在响应头中返回分块传输编码。 “泽西世界”中有什么方法让它在响应头中返回Content-Length
标题而不是Transfer-Encoding: chunked
标题?
答案 0 :(得分:5)
选择Content-Length
或Transfer-Encoding
只是容器的选择。这实际上是缓冲区大小的问题。
一种可能的解决方案是提供SevletFilter
缓冲所有那些编组的字节并设置Content-Length
标头值。
请参阅this page。
@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() {
}
}
答案 1 :(得分:3)
在扩展ResourceConfig的类中,您可以设置缓冲区大小。超过此大小的回复将被分块,下面将有Content-Length。
public class ApplicationConfig extends ResourceConfig {
public ApplicationConfig() {
//your initialization
property(CommonProperties.OUTBOUND_CONTENT_LENGTH_BUFFER, 2000000);
}
}
答案 2 :(得分:2)
例如,如果您的输入流是从本地文件系统读取的,那么就是 添加:
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代码。
答案 3 :(得分:0)
StackOverflow上一个非常相似的问题的答案可以be found here
我在这里复制它以确保它没有转换为注释:
用于执行此操作的优秀示例过滤器,可以从项目中单独使用,来自github上this ContentLengthFilter.java项目的Carrot2。
请注意,使用带有字节流的响应包装器来解决问题,因此这也可以确保过滤器链中的某些其他过滤器/代码不会设置Transfer-Encoding: Chunked
,并覆盖您的{{1它设置时的标题。您可以通过使用较大的文件对其进行测试来验证这一点,因为它们通常会在响应中进行分块。
我也会在这里复制文件的内容,以确保它不会成为断开的链接:
Content-Length