1

私はJerseyとMoxyでTomcat 7を使用しています。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;
    }
}

moxy を使用できるように、次の内容の jaxb.properties ファイルを org.kkm.test.model に配置しました。

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 クラスのメッセージ本文ライターなどのエラー。

次に、次のように 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>

ご覧のとおり、ルート要素はありません。そのため、「アドレス」をルート要素として取り、「アドレス」要素の後のコンテンツを「追加コンテンツ」と見なしてエラーとして表示します。

4

1 に答える 1

1

最後に、答えを見つけました。それはとても簡単でした。どうしてそれを以前に考えられなかったのですか?これがパフォーマンスに影響するかどうかはわかりません。MessageBodyWriter などは必要ありません。org.kkm.test.modelからjaxb.propertiesファイルをコピー (移動ではなく)し、実装パッケージ (つまり、org.kkm.test.model.impl ) に配置して、@XmlRootElement(name="reading" )実装でも (つまり、ReadingImpl で)。順序付けが必要な場合は、@XmlType(propOrder...を追加します。

于 2013-07-04T17:47:15.850 に答える