这是一个非常不寻常的问题。我只是为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";
httpcomponents
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;
}
}
}
HttpURLConnection类:
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;
}
}
}
答案 0 :(得分:0)
我通过删除
来解决问题更加奇怪conn.setChunkedStreamingMode(0);
只需替换代码:
conn.setDoOutput(true);
conn.setChunkedStreamingMode(0);
到
conn.setRequestMethod("POST");
conn.setDoOutput(true);
然而在Android文档中,据说是
为获得最佳性能,您应该致电 setFixedLengthStreamingMode(int)当身体长度已知时 advance,或者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();
我发现我的网址没有被重定向。所以我猜这个问题不是因为重定向。
所以这是新问题。我可以删除代码
conn.setChunkedStreamingMode(0)
但是这不是建议并且花费更多的内存消耗,如果缓冲区太大,可能会导致我的应用程序崩溃。
有什么想法吗?
=============================================== ==============
我发现虽然setChunkedStreamingMode()在我的情况下不能使用,但setFixedLengthStreamingMode()工作正常。
所以我使用setFixedLengthStreamingMode(),现在一切正常。 仍然想知道为什么setChunkedStreamingMode()在我自己的服务器中工作但不在webhostingpad.com的服务器中。