Webservice 学习笔记汇总
一、概念
1.什么是 webservice
web service 急 web服务,一种跨操作系统平台,跨编程语言的远程调用技术。
2. webservice 中的三要素
2.1 SOAP(simple object access protocol)
简单对象访问协议,是一种简单基于xml格式的协议,使用http协议交换信息,可以理解为 SOAP = Http + XML
2.2 WSDL(web service description language)
web service 描述语言:基于XML格式,用户描述 webservice 及其函数、参数、返回值,通俗可理解为webservice 的使用说明书。
2.3 UDDI (Universal Description Discovery and Integeration)
UDDI是一种目录服务,企业可以使用它对web service进行注册、搜索,从而达到资源共享促进全球经济合作。
二、使用JDK开发第一个webservice程序
JAX-WS(Java API for XML Webservices)
JAX-WS 规范是一组XML web services 的JAVA API
1.编写服务接口类
@WebService(name = "Login",// 定义Port名称
serviceName = "MyService", // 修改WebService服务名称
targetNamespace = "http://com.soft.ws/my" // 定义命名空间,默认为倒置的包名
)
public interface MyService {
// 提供一个对外公开的服务
@WebMethod(operationName = "authorization")
// 修改方法名
String authorization(@WebParam(name = "userId") String userId,
@WebParam(name = "password") String password);
}
2.服务接口实现类
/**
* 服务实现类
*/
@WebService(endpointInterface = "com.soft.platform.webservice.server.MyService",
name = "Login",// 定义Port名称
serviceName = "MyService", // 修改WebService服务名称
targetNamespace = "http://com.soft.ws/my" // 定义命名空间,默认为倒置的包名
//服务实现类和接口的注解要一样全
)
public class MyServiceImpl implements MyService {
@WebMethod(operationName = "authorization" // 修改方法名
)
@Override
public String authorization(
@WebParam(name = "userId") String userId,
@WebParam(name = "password") String password) {
// 业务方法
if ("admin".equals(userId) && "123456".equals(password)) {
return "success";
}
return "error";
}
}
3.发布服务
public class MyPublisher {
public static void main(String[] args) {
//指定服务url
String url = "http://localhost:8989/myservice";
//指定服务实现类
MyService server = new MyServiceImpl();
//采用命令行发布者Endpoint发布服务
Endpoint.publish(url, server);
}
}
4.查看服务的wsdl使用说明书
5.WSDL服务使用说明书阅读
注意:从下向上阅读,重点关注服务试图名称对象,通过服务试图名称获取bing标签,更具bing获取最终的服务核心类portType。
6.webservice客户端调用
6.1 生成客户端调用代码
使用wsimport命令,生成客户端调用代码
wsimport -d (生成.class 默认参数) . (当前目录) -p(指定包名) wsdl地址
wsimport -s (生成源代码) . (当前目录) -p(指定包名) wsdl地址
6.2 第一种调用方式
MyService service = new MyService();
Login loginPort = service.getLoginPort();
String s = loginPort.authorization("admin","123456");
System.out.println("s = " + s);
6.2 标准调用方式(通用)
URL url = new URL("http://localhost:8989/myservice?wsdl");
// 指定命名空间和服务名称
QName qName = new QName("http://com.soft.ws/my", "MyService");
Service service = Service.create(url, qName);
// 通过getPort方法返回指定接口
Login loginPort = service.getPort(new QName("http://com.soft.ws/my",
"LoginPort"), Login.class);
// 调用方法 获取返回值
String result = loginPort.authorization("jyc", "123");
System.out.println(result);
三、CXF发布webservice
Apache CXF 是一个开源的 webservice框架,它支持多种协议,比如:SOAP、XML/HTTP、RESTful HTTp等协议,CXF极大简化了webservice的服务发布与调用,并且与spring框架无缝整合
开发步骤:
1 导入CXF框架的依赖包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>3.1.6</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>3.1.6</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-core</artifactId>
<version>3.1.6</version>
</dependency>
2. 编写服务接口
@WebService
public interface WeatherService {
public String queryWeather(String cityName);
}
3. 编写接口实现类
@WebService
public class WeatherServiceImpl implements WeatherService {
@Override
public String queryWeather(String cityName) {
System.out.println("cityName = " + cityName);
return cityName + ":晴";
}
}
4 配置spring配置文件
4.1 服务bean注册
4.2 发现服务
address:代表服务地址 地址必须以 / 开头
serviceClass: 用来书写发布服务的接口全限定类名
服务地址应该为: http://ip:port/cxf/ws?wsdl
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<bean id="weatherService" class="com.jyc.webservice.WeatherServiceImpl"></bean>
<jaxws:server address="/ws" serviceClass="com.jyc.webservice.WeatherService">
<jaxws:serviceBean>
<ref bean="weatherService"/>
</jaxws:serviceBean>
</jaxws:server>
</beans>
4.3 配置web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!-- 初始化spring工厂的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-cfg.xml</param-value>
</context-param>
<!-- 启动spring工厂 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/cxf/*</url-pattern>
</servlet-mapping>
</web-app>
4.4 启动服务器,访问网址 http://localhost:9090/cxf/ws?wsdl
四、CXF 客户端的调用
1 生成客户端代码
wsimport -s . -p com.jyc.webservice http://localhost:9090/cxf/ws?wsdl
2 客户端关于spring文件的配置
<jaxws:client id="weatherClient"
address="http://localhost:9090/cxf/ws?wsdl"
serviceClass="com.jyc.webservice.WeatherService">
</jaxws:client>
3 客户端spring调用方式
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("spring-cfg.xml");
WeatherService weatherService = (WeatherService)context.getBean("weatherClient");
String result = weatherService.queryWeather("北京");
System.out.println("result = " + result);
五、RestFul开发步骤
说明: webService 的 restFul 和 springmvc 的 RestFul 都是 RestFul 风格的一种实现
1.导入jar包
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>3.1.6</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-core</artifactId>
<version>3.1.6</version>
</dependency>
<dependency>
<groupId>com.colobu</groupId>
<artifactId>fastjson-jaxrs-json-provider
</artifactId>
<version>0.1.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.9</version>
</dependency>
2.开发服务接口
@WebService
public interface MyService {
String authorization(String username,String password);
}
3.开发服务接口的实现类
@WebService
@Path("/myservice")
public class MyServiceImpl implements MyService {
@GET
@Path("/authorization/{username}/{password}")
@Produces("application/json;charset=UTF-8")
@Override
public String authorization(@PathParam("username") String username, @PathParam("password") String password) {
// 业务方法
if ("admin".equals(username) && "123456".equals(password)) {
return "success";
}
return "error";
}
}
4.spring-cfg.xml 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">
<bean id="myService" class="com.jyc.webservice.MyServiceImpl"></bean>
<bean id="fastJsonProvider" class="com.alibaba.fastjson.support.jaxrs.FastJsonProvider"></bean>
<!-- 发布服务 -->
<jaxrs:server address="/rest" serviceClass="com.jyc.webservice.MyService">
<jaxrs:serviceBeans>
<ref bean="myService"/>
</jaxrs:serviceBeans>
<!-- fastJosn 转换 json -->
<jaxrs:providers>
<ref bean="fastJsonProvider" />
</jaxrs:providers>
</jaxrs:server>
</beans>
5. web.xml 配置
<!-- 初始化spring工厂的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-cfg.xml</param-value>
</context-param>
<!-- 启动spring工厂 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- cxf配置 -->
<servlet>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/cxf/*</url-pattern>
</servlet-mapping>
6.启动服务器
7.浏览器访问URL测试
http://localhost:9090/cxf/rest/myservice/authorization/admin/123456
六、使用HttpClient调用rest的webService接口
1.引入httpclient依赖包
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>fluent-hc</artifactId>
<version>4.5.2</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
2.使用HttpClient框架调用服务接口
String asString = Request.Get("http://localhost:9090/cxf/rest/myservice/authorization/admin/123456")
//URL
.execute() //发送请求
.returnContent() //处理响应
.asString(); // 处理字符串
System.out.println("asString = " + asString);