用户登录
用户注册

分享至

如何使用Java 11 HTTP客户端为POST请求定义多个参数

  • 作者: 用户72859855
  • 来源: 51数据库
  • 2022-10-19

问题描述

我有一段代码,它为特定的端点发出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密钥)

软件
前端设计
程序设计
Java相关