Khi nào tài sản @JsonProperty được sử dụng và nó được sử dụng để làm gì?


183

Đậu này 'Nhà nước':

public class State {

    private boolean isSet;

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

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

}

được gửi qua dây bằng cách gọi lại ajax 'thành công':

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

Chú thích @JsonProperty có cần thiết ở đây không? Lợi thế của việc sử dụng nó là gì? Tôi nghĩ rằng tôi có thể loại bỏ chú thích này mà không gây ra bất kỳ tác dụng phụ nào.

Đọc về thông tin này trên https://github.com/FasterXML/jackson-annotations/wiki/Jackson- Chú thích Tôi không biết khi nào cần sử dụng?


Câu trả lời:


238

Đây là một ví dụ tốt. Tôi sử dụng nó để đổi tên biến vì JSON đến từ một .Netmôi trường nơi các thuộc tính bắt đầu bằng một chữ cái viết hoa.

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

Điều này phân tích chính xác đến / từ JSON:

"Parameter":{
  "Name":"Parameter-Name",
  "Value":"Parameter-Value"
}

1
Các biến thành viên Chuỗi không thể được đổi tên thành trường hợp chính xác của chúng, vì vậy tên Chuỗi công khai; trở thành Tên chuỗi công khai; ?
bầu trời xanh

14
Vâng, họ có thể, nhưng trong một môi trường Java khiến chúng không khớp với các tiêu chuẩn mã hóa. Đó là thông tin thêm về phương pháp giảng dạy của tôi về vấn đề mã hóa thực sự nhưng đây là một ví dụ đơn giản nhưng tốt về việc sử dụng @JsonPropertychú thích thực sự .
OldCurmudgeon

Chú thích này có thể được sử dụng cho các thành viên của loại Double? Tôi chỉ tự hỏi liệu loại này phải là Stringhoặc bất kỳ loại nào mà JSON hỗ trợ? Nó có thể là bất kỳ loại nào không? @OldCurmudgeon
Dreamer

3
@Dreamer Vâng. Các loại là không liên quan. Điều này chỉ ảnh hưởng đến tên .
OldCurmudgeon

1
@Pavan - Điều đó sẽ không liên quan gì đến việc đặt tên. Tôi đoán bạn nên kiểm tra setters của bạn.
OldCurmudgeon

44

Tôi nghĩ OldCurmudgeon và StaxMan đều đúng nhưng đây là một câu trả lời với ví dụ đơn giản cho bạn.

@JsonProperty (tên), nói với Jackson ObjectMapper ánh xạ tên thuộc tính JSON thành tên của trường Java được chú thích.

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

//where it gets mapped 
public static class Car {
  @JsonProperty("Type")
  public String type;
 }

Tên Class có giống với phần tử gốc của JSON không. Điều này không làm việc cho tôi.
Pavan

39

tốt cho giá trị của nó bây giờ ... JsonProperty được sử dụng để chỉ định các phương thức getter và setter cho biến ngoài việc tuần tự hóa và giải tuần tự hóa thông thường. Ví dụ: giả sử bạn có một trọng tải như thế này:

{
  "check": true
}

và một lớp 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;
  }
}

Sau đó, trong trường hợp này, chú thích JsonProperty được ghi lại. Tuy nhiên nếu bạn cũng có một phương thức trong lớp

public class Check {

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

  public Boolean getCheck() {
     return check;
  }
}

Hãy xem tài liệu này quá: http://fasterxml.github.io/jackson-annotations/javadoc/2.3.0/com/fasterxml/jackson/annotation/JsonProperty.html


15

Nếu không có chú thích, tên thuộc tính được suy ra (để khớp với JSON) sẽ được "đặt" và không - dường như là mục đích - "is set". Điều này là do theo đặc tả của Java Beans, các phương thức của biểu mẫu "isXxx" và "setXxx" được dùng để có nghĩa là có thuộc tính logic "xxx" để quản lý.


1
Đây là câu trả lời đúng cho trường hợp cụ thể được đưa ra trong câu hỏi
Andrew Spencer

6

Như bạn đã biết, đây là tất cả về tuần tự hóa và khử muối một đối tượng. Giả sử có một đối tượng:

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

