来自 Java 的请求 (HttpURLConnection) - 如何发送二进制内容

问题描述 投票:0回答:2

我有我的服务器(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]
java spring spring-boot httpurlconnection
2个回答
1
投票

实际上,我编写了一个开源库,其中包含

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 ,可以在 here 找到 Maven 工件,库(jar、Javadoc 和源代码)here 以及尚未发布的分支的源代码是这里


0
投票

您必须在多个阶段进行更改才能使其发挥作用。这是一个详细的线程,在这方面应该有所帮助。 Spring boot中如何设置UTF-8字符编码?

© www.soinside.com 2019 - 2024. All rights reserved.