使用JAXB / Jersey </foo>解组列表<foo>

时间:2012-02-15 11:20:40

标签: java jaxb jersey unmarshalling

我想编组/解组2种自定义类型。类型1有一个List。编组按预期工作 - 我在列表中看到每个type2元素的单独元素,但是当我尝试解组它时,这不起作用。

工作流

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

}

如果我从浏览器访问Web服务,这是一个示例输出:

   <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已成功编组/解组,但列表无法解组,为什么会这样?客户端只是忽略了WorkflowSteps列表,应用服务器和REST客户端也没有收到任何错误或异常?从上面的示例输出中,我希望每个元素都会转换为WorkflowStep类型的对象,然后会自动添加到List中吗?

1 个答案:

答案 0 :(得分:6)

问题出在这个方法上:

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

您的JAXB实现会检查此方法是否已有List,如果有,则使用它。您正在返回的List不是由您解组的对象保留的,因此在解组操作之后List将丢失。

选项#1 - 更改getSteps()方法

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

选项#2 - 使用字段访问

您可以将此更改指定JAXB应使用字段访问权。

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

了解更多信息