0

これは非常に珍しい問題です。httpcomponents と httpurlconnection のテストを作成するだけです。どちらも 3 つのキーと値の文字列ペアを php ファイルに投稿すると、php は 3 つの文字列を結合して戻ります。両方のテストは、仮想マシンの Debian Linux である私自身の Linux サーバーで正常に動作します。ただし、webhostingpad.com によってホストされている自分のサイトに php ファイルをアップロードすると、httpcomponents テストのみが機能します。httpurlconnection の場合、エラー コードとして 403 禁止されます。

誰が私が何をすべきかヒントを持っていますか?

ここに私のファイルがあります:

<?php
$s1 = $_POST['s1'];
$s2 = $_POST['s2'];
$s3 = $_POST['s3'];

echo "$s1 $s2$s3";

httpコンポーネント

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new HttpPostTask().execute();
    }

    public class HttpDealing {
        public void post() throws UnknownHostException, IOException, HttpException {
            HttpParams params = new SyncBasicHttpParams();
            HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(params, "UTF-8");
            HttpProtocolParams.setUserAgent(params, "Test/1.1");
            HttpProtocolParams.setUseExpectContinue(params, true);

            HttpProcessor httpproc = new ImmutableHttpProcessor(new HttpRequestInterceptor[] {
                    // Required protocol interceptors
                    new RequestContent(),
                    new RequestTargetHost(),
                    // Recommended protocol interceptors
                    new RequestConnControl(),
                    new RequestUserAgent(),
                    new RequestExpectContinue()});

            HttpRequestExecutor httpexecutor = new HttpRequestExecutor();

            HttpContext context = new BasicHttpContext(null);

            HttpHost host = new HttpHost("192.168.1.107", 80);

            DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
            ConnectionReuseStrategy connStrategy = new DefaultConnectionReuseStrategy();

            context.setAttribute(ExecutionContext.HTTP_CONNECTION, conn);
            context.setAttribute(ExecutionContext.HTTP_TARGET_HOST, host);

            System.out.println("user-agent is " + context.getAttribute("User-Agent"));
            System.out.println("content-type is " + context.getAttribute("Content-Type"));

            try {

                List<NameValuePair> text_list = new ArrayList<NameValuePair>();  
                text_list.add(new BasicNameValuePair("s1", "Good"));  
                text_list.add(new BasicNameValuePair("s2", "idea"));  
                text_list.add(new BasicNameValuePair("s3", "!"));
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(text_list, "utf-8");

                if (!conn.isOpen()) {
                    Socket socket = new Socket(host.getHostName(), host.getPort());
                    conn.bind(socket, params);
                }
                BasicHttpEntityEnclosingRequest request = new BasicHttpEntityEnclosingRequest("POST",
                        "/test_name_post.php");
                request.setEntity(entity);
                System.out.println(">> Request URI: " + request.getRequestLine().getUri());

                request.setParams(params);
                httpexecutor.preProcess(request, httpproc, context);
                HttpResponse response = httpexecutor.execute(request, conn, context);
                response.setParams(params);
                httpexecutor.postProcess(response, httpproc, context);

                System.out.println("<< Response: " + response.getStatusLine());
                System.out.println(EntityUtils.toString(response.getEntity()));
                System.out.println("==============");
                if (!connStrategy.keepAlive(response, context)) {
                    conn.close();
                } else {
                    System.out.println("Connection kept alive...");
                }
            } finally {
                conn.close();
            }
        }
    }

    private class HttpPostTask extends AsyncTask<Void, Void, String> {
        protected String doInBackground (Void... v) {

            HttpDealing http_dealing = new HttpDealing();
            try {
                http_dealing.post();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (HttpException e) {
                e.printStackTrace();
            }

            return null;
        }
    }

}

