筆記:Jersey REST 傳輸格式-XML


XML類型是使用最廣泛的數據類型,Jersey 對XML類型的數據處理,支持Java領域的兩大標准,即JAXP(Java API for XML Processing,JSR-206)和JAXB(Java Architecture for XML Binding,JSR-222),JAXP標准包含了DOM、SAX和StAX 三種解析技術標准。

  • DOM是面向文檔解析的技術,要求將XML數據全部加載到內存,映射為樹和結點模型以實現解析
  • SAX是事件驅動的流解析技術,通過監聽注冊事件,觸發回調方法以實現解析
  • StAX是拉式流解析技術,拉式解析使得讀取過程可以主動推進當前XML位置的指針而不是被動的獲得解析中的XML數據。

JAXP定義了三種標准類型的輸入接口Source(DOMSource、SAXSource、StreamSource)和輸出接口Result(DOMResult、SAXResult和StreamResult),示例代碼如下:

/**

* 使用 StAX 拉式流解析技術

*

* @param streamSource

* @return

*/

        @POST

        @Path("stream")

        @Produces(MediaType.APPLICATION_XML)

        @Consumes(MediaType.APPLICATION_XML)

        public StreamSource getStreamSource(StreamSource streamSource) {

                return streamSource;

        }

   

        /**

* 使用 SAX 事件驅動的流解析技術

*

* @param saxSource

* @return

*/

        @POST

        @Path("saxsource")

        @Produces(MediaType.APPLICATION_XML)

        @Consumes(MediaType.APPLICATION_XML)

        public SAXSource getSAXSource(SAXSource saxSource) {

                return saxSource;

        }

   

        /**

* 使用DOM面向文檔解析技術

*

* @param domSource

* @return

*/

        @POST

        @Path("domsource")

        @Produces(MediaType.APPLICATION_XML)

        @Consumes(MediaType.APPLICATION_XML)

        public DOMSource getSAXSource(DOMSource domSource) {

                return domSource;

        }

   

        /**

* 使用DOM面向文檔解析技術

*

* @param document

* @return

*/

        @POST

        @Path("doc")

        @Produces(MediaType.APPLICATION_XML)

        @Consumes(MediaType.APPLICATION_XML)

        public Document getSAXSource(Document document) {

                return document;

        }

JAXP 的缺點是需要編碼解析XML,則增加了開發成本,但對業務邏輯的實現並沒有實質的貢獻,JAXB只需要在POJO定義相關的注解,使其和XML的schema對應,無須對XML進行程序式解析,彌補了JAXP的這個缺點,JAXB通過序列化和反序列化實現了XML數據和POJO對象的自動轉換過程,JAXB的注解位於javax.xml.bind.annotation 包,從性能來說 JAXB低於JAXP,但使用JAXB的開發效率很高,示例代碼如下:

  • POJO代碼

    @XmlRootElement

    public class CreateParam implements Serializable {

            private String name;

            private String sex;

            private TestEnum testEnum;

       

            @XmlAttribute(name = "name")

            public String getName() {

                    return name;

            }

       

            public void setName(String name) {

                    this.name = name;

            }

       

            @XmlAttribute(name = "sex")

            public String getSex() {

                    return sex;

            }

       

            public void setSex(String sex) {

                    this.sex = sex;

            }

       

            @XmlAttribute(name = "testEnum")

            public TestEnum getTestEnum() {

                    return testEnum;

            }

       

            public void setTestEnum(TestEnum testEnum) {

                    this.testEnum = testEnum;

            }

    }

       

    @XmlRootElement

    public class DemoResult implements Serializable {

    private boolean hasError;

    private int returnCode;

    private String message;

       

    @XmlAttribute(name = "hasError")

    public boolean isHasError() {

    return hasError;

    }

       

    public void setHasError(boolean hasError) {

    this.hasError = hasError;

    }

       

    @XmlAttribute(name = "returnCode")

    public int getReturnCode() {

    return returnCode;

    }

       

    public void setReturnCode(int returnCode) {

    this.returnCode = returnCode;

    }

       

    @XmlAttribute(name = "message")

    public String getMessage() {

    return message;

    }

       

    public void setMessage(String message) {

    this.message = message;

    }

    }

       

  • REST服務代碼

            @POST

            @Path("jaxb")

            @Produces(MediaType.APPLICATION_XML)

            @Consumes(MediaType.APPLICATION_XML)

            public DemoResult getEntity(CreateParam createParam) {

                    DemoResult result = new DemoResult();

                    result.setHasError(false);

                    result.setMessage("創建 name=" + createParam.getName() + "\tsex=" + createParam.getSex()

                                    + "\tenum value=" + createParam.getTestEnum().getEnumValue()

                                    + "\tenum desc=" + createParam.getTestEnum().getEnumDesc());

       

                    System.out.println(createParam.getTestEnum() == TestEnum.Error);

       

                    return result;

            }

  • 單元測試代碼

    @Test

    public void PostJaxbXMLTest() {

    CreateParam createParam = new CreateParam();

    createParam.setName("jaxbXml");

    createParam.setSex("man男人");

    createParam.setTestEnum(TestEnum.Error);

       

    Invocation.Builder builder = target.path("demos").path("jaxb").request();

    Response response = builder.post(Entity.entity(createParam, MediaType.APPLICATION_XML));

    if (response.getStatus() == 200) {

    DemoResult result = response.readEntity(DemoResult.class);

    System.out.println("result hasError=" + result.isHasError() + "\tmessage=" + result.getMessage());

    } else {

    System.out.println("response status=" + response.getStatus() + "\tmessage=" + response.getStatusInfo());

    }

    }

示例中的POJO類,都定義為XML的屬性(property)來組織的,POJO的字段也可以作為元素(element)組織,如果REST請求的傳輸數據量很大,並且無須和外系統對接的場景,建議使用屬性來組織XML,這樣可以極大的減少XML格式的數據包大小。

注意:Jersey默認設置了XMLConstants.FEATURE_SECURE_PROCESSING屬性,當屬性和元素過多是,會報"well-formedness error"的警告信息,可以通過設置 MessageProperties.XML_SECURITY_DISABLE 參數值來屏蔽,設置示例如下:

  • REST服務設置

    // 繼承ResouceConfig類,並增加屬性設置

    public class RESTfulResourceConfig extends ResourceConfig {

    public RESTfulResourceConfig() {

    property(MessageProperties.XML_SECURITY_DISABLE, Boolean.TRUE);

    }

    }

  • 客戶端設置

    ClientConfig clientConfig = new ClientConfig();

    clientConfig.property(MessageProperties.XML_SECURITY_DISABLE, Boolean.TRUE);

    Client c = ClientBuilder.newClient(clientConfig);

       

   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM