2012-04-12 97 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()); 
    } 

} 

欲瞭解更多信息