首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >InputStream丢失

InputStream丢失
EN

Stack Overflow用户
提问于 2013-10-03 20:42:16
回答 3查看 1.6K关注 0票数 1

我有一门课名为: ServiceCaller.java

该类包含一个用于调用web服务的方法:

代码语言:javascript
复制
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);

}

下面是响应类:

代码语言:javascript
复制
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中函数的测试类:

代码语言:javascript
复制
    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前一段代码的输出:

代码语言:javascript
复制
Status Code: 200
JSON String:

Exception: No Exception

问题是,测试类中返回的InputString似乎是空的,因为对字符串的转换返回一个空字符串,但是如果我在CallService函数中执行相同的代码来转换InputString,则转换是成功的,还请注意,状态代码和异常(字符串)正在正确返回。

EN

回答 3

Stack Overflow用户

发布于 2013-10-03 20:57:00

代码语言:javascript
复制
public static Response CallService(String strURL, String Token, int timeout, Boolean isPostMethod) {

     HttpURLConnection urlConnection = ...

     ...

     new Response(statusCode, urlConnection.getInputStream(), "No Exception");
}

这个代码丢失在..。可能是最重要的部分。在返回到调用方之前,我猜您正在关闭HttpURLConnection。您如何做到这一点可能会有所不同:

  • 您只需在return之前关闭它。
  • 尝试-抓住-最后:你要关闭它在最后的块。
  • 您使用的是Java7中介绍的try-with-resource结构,HttpURLConnection可能会自动关闭。这是不太可能的,因为HttpURLConnection没有实现AutoClosable。
票数 1
EN

Stack Overflow用户

发布于 2013-10-04 18:07:47

我首先从InputStream中获取HttpURLConnection,然后将其转换为字节数组,然后将该字节数组放入ByteArrayInputStream中,从而解决了问题

代码语言:javascript
复制
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 -输入缓冲区。

票数 1
EN

Stack Overflow用户

发布于 2013-10-04 13:35:41

问题在于您已经在使用InputStream方法中的CallService方法。

代码语言:javascript
复制
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命名约定规定方法名称应该以小写字符开头。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19168876

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档