Клиент Quarkus: сбой десериализации из-за событий на стороне сервераJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Клиент Quarkus: сбой десериализации из-за событий на стороне сервера

Сообщение Anonymous »

Я пытаюсь изучить Quarkus, поэтому не стесняйтесь поправлять меня, если я допустил какие-либо ошибки.
Итак, теперь к проблеме.
Я есть сервер, который отправляет ответы 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
  • Клиентский интерфейс 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
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»