Java HttpUrlConnection发送POST请求并发送JSON数据

108

我已经开发了一段Java代码,可以使用URL和HttpUrlConnection将以下cURL转换为Java代码。

cURL如下:

curl -i 'http://url.com' -X POST -H "Content-Type: application/json" -H "Accept: application/json" -d '{"auth": { "passwordCredentials": {"username": "adm", "password": "pwd"},"tenantName":"adm"}}'

我已经写了这段代码,但它总是返回HTTP 400坏请求错误。我找不到缺少什么。

String url="http://url.com";
URL object=new URL(url);

HttpURLConnection con = (HttpURLConnection) object.openConnection();
con.setDoOutput(true);
con.setDoInput(true);
con.setRequestProperty("Content-Type", "application/json");
con.setRequestProperty("Accept", "application/json");
con.setRequestMethod("POST");

JSONObject cred   = new JSONObject();
JSONObject auth   = new JSONObject();
JSONObject parent = new JSONObject();

cred.put("username","adm");
cred.put("password", "pwd");

auth.put("tenantName", "adm");
auth.put("passwordCredentials", cred.toString());

parent.put("auth", auth.toString());

OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream());
wr.write(parent.toString());
wr.flush();

//display what returns the POST request

StringBuilder sb = new StringBuilder();  
int HttpResult = con.getResponseCode(); 
if (HttpResult == HttpURLConnection.HTTP_OK) {
    BufferedReader br = new BufferedReader(
            new InputStreamReader(con.getInputStream(), "utf-8"));
    String line = null;  
    while ((line = br.readLine()) != null) {  
        sb.append(line + "\n");  
    }
    br.close();
    System.out.println("" + sb.toString());  
} else {
    System.out.println(con.getResponseMessage());  
}  

6
Java语言冗长的表现很好地被描绘出来了。 - yurin
6个回答

170

您的JSON格式不正确。请改为

JSONObject cred = new JSONObject();
JSONObject auth=new JSONObject();
JSONObject parent=new JSONObject();
cred.put("username","adm");
cred.put("password", "pwd");
auth.put("tenantName", "adm");
auth.put("passwordCredentials", cred.toString()); // <-- toString()
parent.put("auth", auth.toString());              // <-- toString()

OutputStreamWriter wr= new OutputStreamWriter(con.getOutputStream());
wr.write(parent.toString());

写作

JSONObject cred = new JSONObject();
JSONObject auth=new JSONObject();
JSONObject parent=new JSONObject();
cred.put("username","adm");
cred.put("password", "pwd");
auth.put("tenantName", "adm");
auth.put("passwordCredentials", cred);
parent.put("auth", auth);

OutputStreamWriter wr= new OutputStreamWriter(con.getOutputStream());
wr.write(parent.toString());

因此,应该仅对外部对象调用一次JSONObject.toString()。

另一件事情(很可能不是你的问题,但我还是想提一下):

为确保不会遇到编码问题,如果编码不是UTF-8,则应该指定编码方式:

con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
con.setRequestProperty("Accept", "application/json");

// ...

OutputStream os = con.getOutputStream();
os.write(parent.toString().getBytes("UTF-8"));
os.close();

8
在我的情况下,设置请求属性的 content-type 是至关重要的:con.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); - Morey
什么都不起作用。我正在发送输入,但在API端收到的是空白。 - Adarsh Singh
byte[] outputBytes = rootJsonObject.getBytes("UTF-8"); OutputStream os = con.getOutputStream(); os.write(outputBytes);请将最后三行更改为以下内容:byte[] outputBytes = rootJsonObject.getBytes("UTF-8"); OutputStream os = con.getOutputStream(); os.write(outputBytes); - MrSalesi

39
private JSONObject uploadToServer() throws IOException, JSONException {
            String query = "https://example.com";
            String json = "{\"key\":1}";

            URL url = new URL(query);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setConnectTimeout(5000);
            conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setRequestMethod("POST");

            OutputStream os = conn.getOutputStream();
            os.write(json.getBytes("UTF-8"));
            os.close();

            // read the response
            InputStream in = new BufferedInputStream(conn.getInputStream());
            String result = org.apache.commons.io.IOUtils.toString(in, "UTF-8");
            JSONObject jsonObject = new JSONObject(result);


            in.close();
            conn.disconnect();

            return jsonObject;
    }

