WebService
webService的几个重要术语
WSDL(Web Services Description Language):Web服务描述语言。一个XML文档,WSDL定义了Web Service 的名称、处理服务的方法、请求的参数及返回的数据格式。一个WebService对应唯一一个wsdl文档。
SOAP(Simple Object Access Protocol):简单对象传输协议。一个基于HTTP和XML的协议,用于在Web上的应用程序交换结构化的数据。
SEI(WebService Endpoint Interface):WebService服务端用来处理请求的接口。
CXF(Celtix + XFire):一个Apache的用于开发webService服务器和客户端框架。
常用的网络协议:
tcp:文件传输协议,底层文件传输,确保文件不会丢失。
udp:用户数据报协议,只传不效验,传输速度快,但是不确保文件不丢失。
http:超文本传输协议,针对网页的一种协议。
https:超文本加密协议,针对网页的一种加密协议。
ftp:文件传输协议,远程文件服务器所使用的协议,可以进行远程文件上传,下载。
smb:windows共享夹所使用的协议。
nfs:linux共享文件夹所使用的协议。
afp:苹果系统共享文件夹所使用的协议。
WSDL的基本结构
Types元素 :数据类型定义的容器
Message元素:通信消息的数据结构的抽象类型定义
PorType元素:可以描述一个Web Service可被执行的操作以及相关的消息
Binding元素:特定端口类型的具体协议和数据格式规范的绑定
Service元素:相关服务访问点的集合
SOAP的概述
SOAP(SImple Object Access Protocol,简称对象访问协议):基于XML的,用于在分布式环境下交换信息的轻量级协议。
SOAP 1.2规范与2003年6月24日被发布为W3C推荐标准
SOAP的优点:
- 与厂商无关
- 相对于平台独立 相
- 对与操作系统独立
- 相对与编程语言独立
JAX-WS(Java API for XML Web Service)
1.定义WebService接口(使用注解方式)
package com.znsd.ws.service;
import java.util.List;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
public interface MyService {
@WebMethod
public List<String> getState();
@WebMethod
public List<String> getCapital(String capital);
}
2.创建webService的实现类
package com.znsd.ws.service;
import java.util.ArrayList;
import java.util.List;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService(endpointInterface = "com.znsd.ws.service.MyService")
public class MyServiceImpl implements MyService {
static List<String> list = new ArrayList<>();
static {
list.add("中国");
list.add("美国");
list.add("日本");
list.add("韩国");
}
@Override
public List<String> getState(){
return list;
}
@Override
public List<String> getCapital(String capital){
List<String> li = new ArrayList<>();
switch (capital) {
case "中国":
li.add("北京");
break;
case "美国":
li.add("纽约");
break;
case "日本":
li.add("东京");
break;
case "韩国":
li.add("首尔");
break;
}
return li;
}
}
3.拟写测试类
package com.znsd.ws.test;
import javax.xml.ws.Endpoint;
import com.znsd.ws.service.MyServiceImpl;
public class Test {
public static void main(String[] args) {
String url = "http://localhost:6666/myweather/getmyweather";//创建所需连接的url
Endpoint.publish(url, new MyServiceImpl());
System.out.println("已发布");
}
}
4.在DOS下编译服务类至测试类(要确定好已配置好环境变量)
- 使用jdk的wsimport.exe在测试类项目src目录下进行编译
- 可以在dos里输入wsimport查看可以属性:其中-encoding 是选择服务类编译的字符编码,-p是服务类生产的包名,-keep是指定的URL需和服务类所创建的URL保持一致,并且在后面加上?wsdl
- (测试时需要注意将测试类和webService分为两个项目,测试时要将服务类始终运行)
测试类运行 - 获得java代码
package com.znsd.ws.client;
import java.util.List;
import com.znsd.ws.webservice.MyService;
import com.znsd.ws.webservice.MyServiceImplService;
import com.znsd.ws.webservice2.ArrayOfString;
import com.znsd.ws.webservice2.WeatherWS;
import com.znsd.ws.webservice2.WeatherWSSoap;
public class Test {
public static void main(String[] args) {
MyService m = new MyServiceImplService().getMyServiceImplPort();
List<String> state = m.getState();
System.out.println(state);
List<String> capital = m.getCapital("中国");
System.out.println(capital);
}
}
使用JAX-WS调用公共的webService(如:天气)
- 公共webService网址:http://www.webxml.com.cn
- 找到查询天气的WSDL: http://ws.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl(注意:如果直接使用该wsdl进行编译会编译失败)
- 在使用java语言调用.net编写的WebService时会解析错误,需要将wsdl的内容保存下来,将里面的节点:
<s:element ref="s:schama" /><s:any />
替换成<s:any minOccurs="2" maxOccurs="2" />
- 在通过本地文件生产代码
- 编译时keep 直接使用保存下来的xml文件全路径
在测试类进行运行测试
package com.znsd.ws.client;
import java.util.List;
import com.znsd.ws.webservice.MyService;
import com.znsd.ws.webservice.MyServiceImplService;
import com.znsd.ws.webservice2.ArrayOfString;
import com.znsd.ws.webservice2.WeatherWS;
import com.znsd.ws.webservice2.WeatherWSSoap;
public class Test {
public static void main(String[] args) {
WeatherWSSoap ws = new WeatherWS().getWeatherWSSoap(); //获得实列
ArrayOfString string = ws.getWeather("深圳",null);
System.out.println(string.getString());
}
}
Apche CXF WebService框架
导入所有jar包
(去掉geronimo-servlet_3.0_spec-1.0.jar,javax.servlet-api-3.1.0.jar 这两个jar包即可)
web.xml配置
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springws.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
<!-- 这是拦截地址 确定拦截位置 必须是services下的请求才会拦截 -->
</servlet-mapping>
关于服务只需要和上文JAX-WS服务类一样写法即可
配置springws.xml
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/bindings/soap
http://cxf.apache.org/schemas/configuration/soap.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<!--cxf 3.0版本后需去掉这两个文件配置
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml"/>-->
<!-- 配置服务路径的两种方式,取一即可 -->
<!-- 第一种配置方式 -->
<!--<bean id="weatherService" class=“com.lxit.service.impl.WeatherServiceImpl" />
<jaxws:endpoint id="wsServiceBean" implementor="#weatherService" address="/getWeather" publish="true" />-->
<!-- 第二种配置方式 -->
<jaxws:server serviceClass="com.lxit.service.impl.WeatherServiceImpl" address="/getWeather"/>
</beans>
然后运行服务得到下面的页面
然后在测试项目src下解析得到java文件即可,选取Endpoint address的路径:http://localhost:8080/spring-ws/services/getWeather?wsdl 记得在末尾加上wsdl之后的测试和上文的JAX-WS一样