httpurl接続:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        new HttpPostTask().execute();
    }

    public class HttpDealing {
        public void post() throws IOException {
            URL url = new URL("http://192.168.1.107/test_name_post.php");
            System.out.println("url is " + url.toString());

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            //conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setChunkedStreamingMode(0);

            List<AbstractMap.SimpleEntry<String, String>> params = new ArrayList<AbstractMap.SimpleEntry<String, String>>();
            params.add(new AbstractMap.SimpleEntry<String, String>("s1", "Good"));
            params.add(new AbstractMap.SimpleEntry<String, String>("s2", "idea"));
            params.add(new AbstractMap.SimpleEntry<String, String>("s3", "!"));

            OutputStream os = conn.getOutputStream();
            BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(os, "utf-8"));
            writer.write(getQuery(params));
            writer.flush();
            writer.close();
            os.close();

            System.out.println("user agent is " + conn.getRequestProperty("User-Agent"));
            System.out.println("content type is " + conn.getRequestProperty("Content-Type"));

            conn.connect();

            System.out.println("response code is " + conn.getResponseCode());

            try {
                InputStream in;
                if (conn.getResponseCode() == HttpURLConnection.HTTP_FORBIDDEN) 
                    in = new BufferedInputStream(conn.getErrorStream());
                else 
                    in = new BufferedInputStream(conn.getInputStream());

                System.out.println("result is " + readStream(in));
            } finally {
                conn.disconnect();
            }
        }


        private String getQuery(List<AbstractMap.SimpleEntry<String, String>> params) throws UnsupportedEncodingException
        {
            StringBuilder result = new StringBuilder();
            boolean first = true;

            for (AbstractMap.SimpleEntry<String, String> pair : params)
            {
                if (first)
                    first = false;
                else
                    result.append("&");

                result.append(URLEncoder.encode(pair.getKey(), "utf-8"));
                result.append("=");
                result.append(URLEncoder.encode(pair.getValue(), "utf-8"));
            }

            return result.toString();
        }

        private String readStream(InputStream in) throws IOException {
            String result = "";
            InputStreamReader reader = new InputStreamReader(in, "utf-8");
            char[] buffer = new char[5];
            int count = 0;

            while ((count = reader.read(buffer)) != -1) 
                result += new String(buffer, 0, count);

            return TextUtils.isEmpty(result) ? null : result;
        }
    }

    private class HttpPostTask extends AsyncTask<Void, Void, String> {
        protected String doInBackground(Void... v) {
            HttpDealing http_dealing = new HttpDealing();
            try {
                http_dealing.post();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return null;
        }
    }

}
4

1 に答える 1

0

削除して問題を解決したのはさらに奇妙です

conn.setChunkedStreamingMode(0);

コードを置き換えるだけです:

conn.setDoOutput(true);
conn.setChunkedStreamingMode(0);

conn.setRequestMethod("POST");
conn.setDoOutput(true);

ただし、Androidのドキュメントでは、

最高のパフォーマンスを得るには、本体の長さが事前にわかっている場合は setFixedLengthStreamingMode(int) を呼び出すか、そうでない場合は setChunkedStreamingMode(int) を呼び出す必要があります。そうしないと、HttpURLConnection は送信前に完全なリクエスト本文を強制的にメモリにバッファリングし、ヒープを浪費し (おそらく枯渇させ)、レイテンシーを増加させます。

したがって、これを行うと利点が失われ、バッファが大きすぎるとアプリがクラッシュする可能性があります。なぜこれが起こるのか分かりますか?

また、phpinfo() で、Apache に私のドメインの IP ではないリモート アドレスがあることに気付きました。それが問題の原因ですか?

setChunkedStreamingMode については、Java Doc に記載されています。

出力ストリーミングが有効になっている場合、認証とリダイレクトを自動的に処理することはできません。認証またはリダイレクトが必要な場合、応答を読み取るときに HttpRetryException がスローされます。この例外は、エラーの詳細について照会できます。

したがって、リダイレクトを手動で処理する必要があります。ただし、hereのコードを使用します。

URLConnection con = new URL( url ).openConnection();
System.out.println( "orignal url: " + con.getURL() );
con.connect();
System.out.println( "connected url: " + con.getURL() );
InputStream is = con.getInputStream();
System.out.println( "redirected url: " + con.getURL() );
is.close();

URL がリダイレクトされていないことがわかりました。したがって、問題はリダイレクトによるものではないと思います。

そこで新たな問題が。コードを削除できます

conn.setChunkedStreamingMode(0)

しかし、それは推奨されておらず、メモリの消費量が多くなり、バッファが大きすぎるとアプリがクラッシュする可能性があります。

何か案は?

================================================== ===========

私の場合、 setChunkedStreamingMode() は使用できませんが、 setFixedLengthStreamingMode() は正常に機能することがわかりました。

だから私は setFixedLengthStreamingMode() を使用し、すべてが正常に動作するようになりました。setChunkedStreamingMode() が自分のサーバーでは機能するのに、webhostingpad.com のサーバーでは機能しないのはなぜなのか、まだ疑問に思っています。

于 2013-08-01T11:47:31.263 に答える