#java #json #spring-boot #postman #spring-webclient
Вопрос:
У меня есть два API:s , CarRental-API на порту 8080 и CarRental-CRUD на порту 8081.
CarRental-CRUD использует JpaRepository для доступа к базе данных памяти h2.
Я хочу использовать CarRental-API для выполнения запросов к CarRental-CRUD, используя webclient.
В CarRental-CRUD я могу отправлять запросы и добавлять автомобили в базу данных , используя эту услугу:
public String addCar(Car car) { carRepository.save(car); return loggerService.writeLoggerMsg("CREATED CAR AND ADDED TO DB"); }
А затем в контроллере :
@RestController @RequestMapping("/crud/v1") public class AdminCarController { @Autowired private AdminCarService adminCarService; @PostMapping(path = "/addcar", consumes = "application/json") public String addCar(@RequestBody Car car) { return adminCarService.addCar(car); } }
Я попытался отправить запрос с помощью webclient в CarRental-API с :
@Service public class AdminCarService { @Autowired LoggerService loggerService; @Autowired private WebClient.Builder webClientBuilder; public String addCar(Car car) { webClientBuilder .build() .post() .uri("localhost:8081/crud/v1/addcar") .retrieve() .bodyToFlux(Car.class); return loggerService.writeLoggerMsg("ADDED CAR TO DB"); } }
Однако, используя carRental-API , я получаю эту ошибку в postman, когда пытаюсь отправить запрос :
"status": 500, "error": "Internal Server Error", "trace": "org.springframework.web.reactive.function.client.WebClientResponseException: 200 OK from POST localhost:8081/crud/v1/addcar; nested exception is org.springframework.web.reactive.function.UnsupportedMediaTypeException: Content type 'text/plain;charset=UTF-8' not supported for bodyType=com.backend.carrentalapi.entity.Carntat
This is the Car Entity :
@Getter @Setter @RequiredArgsConstructor @NoArgsConstructor @Entity @Table(name = "TBL_CAR") public class Car { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long carId; @Column(name = "NAME") private String carName; @Column(name = "MODEL") private String carModel; @Column(name = "DAILY_PRICE") private double dailyPrice; }
Кажется, я не могу найти, где в коде я создаю текст/обычный. Я убедился в postman, что отправляю необработанный запрос тела JSON, а в заголовках указано тип содержимого : приложение/json.
Ответ №1:
В своем WebClient
вы не добавляете тело запроса, а вместо этого ожидаете Car
возврата от вызываемого вами API (и этот API String
вместо этого возвращает простое). Должно сработать следующее.
@Service public class AdminCarService { @Autowired LoggerService loggerService; @Autowired private WebClient.Builder webClientBuilder; public String addCar(Car car) { webClientBuilder .build() .post() .uri("localhost:8081/crud/v1/addcar") .body(BodyInserters.fromValue(car)) .retrieve() .toBodilessEntity(); return loggerService.writeLoggerMsg("ADDED CAR TO DB"); } }
Используя .toBodilessEntity()
, так как вы на самом деле ничего не делаете с ответом.
Комментарии:
1. Спасибо, запрос на публикацию теперь работает, но база данных, похоже, не получает значения, когда я добавляю новый автомобиль. Имеет ли это какое-то отношение к ответу?
2. Нет, это не имеет никакого отношения к ответу. Ваш
CarRental-CRUD
сервис также основан на Spring WebFlux?3. Нет , он основан на интерфейсе JpaRepository
4. Вы подтвердили, что вызов достиг
CarRental-CRUD
контроллера с помощью точки останова или чего-то еще?5. Верно, но тогда ваше приложение не реагирует на 100%, так как в этот момент вы блокируете поток.
.block()
Следует избегать использования любой ценой в полностью реактивном приложении, и вы должны иметь дело сMono
типами данных иFlux
типами данных. Вместо.block()
того, чтобы пытаться.subscribe()
.