2012-04-12 72 views
4

当有人能帮助我了解为什么我收到此错误:JAXB错误:意外的元素解组

javax.xml.bind.UnmarshalException:意外的元素(URI:“”,当地“项目”) 。预期的元素是< {} 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; 
      } 
+0

告诉我们更多关于您的环境。你是否在移动代码新服务器?什么类型的web服务(首先是java代码(或)WSDL)? – kosa 2012-04-12 20:52:07

+0

我用我的Java REST风格的web服务代码 – flexer7661 2012-04-12 21:02:02

回答

4

类你正在创建J AXBContext from Item.class,但XML包含一个名为items的列表,该列表又包含不同的项目条目。你需要另外一个包装

List<Item> 

为此工作。

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

的项目类:

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

} 

注意,没有对项目属性的@XmlElement注释,因为实际的元素在XML被称为“项目” 。

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()); 
    } 
} 
+0

更新了谢谢,但你能再扩大一点吗?我需要编辑这一行? - JAXBContext context = JAXBContext.newInstance(Item.class); – flexer7661 2012-04-12 21:24:27

+0

当然,我会编辑我的答案以包含代码。 – Rob 2012-04-12 21:28:53

+0

非常感谢,只有在测试时Id为空。描述正在获得,但不是Id,任何想法为什么Id为每个项目为空?我正在使用“Items items =(Items)um。unmarshal(new StringReader(entity))“;而不是你的xml文件example – flexer7661 2012-04-13 13:27:05

0

由于有啊正在使用泽西cleint的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()); 
    } 

} 

欲了解更多信息