有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

RESTAPI可以从Postman调用,显示来自Java的400个错误请求

我正在尝试使用POST-restful服务。当我在邮递员身上试用时,我得到了成功的回复。但当我用下面的代码在java上尝试时,我得到的响应代码是400。在《邮递员》中,我用替换转义字符粘贴相同的输入

try {

    URL url = new URL("https://localhost/PasswordVault/api/Accounts");
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("POST");
    conn.setDoOutput(true);

    conn.setRequestProperty("Content-Type", "application/json");
    String input = "{\"qty\":100,\"name\":\"iPad 4\", \"detail\":{\"ver\":\"2020\",\"productionDate\":\"2020\"}}";

    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 (Exception e) {
        System.out.println("Exception:- " + e);
}

共 (3) 个答案

  1. # 1 楼答案

    首先,检查邮递员可能正在发送的请求头,而您的代码没有。在发送请求之前,您可能需要在请求中添加一些标题。其次,我强烈建议使用一些3d party Http客户端库,而不是自己编写Http请求。一些著名的库是Apache Http clientOK Http client。我个人使用自己的Http客户端,它是MgntUtils开源库的一部分。你也可以试试。以下是简化的代码,仅用于演示如何从网站上读取一些响应:

        try {
            HttpClient client = new HttpClient();
            client.setConnectionUrl("https://www.yahoo.com/");
            String result = client.sendHttpRequest(HttpMethod.GET);
            System.out.println(result);
        } catch (IOException e) {
            System.out.println(TextUtils.getStacktrace(e, "com.mgnt."));
        }
        
    

    当然,您也可以使用这个库发送POST请求、设置请求头、读取文本或二进制响应和响应头。这里是HttpClient class Javadoc的链接。该库本身以Maven artifactGithub的形式提供,包括Javadoc和源代码

  2. # 2 楼答案

    我强烈建议你使用图书馆来做这件事。 您可以使用Jackson,这将极大地简化和标准化java与远程HTTP服务的交互

    以下几点会让你开始:

    import javax.ws.rs.client.Client;
    import javax.ws.rs.client.ClientBuilder;
    import javax.ws.rs.client.Entity;
    import javax.ws.rs.client.WebTarget;
    import javax.ws.rs.core.MediaType;
    import javax.ws.rs.core.Response;
    
    public class ApiClient
    {
    
        private transient Client client;
        protected transient WebTarget apiRoot;
    
        public ApiClient(String rootUrl) 
        {
            this.client = ClientBuilder.newBuilder().build();
            // The root URL is your API starting point, e.g. https://host/api
            this.apiRoot = client.target(rootUrl);
        }
    
        public Response doPostToAccounts(String data)
        {
            try 
            {
                // This is where you execute your POST request
                return apiRoot.path("/Accounts")
                    .request(MediaType.APPLICATION_JSON)
                    .post(Entity.entity(data, MediaType.APPLICATION_JSON));
            } catch (Exception e) {
                throw new IllegalStateException(e);
            }
        }
    
    }
    
  3. # 3 楼答案

    一些想法:

    • 用UTF-8编码你的请求帖子数据:"post data".getBytes(StandardCharsets.UTF_8)
    • 阅读服务器的响应(不仅仅是代码),希望能获得有关问题的更多详细信息(connection.getErrorStream()
    • 是否缺少授权标头?(API令牌等)
    • 使用单引号使请求数据字符串更具可读性,或者使用JSON库避免手动错误
    • 也可以调用OutputStream。(()冲洗后关闭)

    例如

      // handle error code
      if(connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
        // use getErrorStream for non OK statuses (https://stackoverflow.com/questions/613307/read-error-response-body-in-java)
        String errorMessage = "HTTP response code: " + responseCode
            + (responseMessage == null || responseMessage.trim().length() == 0 ? "" : " " + responseMessage);
    
        InputStream errorStream = connection.getErrorStream();
        if(errorStream != null) {
          String errorString = streamToString(connection.getErrorStream());
          if(errorString.length() > MAX_MSG_LENGTH) {
            errorString = errorString.substring(0, Math.min(MAX_MSG_LENGTH, errorString.length())) + "...";
          }
          errorMessage += ", HTTP response data: " + errorString;
        }
    
        throw new RuntimeException(errorMessage);
      }
    
      // handle OK code
      // ...