[英]how to handle / read the response with “Transfer-Encoding:chunked”?
[英]How to read response using HttpsUrlconnection when transfer encoding is chunked
我正在编写一个内部使用HttpsUrlConnection调用另一个URL的servlet。 从servlet,我必须返回与从HttpsUrlConnection调用接收到的相同的响应和相同的响应标头。
为此,我正在使用getHeaderFields()
读取所有标头:将标头复制到我的servlet的Httpservletresponse对象中。
另外,在那之后我尝试使用connection.getErrorStream()
读取响应(这主要是在服务器返回状态> 400时发生),这就是为什么我使用getErrorStream的原因。 然后,我读取字节并将字节复制到我的Servlet的HttpServletResponse输出流中。
现在在某些情况下可以正常工作。
但是,当我使用连接调用的服务器返回的响应带有分块的Transfer Encoding时,那么当我调用Servlet API时,如果将响应和响应标头复制到Httpservlet响应,则它将返回错误的无效块编码。
在这种情况下,在日志中,我看到当我使用getHeaderFields读取标头时,看到的第一个标头是分块的传输编码,然后下一个标头名称为null,其值为HTTP 1/1。
另外,我看到的回应也不正确。
在这种情况下,如何从httpsurlconnection读取响应标头和响应主体,并从我的servlet中正确返回它们?
我在分块编码时遇到了类似的问题。 与您不同的是,我的servlet在内部使用HTTP而不是HTTPS。
我也使用一种方法来复制标题字段。 但是我提供了由servlet容器管理的标头列表,因此我不创建,复制或编辑它们:
private static final Set forbiddenCopyHeaders = new HashSet<>(Arrays.asList(new String[]{
"connection"
, "transfer-encoding"
, "content-length"
, "via"
, "x-forwarded-for"
, "x-forwarded-host"
, "x-forwarded-server"
}));
这些是我用于复制响应头的方法:
private void copyResponseHeaders(CloseableHttpResponse internResponse, HttpServletResponse response)
{
Header[] headers = internResponse.getAllHeaders();
Header[] connHeaders = internResponse.getHeaders("connection");
StringBuilder connectionValue = new StringBuilder();
for (Header connHeader : connHeaders)
{
connectionValue.append(connHeader.getValue()).append(", ");
}
for (Header header : headers)
{
String headerName = header.getName();
boolean copyAllowed = !forbiddenCopyHeaders.contains(headerName.toLowerCase())
&& !StringUtils.containsIgnoreCase(connectionValue.toString(), headerName);
if (copyAllowed)
{
if (response.containsHeader(headerName))
{
response.addHeader(headerName, header.getValue());
}
else
{
response.setHeader(headerName, header.getValue());
}
}
}
setViaHeader(internResponse, response);
}
方法setViaHeader():
private void setViaHeader(CloseableHttpResponse response, HttpServletResponse customerResponse)
{
String serverHostName = "companyServer";
try
{
serverHostName = InetAddress.getLocalHost().getHostName();
}
catch (UnknownHostException e)
{
logger.error("für den VIA-Header kann der Hostname nicht ermittelt werden", e);
System.err.println("für den VIA-Header kann der Hostname nicht ermittelt werden: " +
ExceptionUtils.getStackTrace(e));
}
Header[] originalViaHeaders = response.getHeaders("via");
StringBuilder via = new StringBuilder("");
if ((originalViaHeaders != null) && (originalViaHeaders.length > 0))
{
for (Header viaHeader : originalViaHeaders)
{
via.append(viaHeader.getValue()).append(", ");
}
}
via.append(response.getStatusLine().getProtocolVersion().toString()).append(" ").append(serverHostName);
customerResponse.setHeader("via", via.toString());
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.