Неподдерживаемый тип носителя Spring Boot REST API

#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() .