18
您可以使用此代码通过HTTP和JSON进行连接和请求。
try {
         
        URL url = new URL("https://www.googleapis.com/youtube/v3/playlistItems?part=snippet"
                + "&key="+key
                + "&access_token=" + access_token);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setDoOutput(true);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json");
 
        String input = "{ \"snippet\": {\"playlistId\": \"WL\",\"resourceId\": {\"videoId\": \""+videoId+"\",\"kind\": \"youtube#video\"},\"position\": 0}}";
 
        OutputStream os = conn.getOutputStream();
        os.write(input.getBytes());
        os.flush();
 
        if (conn.getResponseCode() != HttpURLConnection.HTTP_CREATED) {
            throw new RuntimeException("Failed : HTTP error code : "
                + conn.getResponseCode());
        }
 
        BufferedReader br = new BufferedReader(new InputStreamReader(
                (conn.getInputStream())));
 
        String output;
        System.out.println("Output from Server .... \n");
        while ((output = br.readLine()) != null) {
            System.out.println(output);
        }
 
        conn.disconnect();
 
      } catch (MalformedURLException e) {
 
        e.printStackTrace();
 
      } catch (IOException e) {
 
        e.printStackTrace();
 
     }

7

正确的答案是良好的,但是

OutputStreamWriter wr= new OutputStreamWriter(con.getOutputStream());
wr.write(parent.toString());
not work for me,改用使用
byte[] outputBytes = rootJsonObject.getBytes("UTF-8");
OutputStream os = con.getOutputStream();
os.write(outputBytes);

1
它没有运行成功是因为你忘记关闭OutputStreamWriter。 - Sujal Mandal

2

我遇到了类似的问题,使用PUT请求时始终返回400错误,而POST请求却完全正常。

以下代码对于POST请求很好用,但对于PUT请求会导致BAD Request错误:

conn.setRequestProperty("Content-Type", "application/json");
os.writeBytes(json);

在进行以下更改后,POST和PUT都正常工作了。
conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
os.write(json.getBytes("UTF-8"));

0

这里是完整的代码和解决方案

PostJSONWithHttpURLConnection.java 类

import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class PostJSONWithHttpURLConnection {
    String charset = "UTF-8";
    HttpURLConnection con;
    URL urlObj;
    JSONObject jObj = null;
    StringBuilder result;

    public JSONObject makeHttpRequest(String url,
                                      String paramsJSON) {
        try {
            urlObj = new URL(url);
            con = (HttpURLConnection) urlObj.openConnection();
            con.setRequestMethod("POST");
            con.setRequestProperty("Content-Type", "application/json; utf-8");
            con.setRequestProperty("Accept", "application/json");

            con.setDoOutput(true);
            con.setReadTimeout(60000);
            con.setConnectTimeout(60000);

            try (OutputStream os = con.getOutputStream()) {
                byte[] input = paramsJSON.getBytes(charset);
                os.write(input, 0, input.length);
            }

            int code = con.getResponseCode();
            Log.d("HTTP CODE", String.valueOf(code));
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            //Receive the response from the server
            InputStream in = new BufferedInputStream(con.getInputStream());
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            result = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                result.append(line);
            }

            Log.d("JSON Parser", "result: " + result.toString());

        } catch (IOException e) {
            e.printStackTrace();
        }

        con.disconnect();

        // try parse the string to a JSON object
        try {
            jObj = new JSONObject(result.toString());
        } catch (JSONException e) {
            Log.e("JSON Parser", "Error parsing data " + e.toString());
        }

        return jObj;
    }
}

在doInBackground(String... strArr)中使用代码

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
String writeValueAsString = objectMapper.writeValueAsString(jSONObject);   
PostJSONWithHttpURLConnection jsonPOST = new PostJSONWithHttpURLConnection();
JSONObject json = jsonPOST.makeHttpRequest(SERVER_ADDRESS + "YOUR_API", writeValueAsString);

jSONObject 是一个类似于 Json 的对象:

{
"Password":"PASSWORD",
"FullName":"Full Name",
"Username":"USER_NAME"
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接