前言:

随着近几年来,SOA,EAI等架构体系的日渐成熟,Webservice越来越炽手可热,尤其是在企业做异质平台整合时成为了首选的技术。

Java的Webservice技术更是层出不穷,比較流行的有:

Axis2,Spring WS以及Jaxws。

本人在日常工作和以往project中,在使用了上述这些Webservice后进行了总结,比較,终于认为jaxws是眼下最标准,须要额外第三方插件最少,配置最少最灵活的webservice。

JAXWS适合差点儿全部Webserviceclient的调用,因此不少巨头型的厂商如:IBM,Weblogic等,在他们的产品上都使用了以JAXWS为标准的Webservice接口。

本教程分成五天,为0基础教程。

通过本教程,能够使一个没有Webservice概念或者没有写过Webservice的JAVA Resource高速上手入门,并能满足一般中小型项目中Webservice的应用。

对于Webservice Security,在(0基础)教程中并不提供,会在高级教程中具体描写叙述。

只是真正利用Webservice Security特性即XML加密技术的project并不多,少之又少,大多还是以http: //xxx/xxxService?userId=&password=这种形式来进行“假安全”通讯的。

必经我们的大部分项目是执行在Intranet里的,并且有非常好的监控和布防。

以下開始我们的教程。

第一天

目标:

1. 理解jaxws

2. 写jaxws之前的准备工作

3. 一切始于HelloWorld

4. 理解同步,异步

一、理解jaxws

1.1JAX-WS概述

JAX-WS2.0 的全称为 Java API for XML-Based Webservices (JAX-WS) 2.0。JAX-WS 2.0 是对 JAX-RPC 1.0 规范的扩展,是 JAX-RPC 1.1 的兴许版本号, JAX-RPC 2.0 标准公布不久后便被又一次命名为 JAX-WS 2.0。 JAX-WS 2.0 是面向 Java 5 的开发 Web services 的最新编程标准,它提供了新的编程模型和对以往的 JAX-RPC 方式的 Web services 进行了增强。 JAX-WS2.0 (JSR 224)是Sun新的web services协议栈,是一个全然基于标准的实现。在binding层,使用的是the Java Architecture for XMLBinding (JAXB, JSR 222),在parsing层,使用的是the Streaming API for XML (StAX, JSR 173),同一时候它还全然支持schema规范。

1.2JAX-WS 2.1特性

支持SOAP 1.1(默认)、1.2

支持XML/HTTP Binding

支持WS-Addressing

支持document/literal样式

支持WS-I Basic Profile 1.1

支持消息传输优化机制(Message Transmission Optimization Mechanism,MTOM)

二、写jaxws之前的准备工作

2.1JDKjavaversion "1.6.0_x"。

2.2JAX-WS RI 2.1.1 in JDK 6

2.2.1 JAX-WS RI 2.1.1安装注解

JAX-WS RI组件下载后为一个”.jar”文件,它并不能直接在project中使用,它是一个以JAVA Swing为界面的JAXWS的安装程序包。

我们须要打开一个命令行窗体,并输入:

输入完这条命令后,你会得到一个安装界面例如以下:

下一步,下一步完毕安装后你会得到这种一个文件夹:

这个文件夹里有我们写JAXWS所需的全部lib包以及JAXWS自带的教程。

三、一切始于HelloWorld

3.1建立Webservice的Server端project

能够看到我们这个文件夹除传统的src,WebContent文件夹外还有几个文件夹,它们各自是:

?    build
?    wsdl
?    wssrc

我们来书写我们的第一个Webservice吧,它的名字叫Hello(Come on, 老套了,又来了)。

package ctsjavacoe.ws.fromjava;

import javax.jws.WebMethod;

import javax.jws.WebService;

@WebService

public class Hello {

@WebMethod

public String say(String name) {

return ("Hello: "+name);

}

}

注意:

@WebService

凝视在了Class之上,这告诉了JAXWS,此类为Webservice。

@WebMethod

凝视在了public方法上,这告诉了JAXWS,此方法为soap方法,该方法有两个參数,一个input的String,一个output的String。

业务逻辑非常easy,client调用传入一个Name,服务端返回给client一个”Hello: “+name的字串。

如今我们通过Java文件来生成Webservice相关布署文件以及调用接口。

3.2通过Java类编译Webservice

JAX-WS 2.0 有两种开发过程:自顶向下和自底向上。自顶向下方式指通过一个 WSDL 文件来创建Web Service,自底向上是从 Java 类出发创建 Web Service。两种开发过程终于形成的文件包含:

1.SEI。一个SEI相应WSDL中WebService的一个port,在Java中是一个Java接口。

