1

我尝试了两种方法:将对象作为对象发布或包装到 JAXBElement 中。没有什么对我有用。

//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);

我什至尝试将它包装在 JAXB 中:

 JAXBElement<EstateDTO> estate = new JAXBElement<EstateDTO>(new QName("estate"), EstateDTO.class, estateOne);

同样的问题:我得到:

                    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.

即使我尝试使用:

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);

解决方案的更多事实:

EstateDTO 类:

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

编辑:

服务器端帖子

        @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);
        }

cosole上的系统说

 EstateDTO [estateId=null, owner=null, estateName=null, street=null, number=0, extraAddressLine=null, zip=0, country=null, space=0, tenants=[]]

postAndGetResponse 方法:

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

依赖项:

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

1 回答 1

1

您的 JAXB 映射似乎是正确的,并且由于您已经映射了您的类,因此@XmlRootElement您不需要将对象包装在JAXBElement. 我还仔细检查了您的 XStream 映射似乎与您的 JAXB 映射匹配(见下文)。我目前的猜测是问题出在你的 post 方法上。您能否将服务中的 post 方法添加到您的问题中?

房地产DTO

EstateDTO通过利用 JAXB 作为异常配置来简化您的课程。这意味着您只需要在行为与默认映射不同的地方添加注释。

包论坛11410653;

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

}

演示

下面是一些独立的 JAXB 代码,以确保一切正常。

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

}

输出

如您所见estateNamestreet、 和country已填充。

<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>
于 2012-07-10T10:29:56.883 回答