#java #vert.x #vertx-httpclient
#java #vert.x #vertx-httpclient
Вопрос:
Привет, может кто-нибудь, пожалуйста, посмотреть :
Когда я пытаюсь получить данные с помощью VERTX HTTP CLIENT, это приводит к исключению нулевого указателя в последней строке, и тот же URL предоставляет данные, когда я использовал java HTTP CLIENT :
HttpClientOptions options = new HttpClientOptions().setKeepAlive(false);
options.setLogActivity(true);
options.setDefaultHost("http://delvmpllbbab10");
options.setDefaultPort(7003);
HttpClient client = vertx.createHttpClient(options);
HttpClientResponse[] clientResponse = {null};
client.request(HttpMethod.GET, "/rcsservices/homePage", response -> {
System.out.println("Received response with status code " response.statusCode());
clientResponse[0] = response;
}).putHeader("content-type", "application/json").end(clientResponse[0].toString());
Из-за этого кода у меня какая-то проблема…
Ответ №1:
Это правильно, вы получите NPE
, поэтому в вашем коде вы инициализируете clientResponse
переменную с помощью { null }
. Если вы теперь проследите за тем, как выполняется код, вы поймете, почему:
- создайте объект запроса:
client.request(
- вы настраиваете, что будет выполнено после получения ответа: `response -> { … }
- вы добавляете заголовок к запросу:
putHeader(...)
- вы запускаете запрос
end(clientResponse[0].toString())
Теперь вы видите, что clientResponse[0]
по-прежнему равно null (это было значение, которое вы инициализировали. Итак, что происходит, так это то, что вы вызываете:
null.toString()
Что недопустимо и всегда будет выдавать Null Pointer Exception
.
Ответ №2:
У меня была та же проблема, что и при запуске Vert-X framework, и я могу заметить следующие улучшения в вашем коде:
- Вы должны обработать ответ с помощью bodyHandler HttpClientResponse, тогда вы не сможете передать внешнюю переменную, если она не является окончательной
- Всегда лучше использовать AsyncResponse, чтобы не блокировать вызывающий поток, особенно если вы полагаетесь на внешнюю систему (другой веб-сервис в вашем случае)
- Я не уверен, что вы хотите предоставить тело или нет,
.end()
в запросе содержится новое «тело запроса клиента», но при выполнении GET тело должно быть нулевым - Попробуйте использовать стандартные
HttpHeaders
иMediaType
(я лично используюMediaType
из JAX-RS) вместо того, чтобы писать свои собственные строки. - Попробуйте вместо этого использовать соответствующий регистратор
System.out.println(...)
Следующий код показывает, как мне удается вернуть ответ исходному вызывающему:
public void callWebService(@Context HttpServerRequest request, @Suspended final AsyncResponse asyncResponse) {
HttpClientOptions options = new HttpClientOptions().setKeepAlive(false);
options.setLogActivity(true);
options.setDefaultHost("http://delvmpllbbab10");
options.setDefaultPort(7003);
HttpClient client = vertx.createHttpClient(options);
client.request(HttpMethod.GET, "/rcsservices/homePage", response -> {
System.out.println("Received response with status code " response.statusCode());
int code = response.statusCode();
if (code == 200) {
response.bodyHandler(bufferResponse -> {
// Adapt according your response type, could be String as well
JsonObject httpResult = bufferResponse.toJsonObject();
System.out.println("Received HTTP response with body " httpResult);
asyncResponse.resume(Response.ok(httpResult).build());
});
} else {
response.bodyHandler(bufferResponse -> {
// Return null in a JSON Object in case of error
String httpResult = "{null}";
asyncResponse.resume(Response.status(code).entity(httpResult).build());
});
}
}).putHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON).end();
Существует множество способов сделать то же самое, и вы можете проверить официальную страницу руководства.