JAXBElement.getValue() is returning null

女生的网名这么多〃 提交于 2019-12-23 20:05:01

问题


I have one to many mapping in my Pojo classes. A shop has a branch and a branch has many shops Here's Shop's Code:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="Shop")
public class Shop {

@XmlID
private String name;
@XmlIDREF
@XmlElement(name="ShopBranch",type=Branch.class)
private Branch branch;
//Getter Setter
}

Below is Branch Code:

 @XmlAccessorType(XmlAccessType.FIELD)
public class Branch {
@XmlID
private String name;
private String address;
@XmlIDREF
@XmlElement(nillable=false,required=true)
private List<Shop> shops;
//Getter and Setters
}

I'm publishing a webservice with some basic methods. and my wsimport is generating Branch class as below

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "branch", propOrder = {
    "branchName",
    "address",
    "branchShop"
})
public class Branch {

    @XmlElement(name = "BranchName")
    @XmlJavaTypeAdapter(CollapsedStringAdapter.class)
    @XmlID
    @XmlSchemaType(name = "ID")
    protected String branchName;
    protected String address;
    @XmlElementRef(name = "BranchShop", type = JAXBElement.class)
    protected List<JAXBElement<Object>> branchShop;
    //Getter-Setter
    }

I have no idea why it is List<JAXBElement<Object>> and not List<JAXBElement<Shop>>. But anyway. I have a method which returns all branches and that is working fine. When i extract branchShop from branch's instance i'm getting correct size for branchShop list but for all of the items in list getValue is returning NULL. Below is brief code:

PencilCatalog service= new PencilCatalog();
com.pencilhouse.webservices.PencilService port=service.getPencilCatalogPort();
((BindingProvider)port).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, Constant.PENCIL_SERVICE);
    List<Branch> branches= port.getAllBranches();
for(Branch b:branches)
{
    System.out.println("******************Branch:"+b.getBranchName()+" "+b.getAddress()+"******************");
    JAXBElement<Object>o=b.getBranchShop().get(0);
    System.out.println(o+"Value"+o.getScope()+" "+o.getValue());
}

o/p

******************Branch:KukatPalli Steer 2 Kukatpalli****************** javax.xml.bind.JAXBElement@45d9d7beValueclass com.pencilhouse.webservices.Branch null

The WSDL generated is quite large. I'm posting only type of Branch and Shop. I'm publishing webservice using Endpoint

XML generated:

<xs:complexType name="shop">
<xs:sequence>
<xs:element name="name" type="xs:ID" minOccurs="0"/>
<xs:element name="ShopBranch" type="xs:IDREF" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="branch">
<xs:sequence>
<xs:element name="BranchName" type="xs:ID" minOccurs="0"/>
<xs:element name="address" type="xs:string" minOccurs="0"/>
<xs:element name="BranchShop" type="xs:IDREF" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>

Intercepted Information: Request:

<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getAllBranches xmlns:ns2="PencilServiceHouse"/>
</S:Body>
</S:Envelope>

Response:

<?xml version="1.0" ?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <ns2:getAllBranchesResponse xmlns:ns2="PencilServiceHouse">
        <return>
            <name>
                    KukatPalli
            </name>
            <address>
                    Steer 2 Kukatpalli
            </address>
            <shops>
                    Pencil World    <!-- This is Shop Information which is coming as NULL in java, This is Shop's Name field which is declared as id using @XmlId -->
            </shops>
            <shops>
                    Pencils Den
            </shops>
            <shops>
                    Pencils Bag
            </shops>
        </return>
        <return>
            <name>
                    Salt Lake
            </name>
            <address>
                    Sec V Salt Lake
            </address>
            <shops>
                    Pencil World
            </shops>
            <shops>
                    Pencils Den
            </shops>
        </return>
        <return>
            <name>
                    Noida
            </name>
            <address>
                    Noida Sec 43
            </address>
            <shops>
                    Pencils Bag
            </shops>
        </return>
        </ns2:getAllBranchesResponse>
    </S:Body>
</S:Envelope>

回答1:


@XmlIDREF provides a way to specify intra-document references. It is required that each object be refrerenced through a sepearate nested relationship (such as @XmlElement) to get the data into the XML document.

I have written more about @XmlIDREF on my blog:

  • http://blog.bdoughan.com/2010/10/jaxb-and-shared-references-xmlid-and.html

UPDATE

I saw your blog, I'm getting data in my xml response but the issue is that when i generate my classes on client side using wsimport it is generating type Object for @XmlIDRef and it doesn't set data for these properties as i explained in my question.

In your example you are going: classes -> schema -> classes. Since Java classes and XML Schema are not a perfect match, and JAXB does not put any JAXB specific metadata in the generated schema some information is lost. You can fix this as follows:

You can use an external bindings file to type the IDREF property.

<jaxb:bindings schemaLocation="schema.xsd" node="/xsd:schema">
    <jaxb:bindings node="xsd:complexType[@name='branch']//xsd:element[@name='BranchShop']">
        <jaxb:property>
            <jaxb:baseType name="org.example.Shop"/>
        </jaxb:property>
    </jaxb:bindings>
</jaxb:bindings>



回答2:


This is not an answer, but it is to big for a comment and uses some formatting, so I have to post it as an answer.


Somehow your examples just don't add up.

First thing which is suspicious to be is that you have two Branch classes. Which already looks weird. Why do you need the second one? Or are these, like, service and client implementations?

Next, your Branch classes use the BranchName and BranchShop elements whereas your XML uses name and shop elements. This does not fit. Seems like your web service does not give the XML you expect. This would explain why the data is missing, but what puzzles me is - why do you get an element in the branchShop at all. I would actually expect the list to be empty but you seem to have something there.

My suggestion would be to figure out, why XML you get does not match your schema and to implement an isolated unmarshalling unit-test to test unmarshalling of the intercepted XML.



来源:https://stackoverflow.com/questions/26357458/jaxbelement-getvalue-is-returning-null

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!