Установите значение поля POJO на основе значения другого поля в Spring Boot

У меня есть простой класс POJO.

class POJO{
private boolean isEnabled,
private String field
}

У меня есть контроллер, который принимает RequestBody типа POJO. Как часть изменения я хочу включить проверку, чтобы, когда isEnabled имеет значение true в RequestBody, установите значение поля «TEST» (значение поля в RequestBody будет нулевым) и когда isEnabled имеет значение false, установите значение поля на значение, полученное от RequestBody

Я могу реализовать if...else... на контроллере/службе, но это требует большого количества репликации кода, особенно потому, что мне нужно установить несколько полей. Есть ли способ включить эту проверку в сам класс POJO?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
130
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вам просто нужно поместить логику в конструктор dto.

class POJO {
  private boolean isEnabled,
  private String field;

  public POJO (boolean isEnabled, String field) {
    this.isEnabled = isEnabled;
    this.field = isEnabled ? "TEST" : field;
  }
} 

Это может быть решением, но явный вызов конструктора POJO в контроллере мне не кажется хорошим решением, особенно потому, что мой RequestBody уже имеет тип POJO.

Ryan Fernandes 16.05.2024 19:28

Почему явный? Spring Web вызывает сам конструктор при сопоставлении объекта. Вы ничего для этого не делаете в контроллере

saddam.ya 16.05.2024 20:07

Я использую Lombok в своем классе POJO, и у меня есть несколько других полей, присутствующих в классе POJO, не зависящих от каких-либо других полей, если я создам конструктор с подписью public POJO (boolean isEnabled, String field) мне придется сделать явный вызов в контроллере, так как я вызывая это через конструктор Lomboks.

Ryan Fernandes 16.05.2024 20:19

Ломбок — это круто, и @AllArgsConstructor — это круто, но нужно помнить о механизмах Java. Если у вас несколько полей, просто поместите их в конструктор public POJO (boolean isEnabled, String field, String field1, String field1, ...) и просто this.field1 = field1; и т. д. и только this.field = isEnabled ? "TEST" : field;. Я считаю, что эту логику следует разместить в конструкторе, а лучше в бизнес-логике @Service. Извините, если я вас не до конца понимаю.

saddam.ya 16.05.2024 21:06

На основе описания вопроса

когда isEnabled имеет значение true в RequestBody, установите значение поля в «TEST» (значение поля в RequestBody будет нулевым)

getField(){
    return this.field == null && this.isEnabled? "TEST" : this.field.
}

Вам просто нужно убедиться, что вы не получаете доступ к field каким-либо другим способом, кроме геттерного.

Другие забавные варианты:

  1. Быстро, но подвержено ошибкам, и я бы не стал использовать его в производстве:
public void setField(String field) {
    this.field = isEnabled ? "TEST" : field;
}

Всякий раз, когда Джексон сопоставляет строку json с объектом Java, он вызывает сеттеры (если они присутствуют). Это будет работать, только если преобразователь объектов Джексона DEсериализует поле isEnabled перед полем field. Так, работает

"{\"isEnabled\":true,\"field\":\"fieldVal\"}"

не работает

"{\"field\":\"fieldVal\",\"isEnabled\":true}"
  1. Вы можете использовать пружинный фильтр и добавить его в методы контроллера. Таким образом, ваш код будет находиться только в одном месте и не будет дублирования кода. https://www.baeldung.com/spring-boot-change-request-body-before-controller
  2. Создайте собственный сериализатор/десериализатор сопоставителя объектов, это даст вам полный контроль над тем, как json отображается в объект Java. https://www.baeldung.com/jackson-deserialization
  3. Используйте AOP в методе контроллера, аспект будет работать как невидимая оболочка вокруг вашего метода, поэтому вы получите доступ к объекту RequestBody до его фактического использования. метод контроллера https://medium.com/trabe/cleaner-spring-mvc-controllers-using-aop-and-filters-41c89ac4f9d

Требование выглядит несколько необычно, и было бы неплохо узнать, зачем вообще вам нужна такая вещь. Есть много способов добиться этого, и лучшее понимание проблемы, которую вы пытаетесь решить, определенно поможет выбрать правильный.

Другие вопросы по теме