java - POST 请求 (HttpURLConnection) 的有趣问题 - 但为什么会发生这种情况呢?

标签 java android rest http post

所以我花了 6 个小时的时间,弄清楚了这个“小”事实: 如果不调用 client.getResponseCode(),则 POST 请求不会通过。

希望有人能解释一下原因! 具体来说,对于这个简约的 Android 客户端独立代码,如果没有 int status = client.getResponseCode(); 行,实际上什么都不会发生。 但有了它,一切都像魔法一样有效。 我没有找到任何关于此的官方文档,所以我想知道发生了什么,或者我不明白什么(实现Java的人通常做得很出色,所以可能是我没有得到一些东西:))。

public class MainActivity extends AppCompatActivity {

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

        final String theUrl = "http://xx.yyy.zz.aa:bb/securitiesFollowServer/users";
        final String TAG = getClass().getSimpleName();

        AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                String body = "BODY OF MESSAGE";

                HttpURLConnection client = null;
                BufferedWriter outputPost = null;

                try {
                    URL url = new URL(theUrl);

                    //  open the connection
                    client = (HttpURLConnection) url.openConnection();
                    client.setRequestProperty("content-type", "text/plain");
                    //client.setRequestMethod("POST"); Someone claimed that setDoOutput(true) works so I will try that instead (I tried both,mutually and exclusively so all 3 options).
                    client.setDoOutput(true);

                    outputPost = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
                    outputPost.write(body);
                    outputPost.flush();
                    outputPost.close();
                    int status = client.getResponseCode();
                    StackTraceElement[] r = Thread.currentThread().getStackTrace();
                    String toNotepad = "";
                    for (int i = 0; i < r.length; ++i) {
                        toNotepad += '\n' + String.valueOf(i) + '.' + ':' + r[i].toString();
                    }
                    // This is where I set a breakpoint and got the stacktrace value from toNotepad,and copy pasted it.
                } catch (IOException e) {
                    Log.e(TAG, "Error ", e);
                } finally {
                    if (client != null) {
                        client.disconnect();
                    }
                    if (outputPost != null) {
                        try {
                            outputPost.close();
                        } catch (IOException e) {
                            Log.e(TAG, "IO ERROR");
                        }
                    }

                    return null;
                }
            }
        };
        task.execute();
    }
}

为了问题的完整性,这里是“服务器端”简约代码

@POST
@Consumes(MediaType.TEXT_PLAIN)
@Produces(MediaType.TEXT_PLAIN)
public String setDebugResource(String a){
    return "I got this string:"+a;}

这是堆栈跟踪(我在上面的代码中很明显地复制粘贴了它的值):

不工作时(或工作时,它是完全相同的堆栈跟踪):

0.:dalvik.system.VMStack.getThreadStackTrace(Native Method)
1.:java.lang.Thread.getStackTrace(Thread.java:580)
2.:dor.only.dorking.android.apppostrequest.MainActivity$1.doInBackground(MainActivity.java:52)
3.:dor.only.dorking.android.apppostrequest.MainActivity$1.doInBackground(MainActivity.java:28)
4.:android.os.AsyncTask$2.call(AsyncTask.java:292)
5.:java.util.concurrent.FutureTask.run(FutureTask.java:237)
6.:android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
7.:java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
8.:java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
9.:java.lang.Thread.run(Thread.java:818)

最佳答案

根据HttpUrlConnection docs您必须在客户端对象上调用 setDoOutput(true),而不是将方法设置为 POST。通过此方法将自动设置为 POST。他们在“发布内容”部分下有一个示例。

有一个例子 here以及更大的讨论here

坦率地说,我会跳过使用原始 HttpUrlConnection 类并使用 Volley 之类的东西。

关于java - POST 请求 (HttpURLConnection) 的有趣问题 - 但为什么会发生这种情况呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37434241/

相关文章:

java - SharedPreferences 可以通过但不保存

java - 如何读取xml文件的内容到Jms队列

java - Java 中是否有双向循环链表的内置接口(interface)?

java - 单击按钮时更改 URL 图片

java - 无法从 START_OBJECT token 中反序列化 `java.lang.Boolean` 的实例

java - 创建 Rest Web 服务以接收图像

android - 解析 list 时解析错误

android - GetByteArrayRegion 导致 ArrayIndexOutOfBoundsException

java - 无论应用程序处于什么状态,都获取设备的位置始终从我的公司应用程序中检测位置

java - 如何从另一个 Rest 服务调用 HTTPS Rest 服务?