JAXB使用Jersey和Moxy

时间:2013-07-04 10:52:30

标签: jersey jax-rs moxy

我正在使用Tomcat 7和Jersey和Moxy。我使用maven添加了jersey.server.jar,jersey.servlet.jar,jersey-core.jar,moxy(org.eclipse.persistence.moxy,版本2.5.0)。

我有接口(包名:org.kkm.test.model):

public interface Model extends BaseModel {
    public String getConsumerId();
    public void setConsumerId(String consumerId);
}

@XmlRootElement(name="reading")
@XmlType(propOrder={"consumerId", "address", "reading", "readingDate", "rotation", "readingStatus"})
public interface Reading extends Model {
    @XmlElement
    public Address getAddress();
    @XmlElement
    public double getReading();
    @XmlElement
    public Date getReadingDate();
    @XmlElement
    public short getRotation();
    @XmlElement
    public ReadingStatus getReadingStatus();

    public void setAddress(Address address);
    public void setReading(double reading);
    public void setReadingDate(Date readingDate);
    public void setRotation(short rotation);
    public void setReadingStatus(ReadingStatus readingStatus);
}


public interface Address {
    public String getAddress1();
    public String getAddress2();
    public String getAddress3();
    public String getAddress4();

    public void setAddress1(String address1);
    public void setAddress2(String address2);
    public void setAddress3(String address3);
    public void setAddress4(String address4);
}

我有实现ReadingImpl和AddressImpl(包名:org.kkm.test.model.impl)。我有一个服务类如下:

@Path("/sample")
public class TestService {
    @GET
    @Produces(MediaType.APPLICATION_XML)
    @Path("/readings")
    public List<Reading> getReadings() {
        Reading reading1 = DependencySupplier.getReading();
        Address address = DependencySupplier.getAddress(); 
        address.setAddress1("Moolekkadavil");
        address.setAddress2("Kottuvallikad");
        address.setAddress3("Moothakunnam.P.O");
        address.setAddress4("683516");
        reading1.setAddress(address);
        reading1.setConsumerId("1234567890");
        reading1.setReading(11.00);
        reading1.setReadingDate(new Date());
        reading1.setReadingStatus(ReadingStatus.BILLED);
        reading1.setRotation((short) 1);
        Reading reading2 = DependencySupplier.getReading();
        reading2.setAddress(address);
        reading2.setConsumerId("1234567890");
        reading2.setReading(11.00);
        reading2.setReadingDate(new Date());
        reading2.setReadingStatus(ReadingStatus.BILLED);
        reading2.setRotation((short) 1);
        List<Reading> list = new ArrayList<Reading>();
        list.add(reading1);
        list.add(reading2);
        return list;
    }
    @GET
    @Produces(MediaType.APPLICATION_XML)
    @Path("/reading")
    public Reading getReading() {
        Reading reading1 = DependencySupplier.getReading();
        Address address = DependencySupplier.getAddress(); 
        address.setAddress1("Moolekkadavil");
        address.setAddress2("Kottuvallikad");
        address.setAddress3("Moothakunnam.P.O");
        address.setAddress4("683516");
        reading1.setAddress(address);
        reading1.setConsumerId("1234567890");
        reading1.setReading(11.00);
        reading1.setReadingDate(new Date());
        reading1.setReadingStatus(ReadingStatus.BILLED);
        reading1.setRotation((short) 1);
        return reading1;
    }
}

我在org.kkm.test.model中放置了一个jaxb.properties文件,其中包含以下内容,以便可以使用moxy:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

我的web.xml是:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <display-name>Test JAX</display-name>
  <servlet>
    <servlet-name>testjax</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>com.sun.jersey.config.property.packages</param-name>
      <param-value>org.kwa.test.service</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>testjax</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>
</web-app> 

我面临的问题是:    当我调用“/ rest / sample / readings”时,我在XML中得到了正确的表示,但是当我调用“/ rest / sample / reading”时,我得到了

  

com.sun.jersey.api.MessageException:Java的消息体编写器   class ...等错误。

然后我写了一个MessageBodyWriter如下:

public class MyMessageBodyWriter implements MessageBodyWriter {

    private List<Class<?>> types;

    public MyMessageBodyWriter() {
        types = new ArrayList<Class<?>>();
        types.add(ReadingImpl.class);
    }

    public long getSize(Object obj, Class type, Type genericType, Annotation[] annotations,
            MediaType mediaType) {
        // TODO Auto-generated method stub
        return -1;
    }

    public boolean isWriteable(Class type, Type genericType, Annotation[] annotations,
            MediaType mediaType) {
        return this.types.contains(type);
    }

    public void writeTo(Object target, Class type, Type genericType, Annotation[] annotations,
            MediaType mediaType, MultivaluedMap headers, OutputStream outputStream)
            throws IOException, WebApplicationException {
        try {
            JAXBContext ctx = JAXBContext.newInstance(type);
            Marshaller marshaller = ctx.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(target, outputStream);
        } catch (JAXBException e) {
            throw new RuntimeException(e);
        }       
    }
}

现在当我调用“/ rest / sample / reading”时,我得到以下XML:

<?xml version="1.0" encoding="UTF-8"?>
<address>
   <address1>Moolekkadavil</address1>
   <address2>Kottuvallikad</address2>
   <address3>Moothakunnam.P.O</address3>
   <address4>683516</address4>
</address><consumerId>1234567890</consumerId><reading>11.0</reading><readingDate>2013-07-04T21:16:39.128</readingDate><readingStatus>BILLED</readingStatus><rotation>1</rotation>

正如您所看到的,没有根元素。因此,在“地址”元素被视为“额外内容”并显示为错误之后,它将“地址”作为根元素和内容。

1 个答案:

答案 0 :(得分:1)

最后,我找到了答案,这很简单。我怎么能不提前想到这个?我不确定这是否会影响性能。您不需要任何MessageBodyWriter或任何东西。从 org.kkm.test.model 复制(不移动) jaxb.properties文件,并将其放在实施包中(即 org.kkm。 test.model.impl )并在实现中添加 @XmlRootElement(name =“reading”)(即在ReadingImpl中)。如果您想要订购,请添加 @XmlType(propOrder ...