Sự tuần tự hóa của đối tượng này là:

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

Tên của biến được sử dụng trực tiếp để tuần tự hóa dữ liệu. Nếu bạn chuẩn bị loại bỏ api hệ thống khỏi việc thực hiện hệ thống, trong một số trường hợp, bạn phải đổi tên biến trong tuần tự hóa / giải tuần tự hóa. @JsonProperty là một dữ liệu meta để báo cho serializer cách đối tượng nối tiếp. Nó được sử dụng để:

  • tên biến
  • truy cập (ĐỌC, VIẾT)
  • giá trị mặc định
  • bắt buộc / không bắt buộc

từ ví dụ:

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; 
}

6

Thêm JsonProperty cũng đảm bảo an toàn trong trường hợp ai đó quyết định họ muốn thay đổi một trong các tên thuộc tính không nhận ra lớp đang đề cập sẽ được nối tiếp thành đối tượng Json. Nếu họ thay đổi tên thuộc tính, JsonProperty đảm bảo nó sẽ được sử dụng trong đối tượng Json chứ không phải tên thuộc tính.


3

Ngoài các câu trả lời khác, @JsonPropertychú thích thực sự quan trọng nếu bạn sử dụng @JsonCreatorchú thích trong các lớp không có hàm tạo không có đối số.

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);
    }
}

Trong ví dụ này, hàm tạo duy nhất được đánh dấu là @JsonCreator, do đó Jackson sẽ sử dụng hàm tạo này để tạo cá thể. Nhưng đầu ra giống như:

Nối tiếp: {"stringValue": "ABCD", "myEnum": "FIRST"}

Ngoại lệ trong luồng "chính" com.fasterxml.jackson.databind.exc.InvalidFormatException: Không thể xây dựng thể hiện của ClassToSerialize $ MyEnum từ giá trị chuỗi 'stringValue': giá trị không phải là một trong các tên đối tượng Enum được khai báo: [FIRST, SEC]

Nhưng sau khi thêm @JsonPropertychú thích vào hàm tạo:

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

Quá trình khử lưu huỳnh thành công:

Nối tiếp: {"myEnum": "FIRST", "stringValue": "ABCD"}

StringValue: ABCD

MyEnum: ĐẦU TIÊN


2

Ngoài tất cả các câu trả lời ở trên, đừng quên phần tài liệu nói

Chú thích đánh dấu có thể được sử dụng để xác định phương thức không tĩnh là "setter" hoặc "getter" cho thuộc tính logic (tùy thuộc vào chữ ký của nó) hoặc trường đối tượng không tĩnh được sử dụng (tuần tự hóa, giải tuần tự hóa) làm logic bất động sản.

Nếu bạn có một non-staticphương thức trong lớp không phải là thông thường getter or setterthì bạn có thể làm cho nó hoạt động như một getter and setterbằng cách sử dụng chú thích trên nó. Xem ví dụ dưới đây

public class Testing {
    private Integer id;
    private String username;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getIdAndUsername() {
        return id + "." + username; 
    }

    public String concatenateIdAndUsername() {
        return id + "." + username; 
    }
}

Khi đối tượng trên được tuần tự hóa, thì phản hồi sẽ chứa

  • tên người dùng từ getUsername()
  • id từ getId()
  • idAndUsername từ getIdAndUsername*

Vì phương thức getIdAndUsernamebắt đầu getsau đó nên nó được coi là getter bình thường, vì vậy tại sao bạn có thể chú thích như vậy @JsonIgnore.

Nếu bạn nhận thấy rằng concatenateIdAndUsernamenó không được trả về và đó là vì tên của nó không bắt đầu getvà nếu bạn muốn kết quả của phương thức đó được đưa vào phản hồi thì bạn có thể sử dụng @JsonProperty("...")và nó sẽ được coi là bình thường getter/setternhư được đề cập trong tài liệu được tô sáng ở trên .


0

Từ javadoc JsonProperty,

Xác định tên của thuộc tính logic, tức là tên trường đối tượng JSON để sử dụng cho thuộc tính. Nếu giá trị là Chuỗi rỗng (là mặc định), sẽ cố gắng sử dụng tên của trường được chú thích.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.