我该如何修复“java.io.IOException:No socket to write;was a POST cac



偶尔当我在Android Gingerbread(操作系统2.3.3)上运行我的应用程序时,我在logcat中会收到这样的警告:

java.io.IOException: No socket to write to; was a POST cached?
at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:618)
at com.voices.voices.webservice.WebService$WebServiceAsyncTask.downloadUrl(WebService.java:1705)
at com.voices.voices.webservice.WebService$WebServiceAsyncTask.doInBackground(WebService.java:1615)
at com.voices.voices.webservice.WebService$WebServiceAsyncTask.doInBackground(WebService.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:185)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
at java.lang.Thread.run(Thread.java:1019)

并且该调用的HttpUrlConnection失败。一般来说,此调用工作正常,但偶尔会失败。当在安卓操作系统>2.3.3上运行时,它似乎可以在没有这个问题的情况下工作。

问题是它为什么会失败,我应该如何解决这个问题?

以下是一些附加信息:

Webservice.java 第1705行

dataStream = new DataOutputStream(conn.getOutputStream());

错误前几行:

...
            HttpURLConnection conn = null;
            DataOutputStream dataStream = null;

            //SETS COOKIE This should avoid the "Too many redirects issue" because It's apparently redirecting in an infinite loop because it's not maintain the user session.
            CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));

            if( webServiceUrl.contains("https") ){
                TrustManager[] trustAllCerts = new TrustManager[]{
                         new X509TrustManager() {
                             public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                                 return null;
                                 }
                             public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) {
                                 }
                             public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) {
                             }
                         }
                 }; // Install the all-trusting trust manager
                 try {
                     SSLContext sc = SSLContext.getInstance("TLS");
                     sc.init(null, trustAllCerts, new java.security.SecureRandom());
                     HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
                     }
                 catch (Exception e) {
                     //L.l("TRUST MANAGER EXCEPTION");
                 }
            }
            try {
                responseInputStream = null;
                System.setProperty("http.keepAlive", "false");
                URL url = new URL(webServiceUrl);
                conn = (HttpURLConnection) url.openConnection();
                conn.setReadTimeout(Constants.CONNECTION_TIMEOUT_MILLISECONDS /* milliseconds */);
                conn.setConnectTimeout(Constants.CONNECTION_TIMEOUT_MILLISECONDS /* milliseconds */);
                conn.setDoOutput(true);
                conn.setDoInput(true);
                conn.setDefaultUseCaches(false);
                if( useMultipart ){
                    conn.setRequestProperty("Content-Type", "multipart/form-data; boundary="+ Constants.MULTIPART_BOUNDARY);
                } else {
                    conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                }
                conn.setRequestProperty("Cache-Control", "no-cache");
                conn.connect();
                // DATA STREAM
                dataStream = new DataOutputStream(conn.getOutputStream());
  ...

我不确定这是否会有帮助,但在Android的HttpURLConnectionImpl.java文件中,这就是错误发生的地方

@Override
public OutputStream getOutputStream() throws IOException {
    if (!doOutput) {
        throw new ProtocolException("Does not support output");
    }
    // you can't write after you read
    if (sentRequestHeaders) {
        // TODO: just return 'requestBodyOut' if that's non-null?
        throw new ProtocolException(
                "OutputStream unavailable because request headers have already been sent!");
    }
    if (requestBodyOut != null) {
        return requestBodyOut;
    }
    // they are requesting a stream to write to. This implies a POST method
    if (method == GET) {
        method = POST;
    }
    // If the request method is neither PUT or POST, then you're not writing
    if (method != PUT && method != POST) {
        throw new ProtocolException(method + " does not support writing");
    }
    int contentLength = -1;
    String contentLengthString = requestHeader.get("Content-Length");
    if (contentLengthString != null) {
        contentLength = Integer.parseInt(contentLengthString);
    }
    String encoding = requestHeader.get("Transfer-Encoding");
    if (chunkLength > 0 || "chunked".equalsIgnoreCase(encoding)) {
        sendChunked = true;
        contentLength = -1;
        if (chunkLength == -1) {
            chunkLength = DEFAULT_CHUNK_LENGTH;
        }
    }
    connect();
    if (socketOut == null) {
        // TODO: what should we do if a cached response exists?
        throw new IOException("No socket to write to; was a POST cached?");
    }

所以出于某种原因,socketOut==为null,非常奇怪。

如果你需要更多信息,请告诉我。

这可能不是最好的方法,但对我来说很有效。我只需要禁用httpURLConnection 上的缓存

conn.setDefaultUseCaches(false);
conn.setUseCaches(false);
conn.setRequestProperty("Expires", "-1");
conn.setRequestProperty("Cache-Control", "no-cache");

最新更新