Игнорировать свойство в Dto из базы данных RequestBody в конечной точке (использовать один Dto для двух целей)

#java #spring #spring-boot #dto

#java #весна #весенняя загрузка #dto

Вопрос:

У меня есть таблица купонов в базе данных, поэтому в приложении есть CouponEntity и CouponDto. Мой вопрос касается обработки двух конечных точек с помощью одного Dto. например, у меня есть конечные точки создания и обновления, обе они используют CouponDto. Существует бизнес-роль, из-за которой я не могу обновить code свойство объекта купона. Как игнорировать это, если клиент передает это свойство в запросе?

Если я использую @JsonIgnore , свойство будет проигнорировано в обеих конечных точках, которые мне нужны, чтобы получить его в create API. Я использовал groups для проверок и отдельных проверок друг от друга, но @JsonIgnore иногда не могу быть установлен.

Для создания купона:

 @PostMapping("/create")
public ResponseEntity<?> createCoupon(@RequestBody CouponCodeDTO couponCodeDTO) {
    return ResponseEntity.ok(couponService.create(couponCodeDTO));
}
  

Для обновления купона:

 @PutMapping("/update/{id}")
public ResponseEntity<?> updateCoupon(
    @PathVariable Long id, @RequestBody CouponCodeDTO couponCodeDTO
) {
    return ResponseEntity.ok(couponService.update(id, couponCodeDTO));
}
  

И CouponDto:

 public class CouponCodeDto extends BaseDto<Integer> {

    @NotBlank
    private String code;

    private Integer availableCount;

    @NotNull
    private LocalDate startDate;
    
   ...
}
  

Комментарии:

1. Попробуйте использовать @JsonFilter и FilterProvider . Проверьте также эту ссылку — dzone.com/articles/spring-web-service-response-filtering

2. @Mahesh_Loya Спасибо за ваш ответ, но статья посвящена фильтрации ответов, и я хочу отфильтровать request , чтобы убедиться, что нежелательное свойство не обновляется.

3. В общем, ваши DTO не должны «избегать» вашего уровня контроллера; точная задача уровня контроллера — переводить между HTTP-стороной вещей и вашей внутренней моделью данных. В случае, когда контроллер обрабатывает отображение DTO на бизнес-объект, довольно легко настроить ваш mapper (например, MapStruct ) для игнорирования определенных полей на входящих объектах.

Ответ №1:

Вы можете использовать @JsonView , чтобы указать поле, которое вы хотите сериализовать / десериализовать для каждого представления, и указать представление в конечной точке.

 public class Views {
    interface Update {}
    interface Create extends Update {}
}

public class CouponCodeDto extends BaseDto<Integer> {

    @NotBlank
    @JsonView(Views.Create.class)
    private String code;

    @JsonView(Views.Update.class)
    private Integer availableCount;

    @NotNull
    @JsonView(Views.Update.class)
    private LocalDate startDate;
    
   ...
}
  

И использовать в теле запроса конечной точки

 @PutMapping("/update/{id}")
public ResponseEntity<?> updateCoupon(@PathVariable Long id, 
                   @JsonView(Views.Update.class) @RequestBody CouponCodeDTO couponCodeDTO) {

@PostMapping("/create")
public ResponseEntity<?> createCoupon(
                   @JsonView(Views.Create.class) @RequestBody CouponCodeDTO couponCodeDTO) {
  

Здесь вы найдете подробную информацию

https://www.baeldung.com/jackson-json-view-annotation

https://spring.io/blog/2014/12/02/latest-jackson-integration-improvements-in-spring

Комментарии:

1. Спасибо за ваш ответ, но, похоже, вы настраиваете представление ответа контроллера, мне нужно отфильтровать request , чтобы убедиться, что нежелательное свойство не обновляется.

2.@MahmoodKohansal Это будет работать как при сериализации, так и при десериализации. Вы пробовали? Вы можете прочитать официальный документ @JsonView здесь

3. Я пробую код и ищу @JsonView для ввода управляющего запроса, я обнаружил, что помещая аннотацию перед @RequestMapping аннотации управляют и фильтруют ответы, для управляющего запроса аннотация @JsonView должна быть помещена перед @RequestBody, что-то вроде: @PutMapping("{id}") public ResponseEntity<?> updateCoupon( @PathVariable Long id, @JsonView(Views.Update.class) @RequestBody CouponCodeDTO couponCodeDTO ) { пожалуйста, отредактируйте ответ, чтобы принять его.

4. @MahmoodKohansal Спасибо, полностью пропустил суть, обновлено.