zoukankan      html  css  js  c++  java
  • 笔记: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() + " sex=" + createParam.getSex()

                                      + " enum value=" + createParam.getTestEnum().getEnumValue()

                                      + " enum 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() + " message=" + result.getMessage());

      } else {

      System.out.println("response status=" + response.getStatus() + " message=" + 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);

         

       

  • 相关阅读:
    C#颜色和名称样式对照表
    C#双缓冲技术
    用户自定义控件(含源代码)圆角Panel
    c#事件
    BackgroundWorker 转
    c#范型List的Sort方法详解
    C#double转化成字符串 保留小数位数
    错误提示之:无法激活请求的服务有关详细信息,请参见服务器的诊断跟踪日志
    错误提示之(MVC3.0):HTTP 404。您正在查找的资源(或者它的一个依赖项)可能已被移除,或其名称已更改,或暂时不可用。请检查以下 URL 并确保其拼写正确。
    SQL Server 2008远程服务连接
  • 原文地址:https://www.cnblogs.com/li3807/p/7100906.html
Copyright © 2011-2022 走看看