我有一门课名为: ServiceCaller.java
该类包含一个用于调用web服务的方法:
public static Response callService(String strURL, String Token, int timeout, Boolean isPostMethod) {
String error = "";
int statusCode = HttpStatus.SC_INTERNAL_SERVER_ERROR;
HttpURLConnection urlConnection = null;
try
{
URL url = new URL(strURL);
// Allow non trusted ssl certificates
if(strURL.startsWith("https"))
{
TrustManagerManipulator.allowAllSSL();
}
urlConnection = (HttpURLConnection) url.openConnection();
if (isPostMethod) {
urlConnection.setRequestMethod("POST");
}
else {
urlConnection.setRequestMethod("GET");
}
// Allow Inputs
urlConnection.setDoInput(true);
// Allow Outputs
urlConnection.setDoOutput(true);
// Don't use a cached copy.
urlConnection.setUseCaches(false);
urlConnection.setRequestProperty("Connection", "Keep-Alive");
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Token", Helpers.getUTF8Encode(Token));
urlConnection.setConnectTimeout(timeout);
DataOutputStream dos = new DataOutputStream(urlConnection.getOutputStream());
dos.flush();
dos.close();
statusCode = urlConnection.getResponseCode();
Response r = new Response(statusCode, urlConnection.getInputStream(), "No Exception");
return r;
} catch (Exception ex) {
error = ex.getMessage();
if (error != null && !error.equals("") && error.contains("401"))
statusCode = HttpStatus.SC_UNAUTHORIZED;
} finally {
urlConnection.disconnect();
}
return new Response(statusCode, null, error);
}下面是响应类:
public static class Response
{
private int statusCode;
private InputStream responseStream;
private String exception;
public int getStatusCode() {
return statusCode;
}
public InputStream getResponseStream() {
return responseStream;
}
public String getExceptionError() {
return exception;
}
public Response(int code, InputStream stream, String strException)
{
this.statusCode = code;
this.responseStream = stream;
this.exception = strException;
}
}这是我用来测试ServiceCaller中函数的测试类:
public class TestDemo {
private static final String EncriptionKey = "keyValueToUse";
public static void main(String[] args) {
try {
String strURL = "http://...";
String strURL2 = "http://...";
String Token = "iTcakW5...";
int timeout = 120000;
Boolean isPostMethod = true;
ServiceCaller.Response resp = ServiceCaller.CallService(strURL2, Token, timeout, isPostMethod);
InputStream inputStream = resp.getResponseStream();
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer);
String resultJSON = writer.toString();
System.out.println("Status Code: " + resp.getStatusCode());
System.out.println("JSON String:\n" + resultJSON);
System.out.println("Exception: " + resp.getExceptionError());
} catch (Exception e) {
e.printStackTrace();
}
}
}下面是执行hte前一段代码的输出:
Status Code: 200
JSON String:
Exception: No Exception问题是,测试类中返回的InputString似乎是空的,因为对字符串的转换返回一个空字符串,但是如果我在CallService函数中执行相同的代码来转换InputString,则转换是成功的,还请注意,状态代码和异常(字符串)正在正确返回。
发布于 2013-10-03 20:57:00
public static Response CallService(String strURL, String Token, int timeout, Boolean isPostMethod) {
HttpURLConnection urlConnection = ...
...
new Response(statusCode, urlConnection.getInputStream(), "No Exception");
}这个代码丢失在..。可能是最重要的部分。在返回到调用方之前,我猜您正在关闭HttpURLConnection。您如何做到这一点可能会有所不同:
return之前关闭它。try-with-resource结构,HttpURLConnection可能会自动关闭。这是不太可能的,因为HttpURLConnection没有实现AutoClosable。发布于 2013-10-04 18:07:47
我首先从InputStream中获取HttpURLConnection,然后将其转换为字节数组,然后将该字节数组放入ByteArrayInputStream中,从而解决了问题
byte[] bytes = IOUtils.toByteArray(urlConnection.getInputStream());
ByteArrayInputStream byteStream = new ByteArrayInputStream(bytes);
return new Response(statusCode, byteStream, "");根据文档,ByteArrayInputStream:
公共ByteArrayInputStream(byte[] buf)创建一个ByteArrayInputStream,以便使用buf作为其缓冲区数组。缓冲区数组未被复制。pos的初始值为0,计数的初始值为buf的长度。参数: buf -输入缓冲区。
发布于 2013-10-04 13:35:41
问题在于您已经在使用InputStream方法中的CallService方法。
statusCode = urlConnection.getResponseCode();
Response resp = new Response(statusCode, urlConnection.getInputStream(), "");
InputStream inputStream = resp.getResponseStream();
StringWriter writer = new StringWriter();
IOUtils.copy(inputStream, writer); // consuming the stream
String resultJSON = writer.toString(); // you never use this, so why is it here?因此,当您尝试在main()中再次读取它时,就没有剩下的字节了。
您只能从其中读取一次字节。
这不会引发任何异常,因为IOUtils只调用InputStream#read(...),如果到达EOF,则返回-1。
注意,Java命名约定规定方法名称应该以小写字符开头。
https://stackoverflow.com/questions/19168876
复制相似问题