users@jsonb-spec.java.net

[jsonb-spec users] Re: JsonbPropertyOrder annotation behaviour

From: Dmitry Kornilov <dmitry.kornilov_at_oracle.com>
Date: Thu, 11 May 2017 15:26:28 +0200

I did some closer look on this. It looks like both implementations are doing it wrong and some clarification in the spec is needed for this use case.

 

I came out with the following rules:

 

1. Properties names specified in @JsonbPropertyOrder annotation must be the original names of properties as it’s specified in Java class. In the sample provided below its "personGender","personName", "personAge".

2. Properties NOT specified in @JsonbPropertyOrder annotation are serialized AFTER properties specified there.

3. If property specified in @JsonbPropertyOrder annotation doesn’t exist it’s ignored and no exception is thrown.

 

Based on that the correct behaviour of your sample code is the following:

 

1) @JsonbPropertyOrder(value = {"personGender","personName", "personAge"})

               

Correct: {"person_gender":"Male","person_name":"David","person_age":12}

Current Yasson: {"person_gender":"Male","person_name":"David","person_age":12}

Current Johnzon: {"person_name":"David","person_age":12,"person_gender":"Male"}


2) @JsonbPropertyOrder(value = {"person_gender","person_name", "person_age"})

 

Correct: property order is not specified because property names in @JsonbPropertyOrder are not corresponding with Java class property names
Current Yasson: {}
Current Johnzon: {"person_gender":"Male","person_name":"David","person_age":12} technically it’s correct, but ANY order is correct in this use case

3) @JsonbPropertyOrder(value = {"personGender", "personAge"})

 

Correct: {"person_gender":"Male","person_age":12,"person_name":"David"}

Current Yasson: {"person_gender":"Male","person_age":12} – person_name is missing
Current Johnzon: {"person_name":"David","person_gender":"Male","person_age":12}  - person_name must be the last one

 

Reflecting these changes I am proposing changing JsonbPropertyOrder class Javadoc to this:

 

/**
 * <p>Specifies order in which properties are serialized.</p>
 *
 * <p>Partial mapping can also be specified. In that case, properties included
 * in annotation declaration will be serialized first (in defined order), followed
 * by any properties not included in the definition. The order of properties not
 * included in the definition is not guaranteed.</p>
 *
 * @since JSON Binding 1.0
 */
@JsonbAnnotation
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
public @interface JsonbPropertyOrder {

    /**
     * Order in which properties are serialized. Names must
     * correspond to original names defined in Java class before any customization
     * applied.
     */
    String[] value();
}

 

WDYT?

 

Thanks,

Dmitry

 

From: Romain Manni-Bucau <rmannibucau_at_tomitribe.com>
Reply-To: <users_at_jsonb-spec.java.net>
Date: Wednesday, 10 May 2017 at 13:47
To: <users_at_jsonb-spec.java.net>
Subject: [jsonb-spec users] Re: JsonbPropertyOrder annotation behaviour

 

Will copy my answer on johnzon list just cause not the same people watch these 2 lists:

 

In the spec you will find (4.2):

 

To customize the order of serialized properties only for one specific type, JSON Binding provides javax.json.bind.annotation.JsonbPropertyOrder annotation. Order specified by JsonbPropertyOrder annotation overrides order specified by PropertyOrderStrategy. The order is applied to already renamed properties as stated in 4.1.

 

So for me Johnzon looks right in that regard.

 

I think the missing property case is unspecified - didnt find it at least - but like the fact we respect the order of the specified ones and add other ones. If it is intended to be ignored there is the ignore annotation so sounds good for me.

 

Do you read it differently?


 

Romain Manni-Bucau

@rmannibucau

http://www.tomitribe.com

https://blog-rmannibucau.rhcloud.com

https://github.com/rmannibucau

 

2017-05-10 13:44 GMT+02:00 Ravisankar Challa <ravisankar2_at_gmail.com>:

Hi there,

I am evaluation jsob implementations yasson and apache johnzon.

I found some differences in the way the @JsonbPropertyOrder annotation is treated by the two implementations.

Could you please confirm whether the yasson implementation is as per the spec for the below scenarios.

 

This is my pojo.


@JsonbPropertyOrder(value = {"personGender","personName", "personAge"})
public class Person {
    
    private String personName;
    private int personAge;
    private String personGender;
 
    public String getPersonName() {
        return personName;
    }
    public void setPersonName(String name) {
        this.personName = name;
    }
    public int getPersonAge() {
        return personAge;
    }
    public void setPersonAge(int age) {
        this.personAge = age;
    }
    public String getPersonGender() {
        return personGender;
    }
    public void setPersonGender(String personGender) {
        this.personGender = personGender;
    }
}

JsonbConfig config = new JsonbConfig().withPropertyNamingStrategy(PropertyNamingStrategy.LOWER_CASE_WITH_UNDERSCORES);
        Jsonb jsonb = JsonbBuilder.create(config);
        Person p = new Person();
        p.setPersonAge(12);
        p.setPersonName("David");
        p.setPersonGender("Male");
        System.out.println(jsonb.toJson(p));

1) @JsonbPropertyOrder(value = {"personGender","personName", "personAge"})

  Yasson: {"person_gender":"Male","person_name":"David","person_age":12}

  Johnzon: {"person_name":"David","person_age":12,"person_gender":"Male"} -- incorrect

When should the property order should be applied before or after the filled is tranformed ?


2) @JsonbPropertyOrder(value = {"person_gender","person_name", "person_age"})
   Yasson: {} - empty json object
  Johnzon: {"person_gender":"Male","person_name":"David","person_age":12} -- correct

3)@JsonbPropertyOrder(value = {"personGender", "personAge"})

  Yasson: {"person_gender":"Male","person_age":12} -- If a field name is not specified in property order it is ignored
  @JsonbPropertyOrder(value = {"person_gender", "person_age"})
  {"person_name":"David","person_gender":"Male","person_age":12} -- all the fields are serialized;

Yasson pom.xml
<dependencies>
   <dependency>
        <groupId>javax.json.bind</groupId>
        <artifactId>javax.json.bind-api</artifactId>
        <version>1.0.0-M2</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse</groupId>
        <artifactId>yasson</artifactId>
        <version>1.0.0-M2</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish</groupId>
        <artifactId>javax.json</artifactId>
        <version>1.1.0-M2</version>
    </dependency>
  </dependencies>
  
  <repositories>
    <!-- Needed for Yasson -->
    <repository>
        <id>yasson-releases</id>
        <name>Yasson Snapshots repository</name>
        <url>https://repo.eclipse.org/content/repositories/yasson-releases</url>
    </repository>
</repositories>