在服务端返回 2XX 以外的 HTTP 响应码时,HttpURLConnection 该怎样拿到 response body?
和 webservice 供应商联调 saop 接口时遇到一个问题:服务商所有业务逻辑错误 (包括用户名密码、逻辑校验、请求数据为空等等) 都返回 HTTP 状态码 500 而不是状态码 200,同时错误码及详情在返回 body 中给出。
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setConnectTimeout(Integer.valueOf(wsConnectTimeout));
conn.setReadTimeout(Integer.valueOf(wsRequestTimeout));
conn.setRequestProperty("Content-Type", "text/xml;charset=utf-8");
conn.setRequestProperty("Content-Length", String.valueOf(message.length()));
conn.setRequestProperty("SOAPAction", wsURL);
OutputStream os = conn.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(os, "utf-8");
writer.write(message);
writer.flush();
writer.close();
reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
上述对接代码在执行到最后一行时会抛以下异常:
java.io.IOException: Server returned HTTP response code: 500 for URL: https://gpm-test.defonds.com/rrc/soap/v1 at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1626) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254) at com.defonds.als.server.tools.interfaces.standard.gpm.WSClientGPMManagerImpl.gpmCostRateWebservice(WSClientGPMManagerImpl.java:1376) |
异常当然容易捕捉,但是服务商返回的错误详细错误原因就丢失了。
那么怎么样才可以从 response body 中拿到错误详细信息呢?用 onn.getInputStream() 已经抛错了,再用还是 500。
当状态码不是 2XX 时,要用 getErrorStream() 来读取响应体里的内容,在捕捉到 500 IO 异常之后进行以下处理:
try {
// Since webservice returns 500 for any logic error, we get their error message from the error stream
if (500 == conn.getResponseCode()) {
reader = new BufferedReader(new InputStreamReader(conn.getErrorStream(), "utf-8"));
String line = null;
while ((line = reader.readLine()) != null) {
result += line;
}
reader.close();
dealWith500LogicError(result, errorMsg);
}
}catch (Exception e2) {
logger.logError(e2.toString());
}
dealWith500LogicError 是负责错误文本解析的方法。
参考资料
Class HttpURLConnection
How to get response body using HttpURLConnection, when code other than 2xx is returned?