SlandShow
@SlandShow
70% of my body is made of movies.

Почему сервер выдаёт 500-ку при попытки вытянуть запись через REST по id?

У меня есть приложение A на Tomcat, приложение B на WildFly. Задача такая: приложение A имеет три REST-контроллера, которые:
  1. Выдают список всех расписаний на сегодня
  2. Выдают конкретное расписание по id
  3. Выдают список всех станций


Когда я запускаю оба приложения, приложение B вытаскивает сначала список всех расписаний поездов на сегодня.

Но теперь рассмотрим такой use-case. В приложении A меняется расписание (добавляется новая запись). A шлёт сообщение через брокер (RabbitMQ) B. Приложение B принимает сообщение и пытается вытащить новое расписание через REST-контроллер первого приложения по id-шнику. И вот именно тут происходят проблемы.

Итак, давайте сначала покажу код самого REST-контроллера:
@RestController
public class BoardScheduleController {

    private static final Logger LOGGER = Logger.getLogger(BoardScheduleController.class);

    @Autowired
    ScheduleService scheduleService;

    @Autowired
    StationService stationService;

    @GetMapping("/api/board/schedule/today")
    public ResponseEntity<?> getSchedulesForToday() {
        List<ScheduleDTO> schedules = null;
        try {
            schedules = scheduleService.getAllForToday();
        } catch (ParseException e) {
            e.printStackTrace();
        }

        LOGGER.info("RETRIEVED " + schedules.size() + " RECORDS");
        return ResponseEntity.ok(schedules);
    }

    @GetMapping("/api/board/stations")
    public ResponseEntity<?> getStationList() {
        List<StationDTO> stations = stationService.getAll();

        LOGGER.info("RETRIEVED " + stations.size() + " RECORDS");
        return ResponseEntity.ok(stations);
    }

    @GetMapping("/api/board/schedule/{id}")
    public ResponseEntity<?> getScheduleById(@PathVariable Long id) {
        ScheduleDTO schedule = scheduleService.getByIdScheduleDTO(id);
        LOGGER.info("DTO: " + schedule.getStationDepartureName() + " -> " + schedule.getStationArrivalName() + " (" + schedule.getDateDeparture() + " --> " + schedule.getDateArrival() + ")");
        LOGGER.info("RETRIEVED " + schedule + " SCHEDULER");
        return ResponseEntity.ok(schedule);
    }

}


Итак, когда в service-слое первого приложения отправляется сообщение о том, что появилось изменение в расписании (создалось новое). Затем, когда это сообщение успешно читаетListener, второе приложение пытается вытащить оное по id (id новой записи у меня передаётся в самом сообщении в виде строки).

В логах видно, что оно читается:
INFO    2018-10-12 22:49:33,799 [pool-9-thread-4] com.slandshow.helpers.Listener  -  [x] Received 'create id=46'
INFO    2018-10-12 22:49:33,800 [pool-9-thread-4] com.slandshow.helpers.Listener  - create id=46


Теперь пытаемся вытащить данную запись через REST по id = 46:
public Schedule getById(Long id) {
        String response = getResultResponse(Utils.URL_SCHEDULE_BY_ID + id);
        Schedule schedule = null;
        try {
            log.info(response);
            schedule = objectMapper.readValue(response, new TypeReference<Schedule>() {
            });
        } catch (IOException e) {
            log.error("ERROR, CAN'T LOAD SCHEDULE BY ID " + e.getMessage());
        }
        return schedule;
    }

    ...
  // Внутри класса Loader использую эту функцию для того, чтобы вытащить JSON по REST'у
   private String getResultResponse(String URL) {
        WebResource webResource = client.resource(URL);
        return webResource.accept(MediaType.APPLICATION_JSON).get(ClientResponse.class).getEntity(String.class);
    }


Ну и да, внутри второго приложения используется балванка Schedule:
public class Schedule implements Serializable {

    private Long id;

    private String dateDeparture;

    private String dateArrival;

    private String trainName;

    private String stationDepartureName;

    private String stationArrivalName;

    private Integer price;

    /* Getters & setters */
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }

    public String getDateDeparture() { return dateDeparture; }
    public void setDateDeparture(String dateDeparture) { this.dateDeparture = dateDeparture; }

    public String getDateArrival() { return dateArrival; }
    public void setDateArrival(String dateArrival) { this.dateArrival = dateArrival; }

    public String getTrainName() { return trainName; }
    public void setTrainName(String train) { this.trainName = trainName; }

    public String getStationDepartureName() { return stationDepartureName; }
    public void setStationDepartureName(String stationDeparture) { this.stationDepartureName = stationDeparture; }

    public String getStationArrivalName() { return stationArrivalName; }
    public void setStationArrival(String stationArrival) { this.stationArrivalName = stationArrival; }

    public Integer getPrice() {
        return price;
    }
    public void setPrice(Integer price) {
        this.price = price;
    }
}


Так вот, когда выполняется ретривинг данных через REST, я получаю реквестом 500-ку. Вернее, я получаю строковое представление странички с 500-ой, где написано это:
java.lang.IllegalArgumentException: source cannot be null


Не понимаю, что не так? REST-контроллер должен работать верно, ведь список поездов и расписаний он отправляет, а по id не может найти (вручную проверял и он возвращает действительно валидный JSON).
  • Вопрос задан
  • 128 просмотров
Пригласить эксперта
Ответы на вопрос 1
profesor08
@profesor08
Если 500, значит сервер выдал непредвиденную ошибку, бросил исключение. Так вот смотри где оно возникает и смотри почему.
Приведенный код бесполезен, тут даже отсутствует код, где вылетает исключение. В логе тебе прям разжевали, где ошибка и какая ошибка. Проверь какие туда приходят данные и откуда они такие приходят.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы