Только использование @JsonIgnore во время сериализации, но не десериализация
У меня есть пользовательский объект, который отправляется на сервер и с него. Когда я отправляю объект пользователя, я не хочу отправлять хешированный пароль клиенту. Поэтому я добавил @JsonIgnore
в свойство пароля, но это также блокирует его от десериализации в пароль, что затрудняет регистрацию пользователей, когда у них нет пароля.
Как я могу получить @JsonIgnore
только для сериализации, а не для десериализации? Я использую Spring JSONView, поэтому у меня нет тонны контроля над ObjectMapper
.
Вещи, которые я пробовал:
- JsonMappingException: не найдено подходящего конструктора для типа : невозможно создать экземпляр из объекта JSON
- Дессериализация Json в другую иерархию classов с использованием Jackson
- Как настроить MappingJacksonHttpMessageConverter, используя конфигурацию с пружинной аннотацией?
- Как сопоставить имена полей JSON для разных имен полей объектов?
- Добавить
@JsonIgnore
в собственность - Добавить
@JsonIgnore
только для метода получения
Точно, как это сделать, зависит от версии jacksonа, которую вы используете. Это изменилось около версии 1.9 , до этого вы могли бы сделать это, добавив @JsonIgnore
к получателю.
Что вы пробовали:
Добавить @JsonIgnore только для метода получения
Сделайте это, а также добавьте конкретную аннотацию @JsonProperty
для имени поля «пароль» JSON для метода setter для пароля на вашем объекте.
В более поздних версиях Jackson добавлены READ_ONLY
и WRITE_ONLY
аргументы annotations для JsonProperty
. Таким образом, вы также можете сделать что-то вроде:
@JsonProperty(access = Access.WRITE_ONLY) private String password;
Документы можно найти здесь .
Чтобы добиться этого, все, что нам нужно, это две annotations:
-
@JsonIgnore
-
@JsonProperty
Используйте @JsonIgnore
для члена classа и его получателя. Используйте @JsonProperty
для своего сеттера.
Пример иллюстрации поможет сделать это:
class User{ // More fields here @JsonIgnore private String password; @JsonIgnore public String getPassword() { return password; } @JsonProperty public void setPassword(String password) { this.password = password; } }
Начиная с версии 2.6: более интуитивным способом является использование annotations com.fasterxml.jackson.annotation.JsonProperty
в поле:
@JsonProperty(access = Access.WRITE_ONLY) private String myField;
Даже если геттер существует, значение поля исключается из сериализации.
JavaDoc говорит:
/** * Access setting that means that the property may only be written (set) * for deserialization, * but will not be read (get) on serialization, that is, the value of the property * is not included in serialization. */ WRITE_ONLY
Если вам это нужно наоборот, просто используйте Access.READ_ONLY
.
В моем случае у меня есть автоматическая сериализация / десериализация объектов Jackson, которые я возвращаю с controllerа Spring MVC (я использую @RestController с Spring 4.1.6). Мне пришлось использовать com.fasterxml.jackson.annotation.JsonIgnore
вместо org.codehaus.jackson.annotate.JsonIgnore
, иначе он просто ничего не делал.
"user": { "firstName": "Musa", "lastName": "Aliyev", "email": "[email protected]", "passwordIn": "98989898", (or encoded version in front if we not using https) "country": "Azeribaijan", "phone": "+994707702747" }
@CrossOrigin(methods=RequestMethod.POST) @RequestMapping("/public/register") public @ResponseBody MsgKit registerNewUsert(@RequestBody User u){ root.registerUser(u); return new MsgKit("registered"); }
@Service @Transactional public class RootBsn { @Autowired UserRepository userRepo; public void registerUser(User u) throws Exception{ u.setPassword(u.getPasswordIn()); //Generate some salt and setPassword (encoded - salt+password) User u=userRepo.save(u); System.out.println("Registration information saved"); } }
@Entity @JsonIgnoreProperties({"recordDate","modificationDate","status","createdBy","modifiedBy","salt","password"}) public class User implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy=GenerationType.AUTO) private Long id; private String country; @Column(name="CREATED_BY") private String createdBy; private String email; @Column(name="FIRST_NAME") private String firstName; @Column(name="LAST_LOGIN_DATE") private Timestamp lastLoginDate; @Column(name="LAST_NAME") private String lastName; @Column(name="MODIFICATION_DATE") private Timestamp modificationDate; @Column(name="MODIFIED_BY") private String modifiedBy; private String password; @Transient private String passwordIn; private String phone; @Column(name="RECORD_DATE") private Timestamp recordDate; private String salt; private String status; @Column(name="USER_STATUS") private String userStatus; public User() { } // getters and setters }