问题描述
我有一段代码,它为特定的端点发出POST请求。这段代码使用的是Apache的HttpClient,我想开始使用Java(JDK11)中的本机HttpClient。但我不知道如何指定我的请求的参数。
这是我使用Apache HttpClient编写的代码:
var path = Path.of("file.txt"); var entity = MultipartEntityBuilder.create() .addPart("file", new FileBody(path.toFile())) .addTextBody("token", "<any-token>") .build();
和使用HttpClient的代码:
var client = HttpClient.newHttpClient(); var request = HttpRequest.newBuilder() .uri(URI.create("https://myendpoint.com/")) .POST( /* How can I set the parameters here? */ );
如何设置file和token参数?
推荐答案
遗憾的是,Java 11HTTP客户端没有为多部分类型的正文提供任何方便的支持。但我们可以在其上构建自定义实现:
Map<Object, Object> data = new LinkedHashMap<>(); data.put("token", "some-token-value";); data.put("file", File.createTempFile("temp", "txt").toPath();); // add extra parameters if needed // Random 256 length string is used as multipart boundary String boundary = new BigInteger(256, new Random()).toString(); HttpRequest.newBuilder() .uri(URI.create("http://www.51sjk.com/Upload/Articles/1/0/331/331278_20221019163508651.com")) .header("Content-Type", "multipart/form-data;boundary=" + boundary) .POST(ofMimeMultipartData(data, boundary)) .build(); public HttpRequest.BodyPublisher ofMimeMultipartData(Map<Object, Object> data, String boundary) throws IOException { // Result request body List<byte[]> byteArrays = new ArrayList<>(); // Separator with boundary byte[] separator = ("--" + boundary + " Content-Disposition: form-data; name=").getBytes(StandardCharsets.UTF_8); // Iterating over data parts for (Map.Entry<Object, Object> entry : data.entrySet()) { // Opening boundary byteArrays.add(separator); // If value is type of Path (file) append content type with file name and file binaries, otherwise simply append key=value if (entry.getValue() instanceof Path) { var path = (Path) entry.getValue(); String mimeType = Files.probeContentType(path); byteArrays.add((""" + entry.getKey() + ""; filename="" + path.getFileName() + "" Content-Type: " + mimeType + " ").getBytes(StandardCharsets.UTF_8)); byteArrays.add(Files.readAllBytes(path)); byteArrays.add(" ".getBytes(StandardCharsets.UTF_8)); } else { byteArrays.add((""" + entry.getKey() + "" " + entry.getValue() + " ") .getBytes(StandardCharsets.UTF_8)); } } // Closing boundary byteArrays.add(("--" + boundary + "--").getBytes(StandardCharsets.UTF_8)); // Serializing as byte array return HttpRequest.BodyPublishers.ofByteArrays(byteArrays); }
这里working example on Github(您需要更改VirusTotal API密钥)