0

这是一个非常不寻常的问题。我只是为httpcomponents和httpurlconnection编写了一个测试,两者都将3个键值字符串对发布到一个php文件中,php会将3个字符串组合在一起并返回。这两个测试都在我自己的 linux 服务器上运行良好,这是一个虚拟机中的 Debian Linux。但是,当我将 php 文件上传到由 webhostingpad.com 托管的网站时,只有 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。可以查询此异常以获取错误的详细信息。

所以我需要手动处理重定向。但是,使用此处的代码。

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();

我发现我的网址没有被重定向。所以我猜这个问题不是因为重定向。

所以这是新的问题。我可以删除代码

conn.setChunkedStreamingMode(0)

但这是不推荐的,并且会消耗更多的内存,如果缓冲区太大,可能会导致我的应用程序崩溃。

有任何想法吗?

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

我发现虽然 setChunkedStreamingMode() 在我的情况下不能使用,但 setFixedLengthStreamingMode() 工作正常。

所以我使用 setFixedLengthStreamingMode() 并且现在一切正常。仍然想知道为什么 setChunkedStreamingMode() 在我自己的服务器中有效,但在 webhostingpad.com 的服务器中无效。

于 2013-08-01T11:47:31.263 回答