I am developing RESTful web services in Java using Jersey, Tomcat and Toplink. One of my requirement is replacing a resource link(person) with actual xml data(returned by that person resource link) in the XML data that my "Customer" service returns. In order to achieve this, while calling(GET method) the Customer service I get the xml output from the "Person" resource and remove the <person> and </person> tags from this xml data(since my "Customer" service has the property "person" where I want to stick this xml data) and set this xml data in the "person" property of the "Customer" resource.
Here is my output:
Output returned from Customer service:
<customer>
<person>http://localhost:8080/xxxx/resources/person/JONESTD</person>
<xxx>...... </xxx>
<xxx>...... </xxx>
......
......
......
</customer>
Output returned from Customer service when I use query string composite=person(to replace
person resource url with actual data) while calling this service:
<customer>
<person><namePrefix>Mr.</namePrefix> <nameFirst>Timothy</nameFirst>
<nameLast>Jones</nameLast> <nameMiddle>D.</nameMiddle> <nameSuffix/>
<nameDisplayInformal>Timothy D. Jones</nameDisplayInformal> <nameDisplayFormal>Mr.
Timothy D. Jones</nameDisplayFormal> <nameSortedInformal>Jones, Timothy
D.</nameSortedInformal> <nameSortedFormal>Timothy, Jones D. Mr.</nameSortedFormal>
<username>JONESTD</username> <emailAddress>JONESTD#xxxx.xx</emailAddress> </person>
<xxx>...... </xxx>
<xxx>...... </xxx>
......
......
......
</customer>
As you see, the XML string I set in the person property of Customer resource is not properly indented. If I view "View Source" it shows this output like this:
<customer>
<namePrefix>Mr.</namePrefix>
<nameFirst>Timothy</nameFirst>
<nameLast>Jones</nameLast> <nameMiddle>D.</nameMiddle>
<nameSuffix/> <nameDisplayInformal>Timothy D.
Jones</nameDisplayInformal> <nameDisplayFormal>Mr. Timothy D.
Jones</nameDisplayFormal> <nameSortedInformal>Timothy, Jones
D.</nameSortedInformal> <nameSortedFormal>Timothy, Jones D.
Mr.</nameSortedFormal> <username>JONESTD</username>
<emailAddress>JONESTD#xxxx.xx</emailAddress>
<xxx>...... </xxx>
<xxx>...... </xxx>
.......
.......
.......
</customer>
I see this < and > only in the person xml string I set in the "person" property. I tried several things(including StringEscapeUtils.unescapeHtml) to convert < and > into < and > (proper xml). But nothing worked for me. Could you please give me some idea on how I can fix this issue?
In order to achieve this, while
calling(GET method) the Customer
service I get the xml output from the
"Person" resource and remove the
and tags from this
xml data(since my "Customer" service
has the property "person" where I want
to stick this xml data) and set this
xml data in the "person" property of
the "Customer" resource.
I believe you are saying that you have a Customer object with a String property to represent the XML contents? When you marshal this content you will see the addition of escaped characters.
I am developing RESTful web services
in Java using Jersey, Tomcat and
Toplink.
When you say you are using TopLink, are you oracle.toplink.* classes, or the org.eclipse.persistence.* classes. If you are using the latter (EclipseLink), you will be able to leverage EclipseLink JAXB (MOXy) to do what you want.
Representing XML as a String
Refer to: Using JAXB to extract inner text of XML element
http://bdoughan.blogspot.com/2011/04/xmlanyelement-and-non-dom-properties.html
Using MOXy with Jersey
http://bdoughan.blogspot.com/2010/08/creating-restful-web-service-part-35.html
Related
Currently my Project is using the JPA for the Database Connection.
I'm also using the default OdataJPA Processor.
How can i achieve not to include certain fields for example ("password") in my odata2 API response. Or do I really have to implement a customOdataJPAProcessor?
The easiest way for excluding some JPA entity attributes is to define a JPA-EDM mapping model. This is basically an XML file which adheres to this schema. You can read more about it in the documentation here: redefining OData JPA metadata.
You have two different ways of linking the mapping model XML, either you specify a file name of a file located in the WEB-INF folder (assuming that you are building a WAR) or, if this is not flexible enough, you can create a JPA EDM extension and return the mapping model file as a stream.
This is how such a file may look like:
<?xml version="1.0" encoding="UTF-8"?>
<JPAEDMMappingModel xmlns="http://www.apache.org/olingo/odata2/jpa/processor/api/model/mapping">
<PersistenceUnit name="My_Persistence_Unit">
<JPAEntityTypes>
<JPAEntityType name="MyEntity">
<EDMEntityType>MyEntity</EDMEntityType>
<EDMEntitySet>MyEntities</EDMEntitySet>
<JPAAttributes>
<JPAAttribute name="attribute" exclude="true" />
</JPAAttributes>
<JPARelationships />
</JPAEntityType>
</JPAEntityTypes>
<JPAEmbeddableTypes />
</PersistenceUnit>
</JPAEDMMappingModel>
I'm using CXF to generate java classes from a WSDL/XSD and later back to XML (for JMS).
In one of the generated classes, it says:
#XmlElement(namespace = "http://www.example.com/", nillable = true)
protected Datum datum;
All good, but when I put a null value:
test.setDatum(null);
I get the following XML generated:
<datum xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true" />
The xsi:nil="true" is what i want, but I don't want the namespace xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance", because this namespace is already specified at the root element. Also the validation fails at the test platform we have to use.
How do I get rid of the extra namespace in the element?
I did it the other way around. I wrote a interceptor that checks for certain attributes. If found, I add the xsi:nil="true" attribute to the xml.
I figure this will be easy for someone who really understands JAXB binding files...
Basic Question
How do you configure JAXB to unmarshal multiple elements into the same class?
Note: I want to avoid adding another dependency to my project (like MOXy). Ideally, this can be accomplished with annotations or a custom bindings file.
Background
I have an XML document that contains lots of variations of the same element--each with the exact same properties. Using my example below, all I care about is "Employees" but the XML specifies "directors, managers and staff." For our purposes, these are all subclasses of the same parent and we only need to work with the parent type (Employee) and our object model doesn't have or need instances of the subclasses.
I want JAXB to bind any instance of director, manager, or staff elements into an Employee object.
Example
input:
<organization>
<director>
<fname>Dan</fname>
<lname>Schman</lname>
</director>
<manager>
<fname>Joe</fname>
<lname>Schmo</lname>
</manager>
<staff>
<fname>Ron</fname>
<lname>Schwan</lname>
</staff>
<staff>
<fname>Jim</fname>
<lname>Schwim</lname>
</staff>
<staff>
<fname>Jon</fname>
<lname>Schwon</lname>
</staff>
</organization>
output:
After unmarshalling this example, I would end up with an Organization object with one property: List<Employees> employees where each employee only has a firstName and lastName.
(Note: each employee would be of type Employee NOT Director/Manager/Staff. Subclass information would be lost when unmarshalling. We also don't care about marshaling back out--we only need to create objects from XML)
Can this be done without extensions like MOXy? Can a custom bindings.xjb file save the day?
This corresponds to a choice structure. You could use an #XmlElements annotation for this use case:
#XmlElements({
#XmlElement(name="director", type=Employee.class),
#XmlElement(name="manager", type=Employee.class)
})
List<Employee> getEmployees() {
return employees;
}
If you are starting from an XML schema the following will help:
http://blog.bdoughan.com/2011/04/xml-schema-to-java-xsd-choice.html
Let's say I'm following HATEOAS and using hypertext in my XML. Something like this:
/customer/32
<Customer>
<FirstName>Joe</FirstName>
<LastName>Smith</LastName>
<Address href="/address/4324">
</Customer>
/address/4324
<Address>
<Street>123 Fake St</Street>
<Town>Springfield</Town>
</Address>
Is there a library akin to or an extension of JAXB that can unmarshall a Customer and automatically query for and unmarshall Address as a property of that Customer (like customer.getAddress().getStreet())? If not, what's a good approach to this that lends itself to client-side caching?
In JAXB you could use an XmlAdapter for this use case. The XmlAdapter would specify value type String and bound type Address. The you would add the logic to convert between them.
For More Info
http://bdoughan.blogspot.com/2010/07/xmladapter-jaxbs-secret-weapon.html?m=1
I am running a query to return State, City, and Zip from my database. How do I get JAX-RS (Jersey) to return this like this;
<State>
<City>
<Zip></Zip>
</City>
</State>
and so on......
Do I need to build an object that matches my xml structure, then pass that to JAX-RS, or can JAX-RS build it for me based on the resultset?
No, Jersey can't create the output directly from a ResultSet. That's because it has no idea how the data is supposed to be represented. You'll have to write a class to hold the results. You can use JAXB annotations on that class to provide greater control over how the XML looks.
You could use POJOs in your JAX-RS service. Then use JPA to map the objects to the database, and JAXB to map them to XML. For an example see:
Part 1 - The Database
Part 2 - Mapping the Database to JPA Entities
Part 3 - Mapping JPA entities to XML (using JAXB)
Part 4 - The RESTful Service
Part 5 - The Client