2.SEI实现类。

3.WSDL和XSD文件。

结合公司内项目的特点,我们很多其它的是碰到以下两种情况:

1.  Onsite要我们做一个Webservice或者是客户要求我们提供Webservice接口;

2.  Onsite已经有一个Webservice了,如今要我们做client集成。

因此,我们选用Server端通过Java Class生成webservice,而client通过wsdl生成Java调用类的做法

JAXWS为我们提供了两个工具:

ü  wsgen

主要用于Server端通过Java类编译成Webservice及相关的wsdl文件

ü  wsimport

主要用于Client端(调用端)通过wsdl编译出调用Server端的Java文件

我们就来生成一下上面的这个Hello,打开一个command窗体,键入例如以下命令:

-wsdl參数代表生成webservice

- s參数代表生成的.java文件置于何处

-d 參数代表生成的编译class文件置于何处(这个能够忽略,我们利用eclipse编译)

-r 參数代表生成的.wsdl文件与.xsd文件生成在何处

-cp參数代表classpath,即Hello.class的所在,为什么我们的-cp后是这么长一个路径呢?请看Eclipse里project编译输出文件夹的路径就知道了:

3.2.1 生成的src文件

好,我们如今回到eclipseproject里,刷新一下project:

看到在wssrc文件夹下已经生成了我们所需的java文件了,请手工cut(对,是cut)这些文件到我们project的”src”文件夹,假设不cut,下次继续使用该文件夹生成webservice类时,wsgen有时会生成不了,但也不报错,不知道为什么,查了一下,可能是一个bug,因该会在兴许的jdk1.6.30up里改进。

3.2.2 生成的wsdl及xsd文件

这里我们有两个文件,一个是wsdl文件,这个就是我们的webservice的entry,一个是xsd文件,这个是什么?

这个就是我们java的方法里的參数的相应,或者换句话说,它就是xml格式的java bean,在webservice的世界里,xsd是作为数据结构描写叙述用的。

如今我们的webservice的服务端有了。

3.2.3 布署webservice

布署前的准备:

在project的WEB-INF文件夹下建立“sun-jaxws.xml”文件,内容例如以下:

<?xml version="1.0" encoding="UTF-8"?>

<endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime'

    version='2.0'>

    <endpoint name='Hello' implementation='ctsjavacoe.ws.fromjava.Hello'

        url-pattern='/HelloService' />

</endpoints>

将ctsjavacoe.ws.fromjava.Hello声明为Web Service。

假设是从WSDL生成的Web Service,则写法为,

<?xml version="1.0" encoding="UTF-8"?>

<endpoints version="2.0" xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime">

<endpoint implementation="ctsjavacoe.ws.fromjava.HelloSEI"

name="Hello" url-pattern="/HelloService" />

</endpoints>

 

改动WEB-INF文件夹下的web.xml文件,增加例如以下内容:

<servlet>

        <servlet-name>Hello</servlet-name>

        <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>

        <load-on-startup>2</load-on-startup>

</servlet>

<servlet-mapping>

        <servlet-name>Hello</servlet-name>

        <url-pattern>/HelloService</url-pattern>

</servlet-mapping>

为每个WebService声明一个com.sun.xml.ws.transport.http.servlet.WSServlet。

開始布署:

1.  在tomcat的webapps文件夹下建立一个文件夹叫“D:\tomcat2\webapps\JaxWSSample”

2.  把eclipseprojectJaxWSSample下WebContent文件夹下全部的东西copy至该文件夹下

3.  重新启动tomcat

在ie中输入:

http://localhost:9090/JaxWSSample/HelloService?wsdl

能够看到我们的webservice已经生成了。

3.3通过Server端的WSDL生成供JAVA调用的client

3.3.1 同步与异步

同步调用,非常好理解,即一来一回,Client端request到Server端,Sever端立马回一个response。

异步调用,就是client调用一次服务端后,服务端处理事务并非即时返回的,比方说传一个600MB文件给服务端,服务端在处理接收和解析文件时,client不会立即得到一个响应,它会等待一段时间,等server处理完后,再通知client“我处理完了”。

3.3.2 利用wsimport产生client

我们新建一个eclipse的project,仅仅须要是JAVAproject即可了,不须要webproject的,由于我们这边仅仅用代码做调用:

把Server端的wsdl及xsd都手工copy到clientproject的wsdl文件夹下。

打开一个cmd窗体敲入例如以下的命令:

wsimport -keep -d bin -s src wsdl/HelloService.wsdl

以上是产生同步client的命令。

假设要产生异步client命令,须要在project根文件夹下建一个binding.xml的文件,内容例如以下:

