1.创建一个java项目
2.创建接口
/**
* 接口中只需要把类注明为@WebService,把要暴露给客户端的方法注明
* 为@WebMethod即可,其余如@WebResult、@WebParam等都不是必要的
*/
@WebService
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface ISayHiService {
@WebMethod
void sayHiDefault();
@WebMethod
void sayHi(@WebParam(name = "name") String name);
@WebMethod
@WebResult(name = "valid")
int checkTime(@WebParam(name = "clientTime") Date clientTime);
}
3.创建实现类
@WebService(endpointInterface = "service.SayHiService")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public class SayHiService implements ISayHiService {
@Override
public void sayHiDefault() {
System.out.println("hi man");
}
@Override
public void sayHi(String name) {
System.out.println("hi" + name);
}
@Override
public int checkTime(Date clientTime) {
// 精确到秒
String dateServer = new java.sql.Date(System.currentTimeMillis())
.toString()
+ " "
+ new java.sql.Time(System.currentTimeMillis());
String dateClient = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.format(clientTime);
return dateServer.equals(dateClient) ? 1 : 0;
}
}
4.发布服务
a.普通java工程时,创建一个类
public class Test {
public static void main(String[] args){
Endpoint.publish("http://localhost:8080/testjws/service/sayHi",
new SayHiService());
}
}
b.web工程时
在WEB-INFO目录下创建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="SayHiService"
implementation="service.SayHiService"
url-pattern="/service/sayHi" />
</endpoints>
在web.xml中添加
<listener>
<listener-class>
com.sun.xml.ws.transport.http.servlet.WSServletContextListener
</listener-class>
</listener>
<servlet>
<servlet-name>SayHiService</servlet-name>
<servlet-class>
com.sun.xml.ws.transport.http.servlet.WSServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SayHiService</servlet-name>
<url-pattern>/service/sayHi</url-pattern>
</servlet-mapping>
5.运行项目
打开链接http://localhost:8080/testjws/service/sayHi?wsdl
成功显示则服务部署成功
6.创建webservice客户端
a.JDK生成
//切换到目标目录
//src 为生成的目录(dir)
//testjws.client 包名(package)
"%JAVA_HOME%inwsimport" -keep -d .src -p testjws.client http://localhost:8080/testjws/service/sayHi?wsdl
生成SayHiService接口与SayHiServiceService类
b.
7.测试
public class Test {
public static void main(String[] args) throws DatatypeConfigurationException {
SayHiService service = new SayHiServiceService().getSayHiServicePort();
service.sayHiDefault();
service.sayHi("789654123");
GregorianCalendar calender = new GregorianCalendar();
calender.setTime(new Date(System.currentTimeMillis()));
XMLGregorianCalendar xmldate = DatatypeFactory.newInstance().newXMLGregorianCalendar(calender);
System.out.println(service.checkTime(xmldate));
/*
URL url = new URL("http://localhost:8080/testjws/service/sayHi?wsdl");
QName qName = new QName("http://service/","SayHiServiceService");
Service service = Service.create(url, qName);
SayHiService port = service.getPort(SayHiService.class);
port.sayHi("hfuua651561h");
*/
}
}
服务端输出为:
hi man
hi789654123
客户端输出为:
0
一、服务端annotations
@WebService
此注示用来标明此java类为某个WebService的实现类或者标明此java接口定义了某个WebService的接口
@WebService有六个参数可以用来配置这个WebService的定义:
-
endpointInterface:指向一个定义此WebService抽象定义接口的完整类路径
- 此处如果不用"endpointInterface"指定接口,那么生成的WebService服务有三个操作"add","multi"和"minus",也就是定义在当前类中的方法集;如果指定了endpointInterface,则只有"add","multi",即定义在Calculator中的方法集
-
name:WebService名;默认的port名为"实现类名+Port",binding名为"实现类名+PortBinding",通过指定name的值来替换 实现类名。
-
portName:指定port名,可以完成替换默认port名,或由上面的"name"指定的port名。
-
targetNamespace:指定targetNamespace值,默认的值为 "http://包名/",可以通过此变量指定一个自定义的targetNamespace值。(注:如果分别定义和接口和实现,则他们有各自的 targetNamespace)
- serviceName:指定service名
- wsdlLocation:指向一个预定义的wsdl的文件,替代自动生成的wsdl文件。
-
@WebMethod
action:指定此方法对应的action
exclude:true --表示此方法包含在web服务中;false表示排除此方法
operationName:指定方法对应的operation的名字。
二、Client客户端
1.读取wsdl文件
URL url = new URL("http://localhost:8080/testjws/service/sayHi?wsdl");
2.调用Service中的Qname(一个wsdl中可能定义多个Service,所以需指定要调用的service名)
QName qName = new QName("http://service/", "SayHiServiceService");
3.创建Service
Service service = Service.create(url, qName);
4.取得相应的Port
SayHiService port = service.getPort(SayHiService.class);
5.调用方法
port.sayDefault();
(getPort()方法的参数:这个方法总是需要指定一个serviceEndpointInterface的类对象serviceEndpointInterface类需要加@WebService的annotation
serviceEndpointInterface的targetNamespace需要匹配对应的portType的namespace。默认是"http://包名/",必要时需要定义@WebService的targetNamespace属性加以改变
serviceEndpointInterface的name总是需要匹配要调用的PortType的name。默认是类名,必要时需要指定@WebService的name属性加以改变
serviceEndpointInterface中需要有对应于要调用的operation的方法定义)