Нужна помощь в реализации @RequestBody POJO, инкапсулирующего карту - PullRequest
0 голосов
/ 14 мая 2019

Я хочу, чтобы в моем теле запроса POST был ключ «фильтры», представляющий собой карту типа фильтра и выбранной опции. Проблема в том, что мне нужен способ по существу сказать: «Хорошо, для этого ключа используйте эту реализацию класса интерфейса Filter и присвойте ему атрибут опции». Однако, пытаясь сделать это, я продолжаю получать эту ошибку, когда использую Postman, который говорит: «Неподдерживаемый тип носителя» «Тип содержимого« application / json; charset = UTF-8 'не поддерживается »

Проблема в том, что у контроллера нет проблем с другими методами, использующими другие POJO как RequestBody и отвечающими с application / json, но по какой-то причине этот объект не дает мне то, что я хочу.

Некоторые ресурсы с похожими проблемами, которые я пытался извлечь и понять, могу ли я решить свою собственную проблему.

Сохранение коллекции интерфейса с использованием Hibernate

JPA Map mapping

Когда использовать аннотацию DiscriminatorValue в спящем режиме

@RestController
public class ScheduleController {

    @Autowired
    Scheduler bruteForceScheduler;

    @PostMapping(path = "/generateSchedules",
            consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public ScheduleResponse scheduleRequest(@RequestBody ScheduleRequest request) {
        ScheduleResponse response = bruteForceScheduler.generate(request);
        return response;
    }
}
@Entity
public class ScheduleRequest {
    @Id
    @GeneratedValue
    private int id;
    @ElementCollection
    private List<Course> mandatory;
    @ElementCollection
    private List<Course> optional;
    @ElementCollection
    private Map<Filter, String> filters;

    // Getters/Setters
}
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING, name = "FILTER")
public class ScheduleResponse {
    @Id
    @GeneratedValue
    private int id;
    @ElementCollection
    private List<Schedule> schedules;
    @ElementCollection
    @MapKeyColumn (name = "FILTER")
    @Column(name = "OPTION")
    private Map<Filter, String> filters;

    // Getters/Setters
}
public interface Filter<T> extends Serializable {
    double getFitness(T o);
}
@MappedSuperclass
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class AbstractScheduleFilter {
    @Id
    @GeneratedValue
    private int id;

    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
}
@Entity
@DiscriminatorValue("Time")
public class TimeFilter extends AbstractScheduleFilter implements Filter<Schedule> {...}

Итак, в Postman общее тело POST должно выглядеть так:

{
  "mandatory": [],
  "optional": [],
  "filters": 
  {
    "Time": "Early"
  }
}

так, чтобы я мог иметь карту фильтров в качестве ключа «фильтров», а затем сказать «о, ключ« времени »для TimeFilter.java, поэтому создайте экземпляр этого класса и установите переменную« опция » как "Ранний". Однако я получаю только что описанную ранее ошибку Unsupported Media Type.

Некоторые альтернативы, которые я исследовал, - вместо этого использовать Map и ссылаться на файл свойств для создания экземпляра нужного класса, но с точки зрения добавления большего количества фильтров, кажется немного не элегантным редактировать файл свойств каждый раз, когда вы хочу добавить новый фильтр. Кроме того, я думал о том, чтобы просто сделать карту списком или набором, поскольку это не давало мне ошибку Unsupported Media Type, как это сделала карта, однако, я полагаю, это потребовало бы дополнительной обтекания объекта, что опять-таки не элегантный.

Пример использования списка вместо:

{
  "mandatory": [],
  "optional": [],
  "filters": 
  [
    {
      "type": "Time",
      "option": "Early"
    }
  ]
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...