![](/img/trans.png)
[英]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.