Я хочу узнать, как использовать Restcontroller WebFlux, создающий потоки json из React. Моя первая попытка заставила меня разобрать текст вместо json, но у меня такое чувство, что я делаю что-то странное. Я решил потратить силы на чтение примеров и нашел пример, возвращающий org.reactivestreams.Publisher вместо возврата WebFlux.
Я нашел немного устаревшую тему, которая могла мне помочь (Невозможно использовать ответ Webflux Streaming в клиенте React-Native), но у него нет однозначного ответа. Это заставило меня где-то прочитать, что React может не соответствовать Reactive, но это был очень старый пост.
Взяв образец из Интернета, если вы посмотрите на https://developer.okta.com/blog/2018/09/25/spring-webflux-websockets-react в основном вы найдете:
WebFlux производит Json, НО НЕ ПОТОК:
RestController producing MediaType.APPLICATION_JSON_VALUE and returning org.reactivestreams.Publisher<the relevant pojo>
Реагировать на использование json:
async componentDidMount() {
const response = await fetch('relevant url');
const data = await response.json();
}
Я пробовал аналогичный подход, но с двумя существенными различиями:
Я возвращаю MediaType.TEXT_EVENT_STREAM_VALUE, потому что считаю, что предпочитаю возвращаемые потоки, поскольку я работаю с кодом без блокировки и вместо того, чтобы возвращать org.reactivestreams.Publisher, я понимаю, что имеет смысл вернуть Webflux, чтобы правильно использовать преимущества Spring 5 +.
мой контроллер отдыха Webflux:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.mybank.web.model.Loans;
import com.mybank.web.service.LoansService;
import reactor.core.publisher.Flux;
@RestController
public class LoansController {
@Autowired
private LoansService loansService;
@CrossOrigin
@RequestMapping(method = RequestMethod.GET, produces = MediaType.TEXT_EVENT_STREAM_VALUE)
@ResponseBody
public Flux<Loans> findAll() {
Flux<Loans> loans = loansService.findAll();
return loans;
}
}
Результатом является явно поток, а не json (скопировано из Postman):
data:{"timestamp":1558126555269,"result":"8"}
data:{"timestamp":1558132444247,"result":"10"}
data:{"timestamp":1558132477916,"result":"10"}
data:{"timestamp":1558132596327,"result":"14"}
Стек основан на загрузке MongoDb и Spring, но я не собираюсь вставлять здесь, поскольку это не актуально.
Реагировать
async componentDidMount() {
const response = await fetch('http://localhost:8080');
const data = await response.json();
}
Я получаю сообщение «Непойманный (в обещании) SyntaxError: Неожиданный токен d в JSON в позиции 0» по очень очевидной причине: я не возвращаю действительный json.
Затем, если я изменю контроллер Webflux для создания json (производит = MediaType.APPLICATION_JSON_VALUE), остальной контроллер не ответит мне ни потоком, ни результатом из кода без блокировки.
[
{
"timestamp": 1558126555269,
"result": "8"
},
{
"timestamp": 1558132444247,
"result": "10"
},
{
"timestamp": 1558132477916,
"result": "10"
},
{
"timestamp": 1558132596327,
"result": "14"
}
]
С таким ответом интерфейс React может анализировать, но я понимаю, что не использую потоковую передачу. Кто-то может возразить, что для такого простого примера бесполезно думать о потоковой передаче, но моя цель обучения действительно сосредоточена на понимании и правильном кодировании с помощью webflux + react consumming streams.
Наконец, после прочтения https://spring.io/blog/2017/02/23/spring-framework-5-0-m5-update Я изменил контроллер restcontroller webflux на создание APPLICATION_STREAM_JSON_VALUE, а также попытался произвести = "application / stream + json". Для обоих вариантов ответ restcontroller кажется потоком json, но снова React жалуется:
{"timestamp":1558126555269,"result":"8"}
{"timestamp":1558132444247,"result":"10"}
{"timestamp":1558132477916,"result":"10"}
{"timestamp":1558132596327,"result":"14"}
Ошибка на стороне React:
Unexpected token { in JSON at position 41
Подводя итог: я не нашел, как использовать из React контроллер Webflux Restcontroller, создающий потоки Json.
Возможно, возможный ответ - «измените React, используя эту библиотеку и используйте ее таким образом», или, может быть, ответ будет «код Webflux Restcontroller для возврата в этом формате». Кстати, после прочтения всех примеров, которые я нашел в теме React + Webflux, я застрял.
Другими словами, мой прямой вопрос: как использовать конечную точку webflux, производящую json-потоки из React?