<?xml version="1.0" encoding="UTF-8"?>

<bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema"

    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" wsdlLocation="wsdl/HelloService.wsdl"

    xmlns="http://java.sun.com/xml/ns/jaxws">

    <bindings node="wsdl:definitions">

        <enableAsyncMapping>true</enableAsyncMapping>

    </bindings>

</bindings> 

然后产生client代码的wsimport命令也会不一样:

wsimport -keep –b binding.xml  -d bin -s src wsdl/HelloService.wsdl

我们来看异步调用的代码(同步代码比异步调用简单,留给大家自己做练习)

wsimport命令会在eclipseproject的src文件夹中生成你在调用时所用的java src文件。

Hello.java与HelloService.java是wsimport给我们生成的供client调用的java文件。

我们把HelloService文件打开,能够看到两行:

file:/D:/workspace/JaxWSClient/wsdl/HelloService.wsdl

把它们改成:

http://localhost:9090/JaxWSSample/HelloService?wsdl

有两行,尤其是Url url=这一行,千万不要漏改了。

我们创建一个调用类,叫:HelloAsyncPollingClient.java文件,内容例如以下:

package ctsjavacoe.ws.fromjava;

 

import javax.xml.ws.Response;

 

public class HelloAsyncPollingClient {

 

    /**

     * @param args

     */

    public static void main(String[] args) throws Exception {

        HelloService service = new HelloService();

        Hello port = service.getHelloPort();

        Response<SayResponse> sayAsync = port.sayAsync("Mk");

        while (!sayAsync.isDone()) {

            System.out.println("is not down");

        }

        try {

            SayResponse callNameResponse = sayAsync.get();

            String message = callNameResponse.getReturn();

            System.out.println(message);

        } catch (Exception ex) {

        }

    }

 

}

执行,得到结果例如以下:

3.3.3 细说同步与异步

在旧的基于JAX-RPC的webservice编程model中,是不支持异步的service 调用的,在最新的Jax-ws webservice 编程model中,增加了对webservice的异步调用的支持。

首先我来讲一下它的原理,大家不要以为在异步的调用下,从client到server 之间的soap message 流也是异步的,事实上不是,Soap/Http 协议在同步跟异步的调用下是一样的,都是client的service在执行时打开一个connectin,发送请求,然后接收返回,这些都在同一个connection中。这种方式对我们有什么影响呢?从client程序的角度来讲,没有影响,client的编程模型是由WSDL中的messages跟port types 来定义的,仅仅要这些东西没有改变,request 跟response是不是在同一个Tcp/ip 的session 中来发送对与我们来说没由影响,然后从架构跟资源的角度来讲,对我们的影响就大了,把连接层的资源跟应用层的程序执行状态绑定起来是由很多弊端的,假如在异步调用时,程序执行出现了异常,将会导致连接层的资源被一直占用,这样会极大的影响我们程序的,稳定性,可靠性,资源的使用跟性能。

3.3.4 异步的还有一种实现

上例中实现的是一种“polling方式的异步调用”,以下给出“callback”方式的异步调用client。

由于此callBack当请求发出去以后当前的这个connection就会关闭 ,为了达到測试的目的,增加了sleep,让client程序等待server端得返回。

callback类型的client要传入一个javax.xml.ws.AsyncHandler类型的匿名内部类,当soapMessage 到达时,Jax-ws会调handleResponse这种方法来处理response.

client測试代码例如以下:

package ctsjavacoe.ws.fromjava;

import javax.xml.ws.AsyncHandler;

import javax.xml.ws.Response;

public class HelloAsyncCallBackClient {

    public static void main(String[] args) throws Exception {

        HelloService service = new HelloService();

        Hello port = service.getHelloPort();

        port.sayAsync("Mk", new AsyncHandler<SayResponse>() {

            public void handleResponse(Response<SayResponse> res) {

                try {

                    SayResponse response = null;

                    response = res.get();

                    String message = response.getReturn();

                    System.out.println(message);

                } catch (Exception e) {

                    e.printStackTrace();

                }

            }

        });

        Thread.sleep(1000);

    }

}

转载于:https://www.cnblogs.com/mfrbuaa/p/4035406.html

