Итак, теперь к проблеме.
Я есть сервер, который отправляет ответы SSE. Я хочу написать клиент Quarkus для вызовов этой конечной точки сервера.
Проблема в том, что, хотя я правильно сопоставил ответ на запись Java, приложение Quarkus завершается с ошибкой: ERROR [io .qua.ver.cor.run.VertxCoreRecorder] (vert.x-eventloop-thread-1) Неперехваченное исключение, полученное Vert.x: jakarta.ws.rs.ProcessingException: ответ не может быть сопоставлен с классом типа TestDTO для ответа с нулевым типом носителя
Фактический ответ сервера таков:
Код: Выделить всё
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Content-Type: text/event-stream
< Cache-Control: no-cache
< Connection: keep-open
< Transfer-Encoding: chunked
<
event: success
data: {"a":"str_value_1","date":"1970-01-01T02:00:00.000Z","b":1}
event: success
data: {"a":"str_value_2","date":"1970-01-01T02:00:00.000Z","b":2}
- Клиентский интерфейс Quarkus
Код: Выделить всё
@Path("/api")
@RegisterRestClient(configKey = "service-api")
public interface TestClient {
@GET
@Path("test")
@Produces(MediaType.SERVER_SENT_EVENTS)
Multi getTest();
}
- TestDTO
Код: Выделить всё
@JsonIgnoreProperties(ignoreUnknown = true)
public record TestDTO(String a, LocalDate date, int b) {
private static final ObjectWriter WRITER = new ObjectMapper()
.writerWithDefaultPrettyPrinter()
.withoutAttribute("jacksonObjectMapper");
@Override
public String toString() {
try {
return WRITER.writeValueAsString(this);
} catch (Exception e) {
return String.format("IssueComment[id=%s]", id);
}
}
}
- TestResource:
Код: Выделить всё
@Path("/test")
@ApplicationScoped
public class testResource {
@RestClient
GitHubServiceClient client;
@GET
@Produces(MediaType.SERVER_SENT_EVENTS)
public Multi hello() {
return client.getTest().onItem().invoke(item -> System.out.println(item));
}
}
Теперь, когда я меняю TestDTO на TestDTO(String a) клиент не выдает ошибку сопоставления. результат, который я получаю, может указать, в чем проблема:
Код: Выделить всё
{
"a" : "{\"a\":\"str_value_1\",\"date\":\"1970-01-01T02:00:00.000Z\",\"b\":1}"
}
{
"a" : "{\"a\":\"str_value_2\",\"date\":\"1970-01-01T02:00:00.000Z\",\"b\":2}"
}
он интерпретирует данные SSE как строку.
< hr />
Обходной путь
Я нашел один из способов обойти эту ошибку — выполнить процесс сопоставления вручную.
Я изменил метод клиентского интерфейса, чтобы он возвращал Multi (т.е. Multi getTest()) и используйте com.fasterxml.jackson.databind.ObjectMapper; в TestResource
вот так:
Код: Выделить всё
@Path("/test")
@ApplicationScoped
public class TestResource{
@RestClient
GitHubServiceClient client;
@GET
@Produces(MediaType.SERVER_SENT_EVENTS)
public Multi hello() {
ObjectMapper objectMapper = new ObjectMapper();
return client.getTest()
.map(Unchecked.function(s -> {
try {
return objectMapper.readValue(s, TestDTO.class);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
})).onItem().invoke(item -> System.out.println(item));
}
}
- Java 17
- Кваркус 3.17.0
Подробнее здесь: https://stackoverflow.com/questions/792 ... ide-events
Мобильная версия