Android HttpURLConnection setRequestMethod PUT
Android HttpURLConnection setRequestMethod PUT
我正在尝试使用 HttpURLConnection 将 Android 应用程序连接到 restful 服务器。 GET 请求成功但 PUT 请求不成功。每个 PUT 请求都作为 GET 请求到达服务器。
@Override
protected Boolean doInBackground(Method... params) {
Boolean result = false;
try {
URL url = new URL("http://server.com/api");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
switch (params[0]) {
case PUT:
connection.setDoOutput(true);
connection.setRequestMethod("PUT");
Log.d(TAG, "Method: " + connection.getRequestMethod()); // Correctly "Method: PUT"
OutputStreamWriter out = new OutputStreamWriter(
connection.getOutputStream());
out.write("Message");
out.close();
break;
case GET:
connection.setRequestMethod("GET");
connection.connect();
break;
default:
connection.setRequestMethod("GET");
connection.connect();
break;
}
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream in = connection.getInputStream();
JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("state")) {
result = true;
if (reader.nextInt() == 1) {
state = true;
Log.d(TAG, "state: 1");
} else {
state = false;
Log.d(TAG, "state: -1");
}
} else if (name.equals("method")) {
method = reader.nextString(); // Server respone is "Method: GET"
}
}
reader.endObject();
in.close();
} else {
Log.d(TAG, "Connection failed");
}
connection.disconnect();
} catch (Exception e) {
Log.e("Exception", e.toString());
e.printStackTrace();
}
return result;
}
请求方法在 connection.connect();
之前正确设置为 PUT。我错过了什么?我不想发送数据。 PUT 请求更改计数器,因此不需要数据。
相同的功能在 Javascript 和 JQuery 的网络前端中实现并且有效
$.ajax({
url: '/api',
method: 'PUT'
});
编辑:
可能是服务器的问题。目前我正在使用 php 文件
<?php
echo(var_dump($_SERVER)); // ["REQUEST_METHOD"]=> string(3) "GET"
function get ($db) {
$state = $db->querySingle('SELECT state FROM states WHERE name="main"');
echo('{"state": ' . $state . ', "method": "get"}');
}
function put ($db) {
$state = $db->querySingle('SELECT state FROM states WHERE name="main"');
$db->exec('UPDATE states SET state=' . ($state+1)%2 . ' WHERE name="main"');
$state = $db->querySingle('SELECT state FROM states WHERE name="main"');
echo('{"state": ' . $state . ', "method": "put"}');
}
if ($db = new SQLite3('database.sqlite')) {
switch($_SERVER['REQUEST_METHOD']){
case 'GET':
get($db);
break;
case 'PUT':
put($db);
break;
}
$db->close();
} else {
}
?>
我用 http://httpbin.org/put 试用了我的应用程序,它成功了。
我发现了问题。我必须在 url 后面附加一个斜杠,否则请求将被重定向并转换为 GET 请求。我不太明白这个问题,但我找到了适合我的解决方案。
我要改
URL url = new URL("http://server.com/api");
到
URL url = new URL("http://server.com/api/");
现在可以了。也许有人可以向我解释。当我尝试用 curl
打开 http://server.com/api
时,我得到一个 303 redirect
到 http://server.com/api
。
我正在尝试使用 HttpURLConnection 将 Android 应用程序连接到 restful 服务器。 GET 请求成功但 PUT 请求不成功。每个 PUT 请求都作为 GET 请求到达服务器。
@Override
protected Boolean doInBackground(Method... params) {
Boolean result = false;
try {
URL url = new URL("http://server.com/api");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
switch (params[0]) {
case PUT:
connection.setDoOutput(true);
connection.setRequestMethod("PUT");
Log.d(TAG, "Method: " + connection.getRequestMethod()); // Correctly "Method: PUT"
OutputStreamWriter out = new OutputStreamWriter(
connection.getOutputStream());
out.write("Message");
out.close();
break;
case GET:
connection.setRequestMethod("GET");
connection.connect();
break;
default:
connection.setRequestMethod("GET");
connection.connect();
break;
}
if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream in = connection.getInputStream();
JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("state")) {
result = true;
if (reader.nextInt() == 1) {
state = true;
Log.d(TAG, "state: 1");
} else {
state = false;
Log.d(TAG, "state: -1");
}
} else if (name.equals("method")) {
method = reader.nextString(); // Server respone is "Method: GET"
}
}
reader.endObject();
in.close();
} else {
Log.d(TAG, "Connection failed");
}
connection.disconnect();
} catch (Exception e) {
Log.e("Exception", e.toString());
e.printStackTrace();
}
return result;
}
请求方法在 connection.connect();
之前正确设置为 PUT。我错过了什么?我不想发送数据。 PUT 请求更改计数器,因此不需要数据。
相同的功能在 Javascript 和 JQuery 的网络前端中实现并且有效
$.ajax({
url: '/api',
method: 'PUT'
});
编辑: 可能是服务器的问题。目前我正在使用 php 文件
<?php
echo(var_dump($_SERVER)); // ["REQUEST_METHOD"]=> string(3) "GET"
function get ($db) {
$state = $db->querySingle('SELECT state FROM states WHERE name="main"');
echo('{"state": ' . $state . ', "method": "get"}');
}
function put ($db) {
$state = $db->querySingle('SELECT state FROM states WHERE name="main"');
$db->exec('UPDATE states SET state=' . ($state+1)%2 . ' WHERE name="main"');
$state = $db->querySingle('SELECT state FROM states WHERE name="main"');
echo('{"state": ' . $state . ', "method": "put"}');
}
if ($db = new SQLite3('database.sqlite')) {
switch($_SERVER['REQUEST_METHOD']){
case 'GET':
get($db);
break;
case 'PUT':
put($db);
break;
}
$db->close();
} else {
}
?>
我用 http://httpbin.org/put 试用了我的应用程序,它成功了。
我发现了问题。我必须在 url 后面附加一个斜杠,否则请求将被重定向并转换为 GET 请求。我不太明白这个问题,但我找到了适合我的解决方案。
我要改
URL url = new URL("http://server.com/api");
到
URL url = new URL("http://server.com/api/");
现在可以了。也许有人可以向我解释。当我尝试用 curl
打开 http://server.com/api
时,我得到一个 303 redirect
到 http://server.com/api
。