4

このエラーが発生する理由を誰かが理解するのを手伝ってくれますか:

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

2 に答える 2

4

JAXBContext を作成しているクラスは 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;
    }

}

実際の要素は XML で「item」と呼ばれるため、items プロパティに @XmlElement アノテーションがあることに注意してください。

アイテム クラス:

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());
    }
}
于 2012-04-12T21:06:07.097 に答える
0

あなたはJersey 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());
    }

}

詳細については

于 2012-04-18T18:20:54.117 に答える