Java 11:新的 HTTP 客户端发送 POST 带有 x-www-form-urlencoded 参数的请求
Java 11: New HTTP client send POST requests with x-www-form-urlencoded parameters
我正在尝试使用新的 http 客户端 api 发送 POST 请求。
是否有一种内置的方式来发送格式为 x-www-form-urlencoded
的参数?
我当前的代码:
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(BodyPublishers.ofString("a=get_account&account=" + URLEncoder.encode(account, "UTF-8")))
.build();
我正在寻找一种更好的传递参数的方法。像这样:
Params p=new Params();
p.add("a","get_account");
p.add("account",account);
我需要自己构建此功能还是已经内置了某些功能?
我正在使用 Java 12.
我认为以下是使用 Java 11 实现此目的的最佳方法:
Map<String, String> parameters = new HashMap<>();
parameters.put("a", "get_account");
parameters.put("account", account);
String form = parameters.entrySet()
.stream()
.map(e -> e.getKey() + "=" + URLEncoder.encode(e.getValue(), StandardCharsets.UTF_8))
.collect(Collectors.joining("&"));
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.headers("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString(form))
.build();
HttpResponse<?> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode() + " " + response.body().toString());
这种方式可能有用:
String param = Map.of("param1", "value1", "param2", "value2")
.entrySet()
.stream()
.map(entry -> Stream.of(
URLEncoder.encode(entry.getKey(), UTF_8),
URLEncoder.encode(entry.getValue(), UTF_8))
.collect(Collectors.joining("="))
).collect(Collectors.joining("&"));
您最多可以使用 10 对(参数,值)Map.of(...)
。它 returns 一个不可修改的地图。
正如 Łukasz Olszewski 所说,工作正常:
String params = Map.of(
Constants.PARAM_CLIENT_ID, apiObject.getClientId(),
Constants.PARAM_SCOPE, apiObject.getScope(),
Constants.PARAM_CODE, apiObject.getCode(),
Constants.PARAM_REDIRECT_URI, apiObject.getRedirectUri(),
Constants.PARAM_GRANT_TYPE, apiObject.getGrantType(),
Constants.PARAM_CODE_VERIFIER, apiObject.getCodeVerifier())
.entrySet()
.stream()
.map(entry -> Stream.of(
URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8),
URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8))
.collect(Collectors.joining("="))
).collect(Collectors.joining("&"));
HttpResponse<?> response = utils.consumeHttpPostFormUrlEncodedClientByRequestUrl(Constants.URL_BASE + Constants.URL_GET_TOKEN, params);
并使用 HttpPostFormUrlEncodedClientByRequestUrl
public HttpResponse<?> consumeHttpPostFormUrlEncodedClientByRequestUrl(String url, String map) throws IOException, InterruptedException {
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.header("Content-Type", String.valueOf(MediaType.APPLICATION_FORM_URLENCODED))
.POST(HttpRequest.BodyPublishers.ofString(map))
.build();
return httpClient.send(request, HttpResponse.BodyHandlers.ofString());
}
查看 Methanol. It's got a nice FormBodyPublisher
x-www-form-urlencoded
个尸体。
var formBody = FormBodyPublisher.newBuilder()
.query("a", "get_account")
.query("account", account)
.build();
var request = MutableRequest.POST("https://example.com", formBody);
// Methanol implements an HttpClient that does nice things to your request/response.
// Here, the Content-Type header will be added for you.
var client = Methanol.create();
var response = client.send(request, BodyHandlers.ofString());
您可以使用更紧凑的 String.join 而不是 Stream.of(根据 Łukasz Olszewski 的回答):
String form = Map.of("param1", "value1", "param2", "value2")
.entrySet()
.stream()
.map(entry -> String.join("=",
URLEncoder.encode(entry.getKey().toString(), StandardCharsets.UTF_8),
URLEncoder.encode(entry.getValue().toString(), StandardCharsets.UTF_8)))
.collect(Collectors.joining("&"));
return HttpRequest.BodyPublishers.ofString(form);
我正在尝试使用新的 http 客户端 api 发送 POST 请求。
是否有一种内置的方式来发送格式为 x-www-form-urlencoded
的参数?
我当前的代码:
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/x-www-form-urlencoded")
.POST(BodyPublishers.ofString("a=get_account&account=" + URLEncoder.encode(account, "UTF-8")))
.build();
我正在寻找一种更好的传递参数的方法。像这样:
Params p=new Params();
p.add("a","get_account");
p.add("account",account);
我需要自己构建此功能还是已经内置了某些功能?
我正在使用 Java 12.
我认为以下是使用 Java 11 实现此目的的最佳方法:
Map<String, String> parameters = new HashMap<>();
parameters.put("a", "get_account");
parameters.put("account", account);
String form = parameters.entrySet()
.stream()
.map(e -> e.getKey() + "=" + URLEncoder.encode(e.getValue(), StandardCharsets.UTF_8))
.collect(Collectors.joining("&"));
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.headers("Content-Type", "application/x-www-form-urlencoded")
.POST(HttpRequest.BodyPublishers.ofString(form))
.build();
HttpResponse<?> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode() + " " + response.body().toString());
这种方式可能有用:
String param = Map.of("param1", "value1", "param2", "value2")
.entrySet()
.stream()
.map(entry -> Stream.of(
URLEncoder.encode(entry.getKey(), UTF_8),
URLEncoder.encode(entry.getValue(), UTF_8))
.collect(Collectors.joining("="))
).collect(Collectors.joining("&"));
您最多可以使用 10 对(参数,值)Map.of(...)
。它 returns 一个不可修改的地图。
正如 Łukasz Olszewski 所说,工作正常:
String params = Map.of(
Constants.PARAM_CLIENT_ID, apiObject.getClientId(),
Constants.PARAM_SCOPE, apiObject.getScope(),
Constants.PARAM_CODE, apiObject.getCode(),
Constants.PARAM_REDIRECT_URI, apiObject.getRedirectUri(),
Constants.PARAM_GRANT_TYPE, apiObject.getGrantType(),
Constants.PARAM_CODE_VERIFIER, apiObject.getCodeVerifier())
.entrySet()
.stream()
.map(entry -> Stream.of(
URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8),
URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8))
.collect(Collectors.joining("="))
).collect(Collectors.joining("&"));
HttpResponse<?> response = utils.consumeHttpPostFormUrlEncodedClientByRequestUrl(Constants.URL_BASE + Constants.URL_GET_TOKEN, params);
并使用 HttpPostFormUrlEncodedClientByRequestUrl
public HttpResponse<?> consumeHttpPostFormUrlEncodedClientByRequestUrl(String url, String map) throws IOException, InterruptedException {
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder(URI.create(url))
.header("Content-Type", String.valueOf(MediaType.APPLICATION_FORM_URLENCODED))
.POST(HttpRequest.BodyPublishers.ofString(map))
.build();
return httpClient.send(request, HttpResponse.BodyHandlers.ofString());
}
查看 Methanol. It's got a nice FormBodyPublisher
x-www-form-urlencoded
个尸体。
var formBody = FormBodyPublisher.newBuilder()
.query("a", "get_account")
.query("account", account)
.build();
var request = MutableRequest.POST("https://example.com", formBody);
// Methanol implements an HttpClient that does nice things to your request/response.
// Here, the Content-Type header will be added for you.
var client = Methanol.create();
var response = client.send(request, BodyHandlers.ofString());
您可以使用更紧凑的 String.join 而不是 Stream.of(根据 Łukasz Olszewski 的回答):
String form = Map.of("param1", "value1", "param2", "value2")
.entrySet()
.stream()
.map(entry -> String.join("=",
URLEncoder.encode(entry.getKey().toString(), StandardCharsets.UTF_8),
URLEncoder.encode(entry.getValue().toString(), StandardCharsets.UTF_8)))
.collect(Collectors.joining("&"));
return HttpRequest.BodyPublishers.ofString(form);