JAXB错误:解组时出现意外元素

时间:2012-04-12 20:50:26

标签: java jaxb jersey jax-rs

有人可以帮我理解为什么我会收到此错误:

javax.xml.bind.UnmarshalException:意外元素(uri:“”,local:“items”)。预期元素为< {} item>

我是JAX-B的新手但是整天都被困在这一天,我真的不明白发生了什么事情,非常感谢任何帮助,非常感谢。

项目类别:

@XmlRootElement

public class Item {

private String itemID;
private String itemDescription;

//need to have a constructor with no params
public Item(){

}

//Constructor: sets object vars
public Item(String itemID, String itemDescription) {

    this.itemID = itemID;
    this.itemDescription = itemDescription;
}

@XmlAttribute
//getters and setters
public String getID() {
    return itemID;
}

public void setId(String id) {
    itemID= id;
}

@XmlElement
public String getDescription() {
    return itemDescription;
}

public void setDescription(String description) {
    itemDescription = description;
}

解组代码:

resource = client.resource("http://localhost:8080/testProject/rest/items");
    ClientResponse response= resource.get(ClientResponse.class);
    String entity = response.getEntity(String.class);

    System.out.println(entity);

    JAXBContext context = JAXBContext.newInstance(Item.class);
    Unmarshaller um = context.createUnmarshaller();
    Item item = (Item) um.unmarshal(new StringReader(entity));


And this is the XML i'm trying to parse:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
   <items>
      <item id="1">
        <description>Chinos</description>
      </item>
      <item id="2">
        <description>Trousers</description>
      </item>
</items>

以下是创建XML的Web服务:

@GET
            @Produces(MediaType.TEXT_XML)
            public List<Item> getItemsBrowser(){

                java.sql.Connection connection;
                java.sql.Statement statement;

                List<Item> items = new ArrayList<Item>();


                ResultSet resultSet = null;

                try {
                    connection = dataSource.getConnection();
                    statement = connection.createStatement();

                    String query = "SELECT * FROM ITEMS";

                    resultSet = statement.executeQuery(query);

                    // Fetch each row from the result set
                    while (resultSet.next()) {
                      String a = resultSet.getString("itemID");

                      String b = resultSet.getString("itemDescription");

                      //Assuming you have a user object
                      Item item = new Item(a, b);

                      items.add(item);
                    }


                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }


                return items;
            }

2 个答案:

答案 0 :(得分:4)

您正在创建JAXBContext的类是Item.class,但XML包含一个名为items的列表,而这些列又包含不同的项条目。你需要另一个包装

的类
List<Item>

让这个工作。

这是一个完整的工作示例:

Items类:

import java.util.List;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Items {

    private List<Item> items;

    @XmlElement(name="item")
    public List<Item> getItems() {
        return items;
    }

    public void setItems(List<Item> items) {
        this.items = items;
    }

}

请注意,items属性上有一个@XmlElement注释,因为实际元素在XML中称为“item”。

Item类:

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;

public class Item {

    private String itemID;
    private String itemDescription;

    // need to have a constructor with no params
    public Item() {}

    public Item(String itemID, String itemDescription) {
        this.itemID = itemID;
        this.itemDescription = itemDescription;
    }

    @XmlAttribute
    public String getId() {
        return itemID;
    }

    public void setId(String id) {
        itemID = id;
    }

    @XmlElement
    public String getDescription() {
        return itemDescription;
    }

    public void setDescription(String description) {
        itemDescription = description;
    }
}

单元测试:

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import org.junit.Test;

public class JAXBTest {

    @Test
    public void xmlIsUnmarshalled() throws JAXBException {
        JAXBContext context = JAXBContext.newInstance(Items.class);
        Unmarshaller um = context.createUnmarshaller();
        Items items = (Items) um.unmarshal(new File("items.xml"));

        assertNotNull(items);
        assertNotNull(items.getItems());
        assertEquals(2, items.getItems().size());

        assertEquals("Chinos", items.getItems().get(0).getDescription());
        assertEquals("Trousers", items.getItems().get(1).getDescription());

        assertEquals("1", items.getItems().get(0).getId());
        assertEquals("2", items.getItems().get(1).getId());
    }
}

答案 1 :(得分:0)

由于您使用的是Jersey客户端API,因此可以执行以下操作并避免创建Items类:

import java.util.List;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.WebResource;

public class JerseyClient {

    public static void main(String[] args) {
        Client client = Client.create();
        WebResource resource = client.resource(""http://localhost:8080/testProject/rest/items"");
        List<Item> items = resource.accept("application/xml").get(new GenericType<List<Item>>(){});
        System.out.println(items.size());
    }

}

了解更多信息