#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 Спасибо, полностью пропустил суть, обновлено.