【问题标题】:Request from Java (HttpURLConnection) - how to send binary content来自 Java (HttpURLConnection) 的请求 - 如何发送二进制内容
【发布时间】:2021-09-07 12:40:35
【问题描述】:

我的服务器 (SpringBoot) 需要上传一个文件,我的客户端 (纯 Java) 需要在那里发送一个 byte[] 数组。

服务器端点如下所示:

@RequestMapping(value = "/", method = RequestMethod.POST, headers={"content-type=multipart/form-data"})
ResponseEntity<String> postBytes(@ApiParam(value = "Upload bytes.", example = "0") @RequestBody Bytes bytes) {                   
    return ResponseEntity.ok(byteLinkService.postBytes(bytes.getBytes()));
}

客户端请求如下所示:

//byte[] bytes is my file to be uploaded
URL url = new URL(this.endpoint + "/bytelink/");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Authorization", "Bearer " + token);
con.setRequestProperty("Content-Type", "multipart/form-data");
con.setRequestProperty("Accept", "*");
con.setDoOutput(true);
            
String jsonInputString = "{\"bytes\": \"" + Arrays.toString(bytes) + "\"}";
try (OutputStream os = con.getOutputStream()) {
    byte[] input = jsonInputString.getBytes("utf-8");
    os.write(input, 0, input.length);           
}

int status = con.getResponseCode();
System.out.println(status);

现在我得到了这个异常:

WARN  o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'text/plain;charset=UTF-8' not supported]

【问题讨论】:

  • 您将输出流编码为utf-8,springboot不支持。

标签: java spring httpurlconnection


【解决方案1】:

您必须在多个阶段进行更改才能使其正常工作。这是一个详细的线程,应该在这方面有所帮助。 How to set UTF-8 character encoding in Spring boot?

【讨论】:

    【解决方案2】:

    实际上,我编写了一个包含HttpClient 实用程序的开源库。我现在正在添加一个允许上传二进制信息的功能。我已经有一个工作代码,但是具有此功能的版本尚未发布。但是我已经对其进行了测试并且它可以工作,所以我可以给你我用于在接收端测试的 Spring boot 服务器代码,你可以查看我的开源分支以及将二进制信息发送到服务器的代码。让我们从服务器端开始。此代码接收 POST 请求并从请求中读取二进制信息并将其保存为文件:

    @RestController
    @RequestMapping("/upload")
    public class UploadTestController {
        @PostMapping
        public ResponseEntity<String> uploadTest(HttpServletRequest request) {
            try {
                String lengthStr = request.getHeader("content-length");
                int length = TextUtils.parseStringToInt(lengthStr, -1);
                if(length > 0) {
                    byte[] buff = new byte[length];
                    ServletInputStream sis =request.getInputStream();
                    int counter = 0;
                    while(counter < length) {
                        int chunkLength = sis.available();
                        byte[] chunk = new byte[chunkLength];
                        sis.read(chunk);
                        for(int i = counter, j= 0; i < counter + chunkLength; i++, j++) {
                            buff[i] = chunk[j];
                        }
                        counter += chunkLength;
                        if(counter < length) {
                            TimeUtils.sleepFor(5, TimeUnit.MILLISECONDS);
                        }
                    }
                    Files.write(Paths.get("C:\\Michael\\tmp\\testPic.jpg"), buff);
                }
            } catch (Exception e) {
                System.out.println(TextUtils.getStacktrace(e));
            }
            return ResponseEntity.ok("Success");
        }
    }
    

    这是客户端代码,它使用我的库中的方法 sendHttpRequest HttpClient 类并将一些二进制文件读取到服务器端。

    private static void testHttpClientBinaryUpload() {
        try {
            byte[] content = Files.readAllBytes(Paths.get("C:\\Michael\\Personal\\pics\\testPic.jpg"));
            HttpClient client = new HttpClient();
            Integer length = content.length;
            Files.write(Paths.get("C:\\Michael\\tmp\\testPicOrig.jpg"), content);
            client.setRequestHeader("Content-Length", length.toString());
            String result = client.sendHttpRequest("http://localhost:8080/upload", HttpMethod.POST, ByteBuffer.wrap(content));
            System.out.println(result);
            System.out.println("HTTP " + client.getLastResponseCode() + " " + client.getLastResponseMessage());
        } catch (Exception e) {
            System.out.println(TextUtils.getStacktrace(e, "com.mgnt."));
        }
    }
    

    最后是我的图书馆。请参阅类 HttpClient 请参阅第 146 行的方法 sendHttpRequest 和第 588 行的方法 sendRequest 以了解它是如何工作的。

    如果你对这个库感兴趣,这里是Javadoc for the latest release,可以找到 Maven 工件here,库(jar、Javadoc 和源代码)here,未发布但分支的源代码是 @ 987654325@

    【讨论】:

      猜你喜欢
      • 2023-04-01
      • 2012-02-15
      • 2020-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多