简体   繁体   中英

Unmarshalling List<foo> with JAXB/Jersey

I want to marshal/unmarshal 2 custom types. And the type 1 has a List. Marshalling works as expected - I see a separate element for every type2 element in the list, but when I try to unmarshal it this doesn't work.

Workflow

@XmlRootElement
public class Workflow {

    private String userEmail;
    private List<WorkflowStep> steps = new ArrayList<WorkflowStep>(5);

    //required by jaxb
    public Workflow() { 

    }

    public void setSteps(List<WorkflowStep> steps) {
        this.steps = steps;
    }

    public List<WorkflowStep> getSteps() {
        //do a defensive copy
        return new ArrayList<WorkflowStep>(steps);
    }

    public void setUserEmail(String email) {
        userEmail = email;
    }

    public String getUserEmail() {
        return userEmail;
    }

}

WorkflowStep

@XmlRootElement
public class WorkflowStep {

    private int cpu = 1;
    private int mem = 1000;
    private Map<String, String> parameters = Collections.emptyMap();


    public WorkflowStep() { 

    }

    public void setCpu(int numCores) {
        cpu = numCores;
    }

    public int getCpu() { 
        return cpu;
    }

    public void setMem(int mb) {
        mem = mb;
    }

    public int getMem() {
        return mem;
    }

}

Here is an example output if I access the web service from a browser:

   <workflow>
    <steps>
        <cpu>1</cpu>
        <inputId>237</inputId>
        <mem>1000</mem>
        <parameters/>
        <status>NOT-YET-STARTED</status>
        <stepId>1509</stepId>
        <submoduleId>0</submoduleId>
        <workflowId>797</workflowId>
    </steps>
    <steps>
        <cpu>1</cpu>
        <inputId>364</inputId>
        <mem>1000</mem>
        <parameters/>
        <status>NOT-YET-STARTED</status>
        <stepId>1510</stepId>
        <submoduleId>3</submoduleId>
        <workflowId>797</workflowId>
    </steps>

    <userEmail>foo@bar.com</userEmail>
    <workflowId>797</workflowId>
    <workflowName>test-name</workflowName>
</workflow>

WorkflowStep is marshalled/unmarshalled successfully but a List cannot be unmarshalled why is that? Nor the application server, nor the REST client receive any errors or exceptions, the client just ignores the list of WorkflowSteps? From the above example output I'd expect that every element would be converted into an object of type WorkflowStep and then will automatically be added to the List?

The problem is with this method:

public List<WorkflowStep> getSteps() {
    //do a defensive copy
    return new ArrayList<WorkflowStep>(steps);
}

Your JAXB implementation checks if there is already a List for this method, and if there is it uses it. The List you are returning is not held by the object you are unmarshalling, so after the unmarshal operation the List is lost.

Option #1 - Change the getSteps() Method

public List<WorkflowStep> getSteps() {
    //don't do a defensive copy
    return steps;
}

Option #2 - Use Field Access

You could change this your specify that JAXB should use field access.

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Workflow {
   ...
}

For more information

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM