---
layout: post
title: WebService
tags: WebService Java
categories: web
---
* TOC
{:toc}
**WSDL**
`definitions` 为根节点,属性为
>`name`:WS 名称,默认为“实现类 + Service”
>
>`targetNamespace`:WS 目标命名空间,默认为“WS 实现类对应包名倒排后构成的地址”
`definitions`的5个子节点
>`types`:描述了 WS 中所涉及的数据类型
>
>`portType`:定义了 WS 接口名称`portType.name`(`endpointInterface`默认为“WS 实现类所实现的接口”),及其操作名称,以及每个操作的输入与输出消息
>
>`message`:对相关消息进行了定义(供 types 与 portType 使用)
>
>`binding`:提供了对 WS 的数据绑定方式
>
>`service`:WS 名称及其端口名称`service_port.name`(`portName`默认为“WS 实现类 + Port”),以及对应的 WSDL 地址
**SOAP**
`header`
`body`
---
# `一`、产品
**soap**风格 (JAX-WS规范JSR-224)
JAX-WS RI:https://jax-ws.java.net/ Oracle 官方提供的实现
Axis:http://axis.apache.org/
CXF:http://cxf.apache.org/
**rest**风格 (JAX-RS规范JSR-339)
Jersey:https://jersey.java.net/ Oracle 官方提供的实现
Restlet:http://restlet.com/
RESTEasy:http://resteasy.jboss.org/
CXF:http://cxf.apache.org/
# `二`、JDK发布与调用
## `1`.发布
### 定义接口
~~~java
//此注解必须
@WebService
public interface HelloService {
String say();
}
~~~
### 实现接口
~~~java
@WebService(serviceName = "HelloService",
portName = "HelloServicePort",
endpointInterface = "org.sllx.practice.jdkws.HelloService")
public class HelloServiceImpl implements HelloService {
@Override
public String say() {
return "helloWorld";
}
}
~~~
### 发布服务
~~~java
public class Server {
public static void main(String[] args){
String address = "http://localhost:8081/ws/soap/hello";
HelloService helloService = new HelloServiceImpl();
Endpoint.publish(address, helloService);
System.out.println("ws is published [" + address + "?wsdl]");
}
}
~~~
访问`http://localhost:8081/ws/soap/hello?wsdl`即可查看详情
## `2`.调用
### 静态客户端
`wsimport http://localhost:8080/ws/soap/hello?wsdl`//通过 WSDL 地址生成 class 文件
`jar -cf client.jar .` //通过 jar 命令将若干 class 文件压缩为一个 jar 包
`rmdir /s/q demo `//删除生成的 class 文件(删除根目录即可)
~~~java
public static void main(String[] args){
HelloService_Service hss = new HelloService_Service();
HelloService hs = hss.getHelloServicePort();
System.out.println(hs.say());
}
~~~
### 动态代理客户端
只需提供`HelloService`接口,无需jar
~~~java
public static void main(String[] args){
try {
URL wsdl = new URL("http://localhost:8081/ws/soap/hello?wsdl");
QName serviceName = new QName("http://jdkws.practice.sllx.org/", "HelloService");
QName portName = new QName("http://jdkws.practice.sllx.org/", "HelloServicePort");
Service service = Service.create(wsdl, serviceName);
HelloService helloService = service.getPort(portName, HelloService.class);
String result = helloService.say();
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
~~~
# `三`、CXF
User为自定义的POJO类
web发布示例集成spring
## `1.`SOAP风格
### 定义接口
~~~java
package top.rainynight.sitews.user.ws;
import top.rainynight.sitews.user.entity.User;
import javax.jws.WebService;
@WebService
public interface UserWS {
User lookOver(int id);
}
~~~
### 实现接口
~~~java
package top.rainynight.sitews.user.ws;
import top.rainynight.sitews.user.entity.User;
import org.springframework.stereotype.Component;
@Component("userWS")
public class UserWSImpl implements UserWS {
@Override
public User lookOver(int id) {
return new User();
}
}
~~~
### 发布服务
#### ①Jetty发布
配置依赖
~~~xml
UTF-8
3.0.0
org.apache.cxf
cxf-rt-frontend-jaxws
${cxf.version}
org.apache.cxf
cxf-rt-transports-http-jetty
${cxf.version}
~~~
发布
~~~java
public class JaxWsServer {
public static void main(String[] args) {
JaxWsServerFactoryBean factory = new JaxWsServerFactoryBean();
factory.setAddress("http://localhost:8080/ws/user");
factory.setServiceClass(UserWS.class);
factory.setServiceBean(new UserWSImpl());
factory.create();
System.out.println("soap ws is published");
}
}
~~~
访问`http://localhost:8080/ws/user?wsdl`
#### ②Web发布
配置依赖
~~~xml
UTF-8
4.0.5.RELEASE
3.0.0
org.springframework
spring-web
${spring.version}
org.apache.cxf
cxf-rt-frontend-jaxws
${cxf.version}
org.apache.cxf
cxf-rt-transports-http
${cxf.version}
~~~
配置web.xml
~~~xml
org.springframework.web.context.ContextLoaderListener
contextConfigLocation
classpath:spring.xml
cxf
org.apache.cxf.transport.servlet.CXFServlet
cxf
/*
~~~
发布
~~~xml
~~~
访问`http://localhost:8080/ws/user?wsdl`
### 调用服务
#### ①静态客户端
~~~java
public class JaxWsClient {
public static void main(String[] args) {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setAddress("http://localhost:8080/ws/user");
factory.setServiceClass(UserWS .class);
UserWS userWS = factory.create(UserWS .class);
User result = userWS .lookOver(1);
System.out.println(result);
}
}
~~~
#### ②动态代理客户端
~~~java
public class JaxWsDynamicClient {
public static void main(String[] args) {
JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance();
Client client = factory.createClient("http://localhost:8080/ws/user?wsdl");
try {
Object[] results = client.invoke("lookOver", 1);
System.out.println(results[0]);
} catch (Exception e) {
e.printStackTrace();
}
}
}
~~~
#### ③通用动态代理客户端
既可调用 JAX-WS 服务,也可调用 Simple 服务
~~~java
public class DynamicClient {
public static void main(String[] args) {
DynamicClientFactory factory = DynamicClientFactory.newInstance();
Client client = factory.createClient("http://localhost:8080/ws/user?wsdl");
try {
Object[] results = client.invoke("lookOver", 1);
System.out.println(results[0]);
} catch (Exception e) {
e.printStackTrace();
}
}
}
~~~
#### ④Spring客户端
~~~xml
~~~
~~~java
public class UserWSClient{
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring-client.xml");
UserWS userWS= context.getBean("userWSClient", UserWS.class);
User result = userWS.lookOver(1);
System.out.println(result);
}
}
~~~
## `2`.REST风格
### 定义接口
`!`REST 规范允许资源类没有接口
>请求方式注解,包括:`@GET、@POST、@PUT、@DELETE`
>
>请求路径注解,包括:`@Path` ,其中包括一个路径参数
>
>数据格式注解,包括:`@Consumes`(输入)、`@Produces`(输出),可使用 `MediaType` 常量
>
>相关参数注解,包括:`@PathParam`(路径参数)、`@FormParam`(表单参数),此外还有 `@QueryParam`(请求参数)
~~~java
package top.rainynight.sitews.user.ws;
import top.rainynight.sitews.user.entity.User;
import javax.jws.WebService;
@WebService
@Path("/")
public interface UserWS {
@GET
@Path("{id:[1-9]{1,9}}")
@Produces(MediaType.APPLICATION_JSON)
User lookOver(@PathParam("id") int id);
}
~~~
### 实现接口
~~~java
package top.rainynight.sitews.user.ws;
import top.rainynight.sitews.user.entity.User;
import org.springframework.stereotype.Component;
@Component("userWS")
public class UserWSImpl implements UserWS {
@Override
public User lookOver(int id) {
return new User();
}
}
~~~
### 发布服务
#### ①jetty发布
配置依赖
~~~xml
UTF-8
3.0.0
2.4.1
org.apache.cxf
cxf-rt-frontend-jaxrs
${cxf.version}
org.apache.cxf
cxf-rt-transports-http-jetty
${cxf.version}
com.fasterxml.jackson.jaxrs
jackson-jaxrs-json-provider
${jackson.version}
~~~
发布
~~~java
public class Server {
public static void main(String[] args) {
// 添加 ResourceClass
List> resourceClassList = new ArrayList>();
resourceClassList.add(UserWSImpl .class);
// 添加 ResourceProvider
List resourceProviderList = new ArrayList();
resourceProviderList.add(new SingletonResourceProvider(new ProductServiceImpl()));
// 添加 Provider
List