我正在使用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>
正如您所看到的,没有根元素。因此,在“地址”元素被视为“额外内容”并显示为错误之后,它将“地址”作为根元素和内容。
答案 0 :(得分:1)
最后,我找到了答案,这很简单。我怎么能不提前想到这个?我不确定这是否会影响性能。您不需要任何MessageBodyWriter或任何东西。从 org.kkm.test.model 中复制(不移动) jaxb.properties文件,并将其放在实施包中(即 org.kkm。 test.model.impl )并在实现中添加 @XmlRootElement(name =“reading”)(即在ReadingImpl中)。如果您想要订购,请添加 @XmlType(propOrder ... 。