zoukankan      html  css  js  c++  java
  • JDK1.6新特性,WebService强化

    Web service是一个平台独立的,松耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的应用程序。

    Web services涉及技术:

    • XML XML是在web上传送结构化数据的伟大方式,Web services要以一种可靠的自动的方式操作数据,HTML不会满足要求,而XML可以使web services十分方便的处理数据,它的内容与表示的分离十分理想
    • SOAP 即Simple Object Access Protocol,SOAP使用XML消息调用远程方法,这样web services可以通过HTTP协议的post和get方法与远程机器交互,而且,SOAP更加健壮和灵活易用。
    • WSDL Web Service描述语言WSDL 就是用机器能阅读的方式提供的一个正式描述文档而基于XML的语言,用于描述Web Service及其函数、参数和返回值。因为是基于XML的,所以WSDL既是机器可阅读的,又是人可阅读的。

    Mustang 简化了Web services 的开发和发布。XML和Web服务一直都是Mustang的关注重点。Mustang为此引入了JAX-WS(Java Architecture for XML-Web Services) 2.0 以及JAXB(Java Architecture for XML Binding) 2.0。 同时还有Streaming API for XML (STaX), 它提供了一个双向API,这个API可以通过一个事件流来读取或者写入XML,其中包括跳过某个部分,然后直接关注与文档中的另外一个小部分的能力。

    JAVA中有三种WebService规范:

    • JAX-WS(Java API For XML-WebService),JDK1.6 自带的版本为JAX-WS2.1,其底层支持为JAXB。早期的JAVA Web服务规范JAX-RPC(Java API ForXML-Remote Procedure Call)目前已经被JAX-WS 规范取代,JAX-WS 是JAX-RPC 的演进版本,但JAX-WS 并不完全向后兼容JAX-RPC。
    • JAXM(JAVA API For XML Message),主要定义了包含了发送和接收消息所需的API,相当于Web 服务的服务器端,其API 位于javax.messaging.*包,它是JAVA EE 的可选包,因此你需要单独下载。SAAJ(SOAP With Attachment API For Java,JSR 67)是与JAXM 搭配使用的API,为构建SOAP 包和解析SOAP 包提供了重要的支持,支持附件传输,它在服务器端、客户端都需要使用。
    • JAX-RS,是JAVA 针对REST(Representation State Transfer)风格制定的一套Web 服务规范,由于推出的较晚,该规范(JSR 311,目前JAX-RS 的版本为1.0)并未随JDK1.6 一起发行,你需要到JCP 上单独下载JAX-RS 规范的接口,其API 位于javax.ws.rs.*包。

    目前Java环境中开发WebService主要有三种方法:

    • Axis2,Axis是apache下一个开源的webservice开发组件,出现的算是比较早了,也比较成熟。这里主要介绍Axis+eclipse开发webservice,当然不用eclipse也可以开发和发布webservice,只是用eclipse会比较方便。
    • Apche CXF,CXF开发webservice也是比较方便和简单的,它和spring的集成可以说是非常地好。
    • JDK1.6自带的JAX-WS规范。

    下面是一个用JDK1.6自带的JAX-WS规范开发的一个Hello World级别的WebService示范(环境:Eclipse):

    1. 创建WebService服务

    主程序:

    package com.clzhang.sample.thinking;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import javax.jws.WebService;
    import javax.xml.ws.Endpoint;
    
    /**
     * 第1步,创建WebService服务,包含所需要的实体(Entity)等;
     * 第2步,利用wsimport命令生成客户端存根;
     * 第3步,创建WebService客户端主程序,通过客户端存根调用WebService。
     * @author acer
     *
     */
    @WebService
    public class JDK16WSServer1 {
        // 简单的一个参数in、一个参数out调用
        public String sayHello(String greeting) {
            System.out.println("greeting is:" + greeting);
    
            return "I got " + greeting;
        }
    
        // 稍复杂的小计算,返回一个实体
        public JDK16WSEntity getEntity(String name, int age, Date birthday) {
            JDK16WSEntity entity = new JDK16WSEntity();
            entity.setAge(age);
            entity.setName(name);
            entity.setBirthday(birthday);
    
            entity.setDesc("您的姓名:" + name + ",年龄:" + age + "出生于:"
                    + new SimpleDateFormat("yyyy-MM-dd").format(birthday));
    
            return entity;
        }
    
        public static void main(String[] args) {
            Endpoint.publish("http://localhost:8888/service", new JDK16WSServer1());
            
            System.out.println("WebService Server started...");
        }
    }

    实体类:

    package com.clzhang.sample.thinking;
    
    import java.util.*;
    import javax.xml.bind.annotation.XmlRootElement;
    
    @XmlRootElement
    public class JDK16WSEntity {
        private int age;
        private String name;
        private Date birthday;
        private String desc;
    
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Date getBirthday() {
            return birthday;
        }
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
        public String getDesc() {
            return desc;
        }
        public void setDesc(String desc) {
            this.desc = desc;
        }
        
        @Override
        public String toString() {
            return age + "|" + name + "|" + birthday;
        }
    }

    创建完成之后,请运行主程序:JDK16WSServer1,以启动WebService服务。

    2. 利用wsimport命令生成客户端代码存根

    打开IE游览器,输入地址:http://localhost:8888/service?wsdl,即可以看到调用接口。

    <?xml version="1.0" encoding="UTF-8"?><!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2.4-b01. --><!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.2.4-b01. --><definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://thinking.sample.clzhang.com/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://thinking.sample.clzhang.com/" name="JDK16WSServer1Service">
    <types>
    <xsd:schema>
    <xsd:import namespace="http://thinking.sample.clzhang.com/" schemaLocation="http://localhost:8888/service?xsd=1"></xsd:import>
    </xsd:schema>
    </types>
    <message name="sayHello">
    <part name="parameters" element="tns:sayHello"></part>
    </message>
    <message name="sayHelloResponse">
    <part name="parameters" element="tns:sayHelloResponse"></part>
    </message>
    <message name="getEntity">
    <part name="parameters" element="tns:getEntity"></part>
    </message>
    <message name="getEntityResponse">
    <part name="parameters" element="tns:getEntityResponse"></part>
    </message>
    <portType name="JDK16WSServer1">
    <operation name="sayHello">
    <input wsam:Action="http://thinking.sample.clzhang.com/JDK16WSServer1/sayHelloRequest" message="tns:sayHello"></input>
    <output wsam:Action="http://thinking.sample.clzhang.com/JDK16WSServer1/sayHelloResponse" message="tns:sayHelloResponse"></output>
    </operation>
    <operation name="getEntity">
    <input wsam:Action="http://thinking.sample.clzhang.com/JDK16WSServer1/getEntityRequest" message="tns:getEntity"></input>
    <output wsam:Action="http://thinking.sample.clzhang.com/JDK16WSServer1/getEntityResponse" message="tns:getEntityResponse"></output>
    </operation>
    </portType>
    <binding name="JDK16WSServer1PortBinding" type="tns:JDK16WSServer1">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"></soap:binding>
    <operation name="sayHello">
    <soap:operation soapAction=""></soap:operation>
    <input>
    <soap:body use="literal"></soap:body>
    </input>
    <output>
    <soap:body use="literal"></soap:body>
    </output>
    </operation>
    <operation name="getEntity">
    <soap:operation soapAction=""></soap:operation>
    <input>
    <soap:body use="literal"></soap:body>
    </input>
    <output>
    <soap:body use="literal"></soap:body>
    </output>
    </operation>
    </binding>
    <service name="JDK16WSServer1Service">
    <port name="JDK16WSServer1Port" binding="tns:JDK16WSServer1PortBinding">
    <soap:address location="http://localhost:8888/service"></soap:address>
    </port>
    </service>
    </definitions>
    View Code

    打开一个DOS窗口,输入(需要将jdk1.6.x/bin目录包括到path环境变量中):

    wsimport -s d:	ddownload -d d:	ddownload -p com.clzhang.sample.thinking.client http://localhost:8888/service?wsdl

    命令参数说明:
      -d:生成客户端执行类的class文件的存放目录
      -s:生成客户端执行类的源文件的存放目录
      -p:定义生成类的包名

    然后拷贝client目录以自己项目的目录。我这里的目录结构如下图所示:

    服务主程序(JDK16WSServer1.java)、实体类(JDK16WSEntity.java)、客户端调用程序(JDK16WSClient1.java)存放于thinking目录下;

    客户端代码存根存放于停刊thinking/client目录下。

    3. 创建客户端主程序调用

    package com.clzhang.sample.thinking;
    
    import java.util.*;
    import java.text.SimpleDateFormat;
    import javax.xml.datatype.DatatypeFactory;
    import javax.xml.datatype.XMLGregorianCalendar;
    
    import com.clzhang.sample.thinking.client.JDK16WSServer1;
    import com.clzhang.sample.thinking.client.JDK16WSServer1Service;
    import com.clzhang.sample.thinking.client.Jdk16WSEntity;
    
    public class JDK16WSClient1 {
        
        public static void main(String[] args) throws Exception {
            JDK16WSServer1Service jwss = new JDK16WSServer1Service();
            JDK16WSServer1 jws = jwss.getJDK16WSServer1Port();
            
            String returnGreeting = jws.sayHello("How are you?");
            System.out.println(returnGreeting);
    
    // 字符串日期-》日期(java.util.Date)-》GregorianCalendar-》XMLGregorianCalendar SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); GregorianCalendar gCal = new GregorianCalendar(); gCal.setTime(sdf.parse("1980-4-3")); XMLGregorianCalendar xmlCal = DatatypeFactory.newInstance().newXMLGregorianCalendar(gCal); Jdk16WSEntity entity = jws.getEntity("张三", 23, xmlCal); System.out.println(entity.getDesc());
    // XMLGregorianCalendar-》GregorianCalendar-》日期(java.util.Date)-》字符串日期 System.out.println(sdf.format(entity.getBirthday().toGregorianCalendar().getTime())); } }

    注意,程序中用到了XMLGregorianCalendar、GregorianCalendar、java.util.Date、字符串日期的互相转换。运行客户端主程序。
    客户端输出:

    I got How are you?
    您的姓名:张三,年龄:23出生于:1980-04-03
    1980-04-03

    服务端输出:

    WebService Server started...
    greeting is:How are you?

    4. 如何把WebService发布到tomcat服务器?

    把WebService发布到tomcat服务器并没有好的方法。折中的方法是,通过一个自启动Servlet,在Servlet初始化阶段,注册WebService服务。

    4.1 创建Servlet

    package com.clzhang.sample.thinking;
    
    import java.io.IOException;
    
    import javax.servlet.GenericServlet;
    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.xml.ws.Endpoint;
    
    public class JDK16WSServlet extends GenericServlet {
        private static final long serialVersionUID = 1L;
        @Override
        public void init(ServletConfig servletConfig) throws ServletException {
            super.init(servletConfig);
    
            Endpoint.publish("http://localhost:8888/service", new JDK16WSServer1());
            
            System.out.println("WebService Server started...");
        }
        
        public void service(ServletRequest servletRequest, ServletResponse servletResponse)
                throws ServletException, IOException {
            servletResponse.getWriter().println("<a href="http://localhost:8888/service?wsdl">WSDL</a>");
        }
    }

    4.2 修改web.xml

        <servlet>
            <servlet-name>WSServlet</servlet-name>
            <servlet-class>com.clzhang.sample.thinking.JDK16WSServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>WSServlet</servlet-name>
            <url-pattern>/servlet/WSServlet</url-pattern>
        </servlet-mapping>

    4.3 启动Tomcat

    打开IE访问:http://localhost:8888/service?wsdl,即可以访问WSDL。客户端程序也可以运行。

    关于JDK1.6新特性暂时到这儿,更多信息参考:更多信息,参考:http://www.oracle.com/technetwork/java/javase/features-141434.html

  • 相关阅读:
    mat工具记录一次full gc的过程
    2021年官网下载各个版本JDK最全版与官网查阅方法
    如何用vmkping命令调试vsphere环境中的VMkernel网络连接(ISCSI 开启巨帧)
    vsphere 虚拟机的迁移,冷迁移,vmotion(热迁移)
    VMkernel 级别的 TCP/IP 堆栈解释
    Ubuntu/Linux 开机运行指定的命令/自动运行命令
    桌面信息软件Desktop Info配置
    Windows10下插入USB串口设备后鼠标跳屏问题——Microsoft Serial Ballpoint
    Windows桌面配置常用软件总结
    安装Linux双系统取消快速启动,为什么在双启动时禁用Windows 8上的快速启动?
  • 原文地址:https://www.cnblogs.com/nayitian/p/3394099.html
Copyright © 2011-2022 走看看