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.