Когда используется свойство @JsonProperty и для чего оно используется?

112

Это bean 'State':

public class State {

    private boolean isSet;

    @JsonProperty("isSet")
    public boolean isSet() {
        return isSet;
    }

    @JsonProperty("isSet")
    public void setSet(boolean isSet) {
        this.isSet = isSet;
    }

}

отправляется по кабелю с использованием обратного вызова ajax 'success':

        success : function(response) {  
            if(response.State.isSet){   
                alert('success called successfully)
            }

Требуется ли здесь аннотация @JsonProperty? В чем преимущество его использования? Я думаю, что я могу удалить эту аннотацию, не вызывая никаких побочных эффектов.

Чтение об этом аннотации на https://github.com/FasterXML/jackson-annotations/wiki/Jackson-Annotations Я не знаю, когда это необходимо для использования?

Теги:
jackson

8 ответов

157
Лучший ответ

Вот хороший пример. Я использую его для переименования переменной, потому что JSON исходит из среды .Net, где свойства начинаются с буквы верхнего регистра.

public class Parameter {
  @JsonProperty("Name")
  public String name;
  @JsonProperty("Value")
  public String value; 
}

Это правильно разбирает/из JSON:

"Parameter":{
  "Name":"Parameter-Name",
  "Value":"Parameter-Value"
}
  • 0
    Могут ли переменные-члены String не быть переименованы в их правильном регистре, поэтому public String name; становится общедоступным String Name; ?
  • 11
    Да, они могут, но в среде Java, которая делает их не соответствующими стандартам кодирования. Это больше о моей педантичности, что реальная проблема кодирования, но это хороший, но простой пример реального использования аннотации @JsonProperty .
Показать ещё 6 комментариев
27

хорошо для того, что стоит сейчас... JsonProperty ТАКЖЕ используется для указания методов getter и setter для переменной, кроме обычной сериализации и десериализации. Например, предположим, что у вас есть такая полезная нагрузка:

{
  "check": true
}

и класс Deserializer:

public class Check {

  @JsonProperty("check")    // It is needed else Jackson will look got getCheck method and will fail
  private Boolean check;

  public Boolean isCheck() {
     return check;
  }
}

Затем в этом случае аннотирование JsonProperty подбирается. Однако, если у вас также есть метод в классе

public class Check {

  //@JsonProperty("check")    Not needed anymore
  private Boolean check;

  public Boolean getCheck() {
     return check;
  }
}

Посмотрите также на эту документацию: http://fasterxml.github.io/jackson-annotations/javadoc/2.3.0/com/fasterxml/jackson/annotation/JsonProperty.html

27

Я думаю, что OldCurmudgeon и StaxMan верны, но вот один ответ предложения с простым примером для вас.

@JsonProperty (имя), сообщает Jackson ObjectMapper, чтобы сопоставить имя свойства JSON с именем аннотированного имени Java.

//example of json that is submitted 
"Car":{
  "Type":"Ferrari",
}

//where it gets mapped 
public static class Car {
  @JsonProperty("Type")
  public String type;
 }
  • 0
    Имя класса должно совпадать с корневым элементом JSON. Это не работает для меня.
9

Без аннотаций, выведенное имя свойства (в соответствии с JSON) будет "установлено", а не - как кажется намерение - "isSet". Это связано с тем, что в соответствии со спецификацией Java Beans методы формы "isXxx" и "setXxx" воспринимаются как означающие, что для управления существует логическое свойство "xxx".

  • 0
    Это правильный ответ для конкретного случая, приведенного в вопросе.
3

Как вы знаете, все это связано с сериализацией и опреснением объекта. Предположим, что существует объект:

public class Parameter {
  public String _name;
  public String _value; 
}

Сериализация этого объекта:

{
  "_name": "...",
  "_value": "..."
}

Имя переменной напрямую используется для сериализации данных. Если вы собираетесь удалить систему api из системной реализации, в некоторых случаях вам нужно переименовать переменную в сериализации/десериализации. @JsonProperty - это метаданные, чтобы рассказать сериализатору как к серийному объекту. Он используется для:

  • имя переменной
  • доступ (READ, WRITE)
  • значение по умолчанию
  • требуется/факультативная

из примера:

public class Parameter {
  @JsonProperty(
        value="Name",
        required=true,
        defaultValue="No name",
        access= Access.READ_WRITE)
  public String _name;
  @JsonProperty(
        value="Value",
        required=true,
        defaultValue="Empty",
        access= Access.READ_WRITE)
  public String _value; 
}
2

В дополнение к другим ответам аннотация @JsonProperty действительно важна, если вы используете аннотацию @JsonCreator в классах, не имеющих конструктора no-arg.

public class ClassToSerialize {

    public enum MyEnum {
        FIRST,SECOND,THIRD
    }

    public String stringValue = "ABCD";
    public MyEnum myEnum;


    @JsonCreator
    public ClassToSerialize(MyEnum myEnum) {
        this.myEnum = myEnum;
    }

    public static void main(String[] args) throws IOException {
        ObjectMapper mapper = new ObjectMapper();

        ClassToSerialize classToSerialize = new ClassToSerialize(MyEnum.FIRST);
        String jsonString = mapper.writeValueAsString(classToSerialize);
        System.out.println(jsonString);
        ClassToSerialize deserialized = mapper.readValue(jsonString, ClassToSerialize.class);
        System.out.println("StringValue: " + deserialized.stringValue);
        System.out.println("MyEnum: " + deserialized.myEnum);
    }
}

В этом примере единственный конструктор отмечен как @JsonCreator, поэтому Джексон будет использовать этот конструктор для создания экземпляра. Но результат выглядит так:

Сериализованный: {"stringValue": "ABCD", "myEnum": "FIRST"}

Исключение в потоке "main" com.fasterxml.jackson.databind.exc.InvalidFormatException: невозможно создать экземпляр com.avl.mbdtool.verificationmodule.exceptiondocument.ClassToSerialize $ MyEnum из значения String 'stringValue': значение не одно из объявленного экземпляра Enum имена: [FIRST, SECOND, THIRD]

Но после добавления аннотации @JsonProperty в конструкторе:

@JsonCreator
public ClassToSerialize(@JsonProperty("myEnum") MyEnum myEnum) {
    this.myEnum = myEnum;
}

Успех десериализации:

Сериализованный: {"myEnum": "FIRST", "stringValue": "ABCD"}

StringValue: ABCD

MyEnum: FIRST

1

Добавление JsonProperty также гарантирует безопасность в случае, если кто-то решит, что хочет изменить одно из имен свойств, не понимая, что рассматриваемый класс будет сериализован для объекта Json. Если они изменят имя свойства, JsonProperty гарантирует, что он будет использоваться в объекте Json, а не в имени свойства.

0

Из JsonProperty javadoc,

Определяет имя логического свойства, то есть имя поля объекта JSON для использования для свойства. Если значение пустое String (которое является значением по умолчанию), попытается использовать имя аннотированного поля.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню