JDK6提供了对Web Service原生的支持,对Web Service进行了完美的封装,完全隐藏了底层内容,甚至可以不用了解wsdl的具体规范。
下面来举个例子,依然从最简单的HelloWorld入手。
服务器端的Java类若要成为一个实现了Web Service的bean, 它需要遵循下边这些原则:
这个类必须是public类、不能是final的或者abstract、必须有一个公共的默认构造函数、绝对不能有finalize()方法。
JKD6 中定义的Web Service注释
1. @WebService 标注要暴露为Web Services的类或接口 ,包含属性:
targetNamespace 定义命名空间,默认为”http://”+”包名倒排”name Web Service 的名称,默认为类名
portName Web Service 的端口名称
serviceName Web Service 的服务名称
wsdlLocation 描述服务的预定义 WSDL 的位置
endpointInterface 定义服务抽象 Web Service 协定的服务端点接口的完整名称
2. @SOAPBinding 定义Web Service 在SOAP中的消息协议,包含属性:
style 定义消息的编码类型user 定义消息的格式化类型
3. @WebMethod 定义Web Service运作的方法,包含属性:
action 操作的活动operationName 与此方法匹配的 wsdl:operation 的名称
xclude 标注此方法是否被暴露,默认为false
4. @WebResult 定义返回值,返回值类型不能为接口类或抽象类,而且必须有个不带参的构造函数,包含属性:
name 设置wsdl中, 返回值的名称partName 表示此返回值的 wsdl:part 的名称
targetNamespace 返回值的 XML 名称空间
header 如果为 true,则结果是从消息头而不是消息正文获取的
5. @WebParam 定义方法的参数,参数类型不能为接口类或抽象类,而且必须有个不带参的构造函数,包含属性:
name 参数名称partName 表示此参数的 wsdl:part 的名称
targetNamespace 参数的 XML 名称空间
header 如果为 true,则结果是从消息头而不是消息正文获取的
mode 参数的流向(IN、OUT 或 INOUT 之一)
wsgen与wsimport命令说明:
wsgen命令的主要功能是用来生成合适的JAX-WS。它读取Web Service的终端类文件,在我们的例子中就是test.jws.service.HelloWorld,同时生成所有用于发布Web Service所依赖的源代码文件和经过编译过的二进制类文件,通常Web Service Bean中用到的异常类会另外生成一个描述Bean。它还能生成WSDL和符合规范的HelloWorld类Web Service。wsgen从资源文件生成一个完整的操作列表并验证是合法的。如果Web Service Bean中的方法有抛出异常,这一步是必需的,否则服务器无法绑定该对像。
命令参数说明:
-cp 定义classpath-r 生成 bean的wsdl文件的存放目录
-s 生成发布Web Service的源代码文件的存放目录(如果方法有抛出异常,则会生成该异常的描述类源文件)
-d 生成发布Web Service的编译过的二进制类文件的存放目录(该异常的描述类的class文件)
wsimport命令的主要功能是根据wsdl文件生成客户端存根及框架,负责与Web Service 服务器通信,并在将其封装成实例,客户端可以直接使用,就像使用本地实例一样。
命令参数说明:
-d 生成客户端执行类的class文件的存放目录-s 生成客户端执行类的源文件的存放目录
-p 定义生成类的包名
因为web的Http服务实际上就是请求和响应的交互,即service和client端的交互。
先建服务器端目录:webService
服务器端的类HelloWorld.java
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
@WebService(targetNamespace = "http://www.jwstest.org")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public class HelloWorld {
@WebMethod(action="toSayHello",operationName="toSayHello",exclude=false)
@WebResult(name="returnWord")//自定荵芽??方法返回蛟?在WSDL中相蜈?的描述
public String sayHello(@WebParam(name="userName")String userName) {
return"Hello :" + userName;
}
@WebMethod
public int getExp(int i, int j) {
return i / j;
}
// wsgen -cp ./bin -r ./wsdl -s ./src -d ./bin -wsdl atest.webService.HelloWorld
}
当前目录下面编译一下:
javac HelloWorld.java
建3个目录:src,bin,wsdl
执行以下命令行语句:
wsgen -cp ./ -r ./wsdl -s ./src -d ./bin -wsdl HelloWorld
编写StartService.java(webservice启动器)
import javax.xml.ws.Endpoint;
public class StartService {
public static void main(String[] args) {
Endpoint.publish("http://localhost:8080/webservice/hws", new HelloWorld());
}
}
编译 javac StartService.java
启动服务:
java StartService
1:可以用jconsole查看服务是否启动。
2:也可以在浏览器地址栏中输入:http://localhost:8080/webservice/hws
会显示:
Web Services
No JAX-WS context information available.
http://hiyachen.blog.chinaunix.net
3:http://localhost:8080/webservice/hws?wsdl
如果 一个XML文件显示,OK,已经启动。
服务器,其实已经做好了。简单吧。
下面做客户端:
建客户端目录client,当然也可以换台机器来做,更形象。
重新用cmd起一个命令行容器。
同样建3个目录:src,bin,wsdl
wsimport -d ./bin -s ./src -p client http://localhost:8080/webservice/hws?wsdl
parsing WSDL...
generating code...
compiling code...
chf@tsinghua.org.cn
会生成2个文件:HelloWorld.java HelloWorldService.java
移到client根目录下。编译一下。
编写文件:ClientRun.java
public class ClientRun {
/**
*@paramargs
*/
public static void main(String[] args) {
HelloWorldService hws = new HelloWorldService();
HelloWorld hw = hws.getHelloWorldPort();
System.out.println(hw.getExp(9, 3));
System.out.println(hw.toSayHello("hiyachen"));
}
}编译 javac ClientRun.java
运行:java ClientRun
以下结果就OK了.
3
Hello:hiyachen
环境:
JDK6,soap1.1,wsdl,annotation
webservice其实也不难,再用上java的servlet类,就可以编出个tomcat了。
加上socket的
Socket client = new Socket("127.0.01.", 80); //客户端向port:80发送请求
ServerSocket server = new ServerSocket(80); //服务器监听port:80的请求。