garyM
garyM

Reputation: 892

Jersey JSON/JAXB Ignoring or not seeing "some" public properties in POJO

I have a POJO I'm attempting to serialize with jersey as a rest api response. Only some of the properties are serialized. The values returned by the getters are not null.

If I attempt to order the properties, an IllegalAnnotationExceptions is thrown for the "missing" properties, as if they were not there.

I have several other POJOs working without issue. I have one object with no properties seen and one with 7 of 10 properties seen.

Can someone clue me in to what is going on ? and suggest how to fix it ?

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import java.io.Serializable;
import java.util.Date;

@XmlType(propOrder = { "startDateTime","endDateTime","durationMinutes","remainingMinutes","percentComplete","nodesDiscovered","nodesTried",
                        "totalNodes", "discoveryCompleted","canceledFlag" })
@XmlRootElement
public class DiscoveryStatus implements Serializable {
    private Number discoveryCompleted=0;
    private Date  startDateTime = new Date();
    private Date  endDateTime  = new Date();

    private Number startMS =20;
    private Number currMS =20;

    private Number durationMinutes =AppSettings.DiscoveryNodeMulticastDurationMins;
    private Number remainingMinutes =20;

    private Boolean canceledFlag=false;
    private Number percentComplete =0;
    private Number nodesDiscovered =0;
    private Number nodesTried =0;
    private Number totalNodes =0;

    public DiscoveryStatus(){
        totalNodes =1;
    }

    // Seen
    public Date getStartDateTime(){
        return this.startDateTime;
    }

    // Seen
    public Number getDurationMinutes(){
        return this.durationMinutes;
    }

    public Number getRemainingMinutes(){
        return this.remainingMinutes;
    }

    // Seen
    public Date getEndDateTime(){
        return this.endDateTime;
    }

    public Number getDiscoveryCompleted(){
        return this.discoveryCompleted;
    }

    public Boolean getCanceledFlag(){
        return this.canceledFlag;
    }

    // Seen
    public Number getPercentComplete(){
        return this.percentComplete;
    }

    // Seen
    public Number getNodesDiscovered(){
        return this.nodesDiscovered;
    }

    // Seen
    public Number getNodesTried(){
        return this.nodesTried;
    }

    // Seen
    public Number getTotalNodes(){
        return this.totalNodes;
    }

    public Number setDiscoveryCompleted(boolean discoveryCompleted ) {
        // gm this.discoveryCompleted =discoveryCompleted;
        return this.discoveryCompleted;
    }

    public Number setPercentComplete (Number percentComplete) {
        this.percentComplete =percentComplete;
        return this.percentComplete;
    }

    public Number setNodesDiscovered(Number nodesDiscovered) {
        this.nodesDiscovered =nodesDiscovered;
        return this.nodesDiscovered;
    }

    public Number setNodesTried(Number nodesTried) {
        this.nodesTried =nodesTried;
        return this.nodesTried;
    }

    public Number setTotalNodes(Number totalNodes) {
        this.totalNodes =totalNodes;
        return this.totalNodes;
    }

    public Date setStartDateTime(Date  startDateTime) {
        this.startDateTime = startDateTime;
        return this.startDateTime;
    }

    public Date setStartDateTime() {
        this.startDateTime = new Date();
        return this.startDateTime;
    }

    public Date setEndDateTime(Date  endDateTime) {
        this.endDateTime = endDateTime;
        return this.endDateTime;
    }

    public Date setEndDateTime() {
        this.endDateTime = new Date();
        return this.endDateTime;
    }

    public Number setDurationMinutes(Number  durationMinutes) {
        this.durationMinutes = durationMinutes;
        return this.durationMinutes;
    }

    public Number setDurationMinutes() {
        this.durationMinutes = AppSettings.DiscoveryNodeMulticastDurationMins;
        return this.durationMinutes;
    }

}

Upvotes: 1

Views: 1752

Answers (2)

bdoughan
bdoughan

Reputation: 149017

Problems with Your Model

There are a few problems with your model:

Getter with no Setter

By default JAXB Will not consider a get method without a corresponding set method as a property. However if you annotate it with @XmlElement then it will.

@XmlElement
public Number getRemainingMinutes(){
    return this.remainingMinutes;
}

@XmlElement
public Boolean getCanceledFlag(){
    return this.canceledFlag;
}

Mismatched Get/Set Methods

JAXB will expect the return type from the get method to match the parameter type for the set method.

public Number getDiscoveryCompleted(){
    return this.discoveryCompleted;
}

public Number setDiscoveryCompleted(boolean discoveryCompleted ) {
    // gm this.discoveryCompleted =discoveryCompleted;
    return this.discoveryCompleted;
}

Solution to Both Problems

Instead of using the default property access, you can use the @XmlAccessorType annotation to tell JAXB to use field access. For your model this will mean annotating a couple of your unmapped fields with @XmlTransient (see: http://blog.bdoughan.com/2012/04/jaxb-and-unmapped-properties.html).

import javax.xml.bind.annotation.*;

import java.io.Serializable;
import java.util.Date;

@XmlType(propOrder = { "startDateTime","endDateTime","durationMinutes","remainingMinutes","percentComplete","nodesDiscovered","nodesTried",
                        "totalNodes", "discoveryCompleted","canceledFlag" })
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class DiscoveryStatus implements Serializable {
    private Number discoveryCompleted=0;
    private Date  startDateTime = new Date();
    private Date  endDateTime  = new Date();

    @XmlTransient
    private Number startMS =20;

    @XmlTransient
    private Number currMS =20;

    private Number durationMinutes =AppSettings.DiscoveryNodeMulticastDurationMins;
    private Number remainingMinutes =20;

    private Boolean canceledFlag=false;
    private Number percentComplete =0;
    private Number nodesDiscovered =0;
    private Number nodesTried =0;
    private Number totalNodes =0;

    public DiscoveryStatus(){
        totalNodes =1;
    }

}

For More Information

Upvotes: 2

Juned Ahsan
Juned Ahsan

Reputation: 68715

Your boolean getter is not as per the convention required. For example:

getCanceledFlag should be isCanceledFlag

To avoid such issues, try putting annotation on your getters. Here is an example:

 @XmlElement
public Number getRemainingMinutes(){

Upvotes: 0

Related Questions