当前位置: 首页 > 知识库问答 >
问题:

我的HttpURLConnection请求有什么问题?

闻人越
2023-03-14

我试图用PUT请求调用REST API,但收到400个错误代码(错误请求)。有人能看出我做错了什么吗?

我已经用REST客户端成功调用了这个API,下面是使用的头和主体:

https://imgur.com/dZVyawnhttps://imgur.com/lMtn2JB

    String credentials = Base64.getEncoder().encodeToString(("wcadmin:wcadmin").getBytes());
    URL url = new URL(getURL());
    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod("PUT");
    connection.setDoOutput(true);
    connection.setDoInput(true);

    //Set Headers
    String fileUrl = "c:\\0000000050.xml";
    File fileToUpload = new File(fileUrl);
    long length = fileToUpload.length();
    String FORM_DATA_BOUNDARY = "------FormBoundary" + System.currentTimeMillis();
    connection.setRequestProperty("csrf_nonce", getNonceValue());
    connection.setRequestProperty("Accept", "application/xml");
    connection.setRequestProperty("Authorization", "Basic " + credentials);
    connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + FORM_DATA_BOUNDARY);
    connection.setRequestProperty("Content-Length", Long.toString(length));

    //Setup Request Body Writer
    OutputStream requestBodyOutputStream = connection.getOutputStream();
    BufferedWriter requestBodyWriter = new BufferedWriter(new OutputStreamWriter(requestBodyOutputStream));

    //Write Body
    requestBodyWriter.write("\r\n\r\n");
    requestBodyWriter.write(FORM_DATA_BOUNDARY);
    requestBodyWriter.write("\r\n");
    requestBodyWriter.write("Content-Disposition: form-data; name=\"file\"; filename=\"" + fileUrl + "\"");
    requestBodyWriter.write("\r\n");
    requestBodyWriter.write("Content-Type: text/xml");
    requestBodyWriter.write("\r\n\r\n");
    requestBodyWriter.flush();

    FileInputStream uploadFileStream = new FileInputStream(fileToUpload);
    int bytesRead;
    byte[] dataBuffer = new byte[1024];
    while ((bytesRead = uploadFileStream.read(dataBuffer)) != -1) {
        requestBodyOutputStream.write(dataBuffer, 0, bytesRead);
    }
    requestBodyOutputStream.flush();

    requestBodyWriter.write("\r\n");
    requestBodyWriter.write(FORM_DATA_BOUNDARY);
    requestBodyWriter.flush();

    //Close the streams
    requestBodyOutputStream.close();
    requestBodyWriter.close();
    uploadFileStream.close();

    //Read Response
    String inputLine;
    StringBuffer content = new StringBuffer();
    InputStream inputStream = connection.getInputStream();
    if (inputStream != null) {
        BufferedReader responseReader = new BufferedReader(new InputStreamReader(inputStream));
        if (responseReader != null) {
            while ((inputLine = responseReader.readLine()) != null) {
                content.append(inputLine);
            }
            responseReader.close();
        }
    }

    connection.disconnect();

错误400收到错误请求响应

共有1个答案

农均
2023-03-14

首先也是最重要的一点:不能同时写入OutputStream和封装同一OutputStream的OutputStreamWriter。他们会互相冲突。

根本不要使用OutputStreamWriter;而是自己将文本转换为字节:

OutputStream requestBodyOutputStream = connection.getOutputStream();

requestBodyOutputStream.write("\r\n\r\n".getBytes(StandardCharsets.UTF_8));
requestBodyOutputStream.write(FORM_DATA_BOUNDARY.getBytes(StandardCharsets.UTF_8));
// etc.

其次,使用系统的默认字符集在字节和字符串之间进行转换,这意味着写入的内容取决于代码运行的系统。不要叫String。getBytes而不指定显式字符集。通常getBytes(StandardCharsets.UTF_8)是您想要的。

类似地,您需要向InputStreamReader创建传递一个字符集(尽管这不是问题的原因,因为您目前没有得到有效的响应)。不要装出一副有魅力的样子;使用响应内容类型头中的charsetMIME-type参数。如果使用的Java版本早于11,则可以使用javax解析内容类型值。激活。MimeType类,但要注意javax。从Java11开始,激活包已从JavaSE中删除。对于Java11及更高版本,Java激活可以作为独立库下载。另一种选择是使用JavaMail库,特别是它的ContentType类进行解析。

第三,主体部分(边界之间)内的内容长度标头应该使用文件长度作为内容长度。整个请求主体的内容长度必须是您所写的所有内容的长度:边界、主体部分标头和文件内容。

消息是,我认为(尽管我不是肯定的)URLConnection将根据您编写的字节自动设置请求的总内容长度,因此您可能不需要自己计算长度;你可以完全不设置“内容长度”。

当您确实传递了一个正确的请求时,您会发现您正在删除响应中的换行符。如果回应应该是人类可读的文本,那么这些新词可能很重要。如果您使用的是Java10或更高版本,则可以使用Reader。与StringWriter一起转移到:

StringWriter responseBody = new StringWriter();
responseReader.transferTo(responseBody);
String content = responseBody.toString();

如果您使用的Java版本早于10:

  • new BufferedReader不能返回null,因此检查null是没有意义的。在Java中,new操作符总是返回一个新对象(除非抛出异常,在这种情况下,new根本不返回)

您正在将文件复制到请求中,而没有任何缓冲,这将是非常缓慢和低效的。考虑使用<代码>文件。复制(fileToUpload.toPath(),requestBodyOutputStream)。

 类似资料:
  • 这是我的axios依赖: 这是我的代码 这段代码有什么问题么?请求并不会取消

  • 我正在尝试使用HttpUrlConnection发送帖子。一切看起来都很好,但它保持返回400,就好像参数不是在DataOutputStream中发送的,或者是以错误的方式发送的。 这是返回的内容: 这很奇怪,因为这个卷曲正常工作: 它会返回我想要的访问令牌

  • 我正在使用PARSE API发出GET请求。我收到一个“414请求URI太大”错误,但我不明白为什么。这是我请求的代码:

  • 我试图使用HttpURLConnection执行post请求,但不知道如何正确执行。 我可以使用以下代码成功地使用Android AsyncHttp客户端执行请求: 可以在台式机上使用curl执行相同的请求: 这两种方法都给了我来自服务器的预期响应。 现在我想使用HttpURLConntions执行相同的请求。问题是我不知道如何正确地执行它。我尝试过这样的事情: 如何正确地将与使用AsyncHtt

  • 问题内容: 运行此代码时,我不断收到此错误: 错误:大小写类型的字符不同,并且整数不能匹配 您可能会认为这不会造成问题,因为我正在查询中创建新列。我还想指出的是,如果有帮助,我正在使用旧版本的PostgreSQL。 问题答案: