Я использую java 1.8 и весеннюю загрузку 2.7.4.
Я хочу получить доступ к удаленному серверу REST, и я застрял в начале.
Я использовал этот туториал для написания кода.
Компиляция прошла нормально, но в конце выполнения не было сделано ни одного запроса, и я не понимаю, почему. Я перенаправил java на прокси-сервер и вижу, что запрос не сделан, я должен увидеть ошибку, связанную с отсутствующим сертификатом...
Это код:
@SpringBootApplication
public class RestApplication {
public static void main(String[] args) {
System.out.println("Start build request");
WebClient client = WebClient.create("https://test.caido.ro");
UriSpec<RequestBodySpec> uriSpec = client.post();
RequestBodySpec bodySpec = uriSpec.uri("/api/login");
RequestHeadersSpec<?> headersSpec = bodySpec.body(BodyInserters.fromValue("{\n" +
" \"email\": \"test\",\n" +
" \"password\": \"test\"\n" +
"}"));
System.out.println("Start send request");
Mono<String> response = headersSpec.retrieve().bodyToMono(String.class);
System.out.println("Stop send request "+response.toString());
}
}
Вы должны использовать response.subscribe( it -> System.out.println("Stop send request " + it);. В противном случае он может даже ничего не делать, поскольку вы на самом деле не подписываетесь на что-то. Подобно обычному потоку в Java, если терминал не работает, ничего не произойдет.




WebClient — не единственный вариант. Вы можете попробовать другие клиенты Http, которые могут быть проще в использовании. Вот несколько вариантов:
С библиотекой MgntUtils ваш код может быть таким же простым, как
private static void testHttpClient() {
HttpClient client = new HttpClient();
client.setContentType("application/json; charset=utf-8");
client.setConnectionUrl("http://www.your.url.com/");
String content = null;
try {
content = client.sendHttpRequest(HttpMethod.POST, "Some textual conent - like your JSON");
} catch (IOException e) {
content = TextUtils.getStacktrace(e, false);
}
System.out.println(content);
}
Конечно, есть много альтернатив, но до сих пор Spring Web Client является единственным HTTP-клиентом Java, который поддерживает реактивные, неблокирующие вызовы. И его спину прикрывает Spring. Для использования OP я не думаю, что он вызывает неблокирующую конечную точку, однако я действительно хочу посмотреть, может ли веб-клиент вызывать как неблокирующие, так и блокирующие конечные точки, потому что он приходит на замену RestTemplate, поэтому он должен быть способен делать то же самое и многое другое.
Вот сравнительная статья о RestTemplate и WebClient: baeldung.com/….
Просто сделал некоторую отладку и обнаружил, что вы сделали несколько ошибок:
1. Вы выполняете свое приложение без SpringApplication.run(WebClientApplication.class, args);
Это означает, что он выполнит все, а затем завершится еще до того, как вы сможете получить ответ (что будет сделано в другом потоке для достижения асинхронности).
2, Вы работаете с Mono, это больше похоже на Promise в JS, он стоит как обертка для ответа, когда он приходит, после того, как ответ приходит, вы можете подписаться и что-то делать с ним, но до этого в основном ничего нет внутри этого объекта, поэтому toString() не даст вам желаемого ответа.
Вот мое предложение:
1. Явно сообщите WebClient, что вы ждете своего ответа и ничего не делаете, пока не получите его, используя Mono.block()
Как это :
System.out.println("Stop send request "+response.block());
2. У вас есть подписчик, который будет обрабатывать ответ, когда он придет, например:
response.subscribe(e -> {
System.out.println("------------------------------RESPONSE----------------------------------");
System.out.println(e);
System.out.println("------------------------------END----------------------------------");
});
Но этот lambda также будет выполняться в другом потоке и может быть прерван до выполнения, если ваш основной поток умрет. Поэтому, если вы все еще хотите протестировать его в своем текущем примере, вы должны указать основному потоку подождать некоторое время, используя Thread.sleep()
И теперь вы должны увидеть ответ или, по крайней мере, запрос.
Попробуйте вызвать
response.block()илиThread.sleep(10_000)в конце. Вашmainможет завершиться (а вместе с ним и вся программа) до того, как ваш запрос будет фактически отправлен.