Reputation: 15898
I tried both: post a object as object or wrapped into JAXBElement. Nothing works for me.
//Create Object
Estate DTO estateOne = new EstateDTO("Hotel", "StreetOne", 1, 111111, "England", 1);
///setting up xstream
XStream xstream = new XStream();
xstream.processAnnotations(EstateResourceIF.class);
xstream.processAnnotations(EstateDTO.class);
xstream.autodetectAnnotations(true);
xstream.setClassLoader(new EstateDTO().getClass().getClassLoader());
xstream.alias("estateDTO", EstateDTO.class);
xstream.alias("estateId", Integer.class);
xstream.alias("estateName", String.class);
//post object
service.post(estateOne).write(System.out);
I even tried wrapping it up in JAXB:
JAXBElement<EstateDTO> estate = new JAXBElement<EstateDTO>(new QName("estate"), EstateDTO.class, estateOne);
Same issues: I get:
Problem creating Marshaller
javax.xml.bind.JAXBException: "com.bachelor.facade.object" doesnt contain ObjectFactory.class or jaxb.index
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:197)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:128)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:277)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:372)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:337)
at org.restlet.ext.jaxb.JaxbRepresentation.getContext(JaxbRepresentation.java:97)
at org.restlet.ext.jaxb.internal.Marshaller$1.initialValue(Marshaller.java:68)
at org.restlet.ext.jaxb.internal.Marshaller$1.initialValue(Marshaller.java:64)
at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:141)
at java.lang.ThreadLocal.get(ThreadLocal.java:131)
at org.restlet.ext.jaxb.internal.Marshaller.getMarshaller(Marshaller.java:163)
at org.restlet.ext.jaxb.internal.Marshaller.marshal(Marshaller.java:216)
at org.restlet.ext.jaxb.JaxbRepresentation.write(JaxbRepresentation.java:530)
at org.restlet.engine.io.BioUtils$1.run(BioUtils.java:305)
at org.restlet.service.TaskService$1$1.run(TaskService.java:132)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:206)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Unable to locate marshaller.
JAXB marshalling error caught.
javax.xml.bind.JAXBException: Unable to locate marshaller.
at org.restlet.ext.jaxb.internal.Marshaller.getMarshaller(Marshaller.java:166)
at org.restlet.ext.jaxb.internal.Marshaller.marshal(Marshaller.java:216)
at org.restlet.ext.jaxb.JaxbRepresentation.write(JaxbRepresentation.java:530)
at org.restlet.engine.io.BioUtils$1.run(BioUtils.java:305)
at org.restlet.service.TaskService$1$1.run(TaskService.java:132)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:206)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Problem creating Marshaller
javax.xml.bind.JAXBException: "failure" doesnt contain ObjectFactory.class or jaxb.index
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:197)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:128)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:277)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:372)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:337)
at org.restlet.ext.jaxb.JaxbRepresentation.getContext(JaxbRepresentation.java:97)
at org.restlet.ext.jaxb.internal.Marshaller$1.initialValue(Marshaller.java:68)
at org.restlet.ext.jaxb.internal.Marshaller$1.initialValue(Marshaller.java:64)
at java.lang.ThreadLocal.setInitialValue(ThreadLocal.java:141)
at java.lang.ThreadLocal.get(ThreadLocal.java:131)
at org.restlet.ext.jaxb.internal.Marshaller.getMarshaller(Marshaller.java:163)
at org.restlet.ext.jaxb.internal.Marshaller.marshal(Marshaller.java:216)
at org.restlet.ext.jaxb.JaxbRepresentation.write(JaxbRepresentation.java:538)
at org.restlet.engine.io.BioUtils$1.run(BioUtils.java:305)
at org.restlet.service.TaskService$1$1.run(TaskService.java:132)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
at java.util.concurrent.FutureTask.run(FutureTask.java:138)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:206)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Unable to locate marshaller.
Even if I try it with:
EstateResourceIF estateResource = service.wrap(EstateResourceIF.class);
List<Preference<MediaType>> acceptedMediaTypes = new ArrayList<Preference<MediaType>>();
acceptedMediaTypes.add(new Preference(MediaType.APPLICATION_JSON));
service.getClientInfo().setAcceptedMediaTypes(acceptedMediaTypes);
estateResource.postEstate(estateOne);
Some more facts for solution:
EstateDTO class:
@XmlRootElement
//JAX-RS supports an automatic mapping from JAXB annotated class to XML and JSON
@XmlAccessorType(XmlAccessType.FIELD)
public class EstateDTO implements Serializable{
/**
*
*/
private static final long serialVersionUID = -8545841080597549468L;
@XmlElement(name="estateId")
private String estateId;
@XmlElement(name="owner")
private String owner;
@XmlElement(name="estateName")
private String estateName;
@XmlElement(name="street")
private String street;
@XmlElement(name="number")
private int number;
@XmlElement(name="extraAddressLine")
private String extraAddressLine;
@XmlElement(name="zip")
private int zip;
@XmlElement(name="country")
private String country;
private int space;
private List<String> tenants = new ArrayList<String>();
public EstateDTO() {
}
public EstateDTO(String estateName, String street, int number, int zip, String country, int space) {
this.estateName = estateName;
this.street = street;
this.number = number;
this.zip = zip;
this.country = country;
this.space = space;
}
EDIT:
Server Sided Post
@POST
@Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Response postEstate(EstateDTO c) {
//EstateDTO c = estate.getValue();
System.out.println(c);
String generatedId = generateID();
c.setEstateId(generatedId);
c.setOwner(sec.getUserPrincipal().getName());
return postAndGetResponse(c);
}
the system out on cosole says
EstateDTO [estateId=null, owner=null, estateName=null, street=null, number=0, extraAddressLine=null, zip=0, country=null, space=0, tenants=[]]
postAndGetResponse Method:
private Response postAndGetResponse(EstateDTO estate) {
Response res;
System.out.println(estate);
if(EstateDAO.instance.getEstateDao().containsKey(estate.getEstateId())) {
res = Response.serverError().status(409).build();
} else {
res = Response.created(UriBuilder.fromUri(uriInfo.getAbsolutePath() + "/" + estate.getEstateId()).build()).entity(estate).build();
EstateDAO.instance.getEstateDao().put(estate.getEstateId(), estate);
}
return res;
}
Dependencies:
<dependency>
<groupId>org.restlet.jee</groupId>
<artifactId>org.restlet</artifactId>
<version>${restlet.version}</version>
</dependency>
<dependency>
<groupId>org.restlet.jee</groupId>
<artifactId>org.restlet.ext.xstream</artifactId>
<version>${restlet.version}</version>
</dependency>
<dependency>
<groupId>org.restlet.jee</groupId>
<artifactId>org.restlet.ext.jackson</artifactId>
<version>${restlet.version}</version>
</dependency>
<dependency>
<groupId>org.restlet.jee</groupId>
<artifactId>org.restlet.ext.jaxb</artifactId>
<version>${restlet.version}</version>
</dependency>
<dependency>
<groupId>org.restlet.jee</groupId>
<artifactId>org.restlet.ext.json</artifactId>
<version>${restlet.version}</version>
</dependency>
<dependency>
<groupId>org.restlet.jee</groupId>
<artifactId>org.restlet.ext.xml</artifactId>
<version>${restlet.version}</version>
</dependency>
<!-- Jersey JAXB -->
<!-- <dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-json</artifactId>
<version>1.12</version>
</dependency>-->
Upvotes: 1
Views: 813
Reputation: 149017
Your JAXB mappings appear to be correct, and since you have mapped your class with @XmlRootElement
you do not need to wrap the object in a JAXBElement
. I also double checked and your XStream mappings appear to match your JAXB mappings (see below). My current guess is the problem lies in your post method. Could you add the post method from the service to your question?
EstateDTO
I have simplified your EstateDTO
class by taking advantage of JAXB being configuration by exception. This means you only need to add annotations where the behaviour differs from the default mapping.
package forum11410653;
import java.io.Serializable;
import java.util.*;
import javax.xml.bind.annotation.*;
@XmlRootElement
//JAX-RS supports an automatic mapping from JAXB annotated class to XML and JSON
@XmlAccessorType(XmlAccessType.FIELD)
public class EstateDTO implements Serializable{
/**
*
*/
private static final long serialVersionUID = -8545841080597549468L;
private String estateId;
private String owner;
private String estateName;
private String street;
private int number;
private String extraAddressLine;
private int zip;
private String country;
private int space;
private List<String> tenants = new ArrayList<String>();
public EstateDTO() {
}
public EstateDTO(String estateName, String street, int number, int zip, String country, int space) {
this.estateName = estateName;
this.street = street;
this.number = number;
this.zip = zip;
this.country = country;
this.space = space;
}
}
Demo
Below is some standalone JAXB code to ensure that everything works.
package forum11410653;
import java.io.*;
import javax.xml.bind.*;
import com.thoughtworks.xstream.*;
public class Demo {
public static void main(String[] args) throws Exception {
EstateDTO estateDTO = new EstateDTO("Hotel", "StreetOne", 1, 111111,
"England", 1);
// setting up xstream
XStream xstream = new XStream();
xstream.processAnnotations(EstateDTO.class);
xstream.autodetectAnnotations(true);
xstream.setClassLoader(new EstateDTO().getClass().getClassLoader());
xstream.alias("estateDTO", EstateDTO.class);
xstream.alias("estateId", Integer.class);
xstream.alias("estateName", String.class);
StringWriter writer = new StringWriter();
xstream.toXML(estateDTO, writer);
String xml = writer.toString();
System.out.println(xml);
// setting up JAXB
JAXBContext jc = JAXBContext.newInstance(EstateDTO.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
EstateDTO unmarshalled = (EstateDTO) unmarshaller
.unmarshal(new StringReader(xml));
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(unmarshalled, System.out);
}
}
Output
As you can see estateName
, street
, and country
are populated.
<estateDTO>
<estateName>Hotel</estateName>
<street>StreetOne</street>
<number>1</number>
<zip>111111</zip>
<country>England</country>
<space>1</space>
<tenants/>
</estateDTO>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<estateDTO>
<estateName>Hotel</estateName>
<street>StreetOne</street>
<number>1</number>
<zip>111111</zip>
<country>England</country>
<space>1</space>
<tenants></tenants>
</estateDTO>
Upvotes: 1