5天学会jaxws-webservice编程第一天相关推荐

  1. 人人都能学会的python编程教程1:第一行代码

    前言 众所周知,现在IT行业很火,行业薪酬也很高,国家在2017年也发布了人工智能教育的推广计划,人人会编程的时代将要到来.不会编程.不懂编程可能有些跟不上时代的节奏,普通人不懂技术也许会觉得这个很难 ...

  2. 学会使用函数式编程的程序员(第2部分)

    本系列的第一篇: 学会使用函数式编程的程序员(第1部分) 组合函数 (Function Composition) 作为程序员,我们是懒惰的.我们不想构建.测试和部署我们编写的一遍又一遍的代码.我们总是 ...

  3. 函数式编程语言python-10分钟学会python函数式编程

    原标题:10分钟学会python函数式编程 在这篇文章里,你将学会什么是函数范式以及如何使用Python进行函数式编程.你也将了解列表推导和其它形式的推导. 函数范式 在命令式范式中,通过为计算机提供 ...

  4. 学会JavaScript函数式编程(第1部分)

    2019独角兽企业重金招聘Python工程师标准>>> 摘要: JS函数式编程入门. 原文:学会使用函数式编程的程序员(第1部分) 作者:前端小智 Fundebug经授权转载,版权归 ...

  5. 人人都能学会的python编程教程(基础篇)完整版

    人人都能学会的python编程教程1:第一行代码 人人都能学会的python编程教程2:数据类型和变量 人人都能学会的python编程教程3:字符串和编码 人人都能学会的python编程教程4:关系运 ...

  6. 学会JavaScript函数式编程(第3部分)

    摘要: JS函数式编程入门. 原文:学会使用函数式编程的程序员(第3部分) 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 本系列的其它篇: 学会使用函数式编程的程序员(第1部分) 学 ...

  7. 三步教会您如何才能快速学会CNC数控编程

    大家都知道,现在的cnc数控编程可以说是一门炙手可热的技术.据大数据统计,目前国内cnc数控编程技术员的工资在8000-15000的幅度之间.好多人就是看到了这么高的待遇而选择学习这门技术.但是,如何 ...

  8. 总结一下sun 公司自己的 JAX-WS WebService 用法

    JAX-WS WebService 是sun 公司自己推出的产品,给自己做个记录,好记性不如烂笔头,方便日后查询,废话不说直接干货. 第一种传统方式: 创建一个类如下: package com.web ...

  9. /* * 编程第一题(20分): 1+(1+2)+(1+2+3)+……+(1+2+3+……+98+99+100) */

    题目: /* 编程第一题(20分): 1+(1+2)+(1+2+3)+--+(1+2+3+--+98+99+100) */ 我是用的java做的 class One {public static vo ...

  10. 高阶函数||编程范式: 命令式编程/声明式编程 || 编程范式: 面向对象编程(第一公民:对象)/函数式编程(第一公民:函数)

    编程范式: 命令式编程/声明式编程 编程范式: 面向对象编程(第一公民:对象)/函数式编程(第一公民:函数) 高阶函数 filter/map/reduce filter中的回调函数有一个要求: 必须返 ...

最新文章

  1. [BZOJ 1014][JSOI2008]火星人prefix(Splay+二分+hash)
  2. 主从同步出现一下错误:Slave_IO_Running: Connecting
  3. matlab复数方程的根,matlab解一元三次方程,得到的都是复数根。
  4. 如何才算掌握Java(J2SE篇)
  5. 牛客网 在线编程 局部最小值位置
  6. Asp.Net Core 中的“虚拟目录”
  7. 从对集合数据去重到Distinct源码分析
  8. TypeSrcript如何引入第三方库 如果加d.ts以及async await如何使用 demo,只有代码,文字后续补充...
  9. 今日恐慌与贪婪指数为92 贪婪程度与昨日持平
  10. python读取大文件csv_对python中大文件的导入与导出方法详解
  11. 动态规划—最长公共子序列LCS及模板
  12. 如何选择适合自己的项目管理方法
  13. python中not是什么意思_python中的not具体使用及意思
  14. 利用adsl拨号服务器VPS构建代理IP池
  15. 高中数学集合知识点小题解题方法
  16. Android RxJava应用:优雅实现网络请求嵌套回调
  17. git merge 冲突解决
  18. n行数字组成的数字三角形详解
  19. SAGA GIS使用———加载以及显示影像
  20. 200 万年薪请不到!清华姚班到底有多牛?| 原力计划

热门文章

  1. pytorch损失函数
  2. 周末巨献:100+诡异的数据集,20万Eclipse Bug、死囚遗言
  3. Differential Privacy差分隐私
  4. Java集合系列总结
  5. Python的Cython在Windows环境下的部署安装
  6. C++Debug Assertion Failed!到底出错在哪里?
  7. 欧几里得算法和唯一分解定理
  8. String类中重写Object中的equals方法源码解析
  9. C++ override什么意思
  10. Thinkphp if标签不支持3层以上嵌套