1.百度百科: 能使得运行在不同机器上的不同应用无须借助附加的、专门的第三方软件或硬件, 就可相互交换数据或集成。依据Web Service规范实施的应用之间, 无论它们所使用的语言、 平台或内部协议是什么, 都可以相互交换数据。Web Service是自描述、 自包含的可用网络模块, 可以执行具体的业务功能。
2.WebService的规则:1.使用xml的形式来描述数据
2.使用soap(simple object access protocal)协议来进行传输
3.wsdl(web service description language):来描述web service服务(如提供服务的地址,和提供服务的类的信息,要操作的方法,数据类型,等等。),他使用的xml形式来保存。
3.使用wsimport来生成的本地代理文件:
wsimport是java中的一个工具,使用要求:1.jdk的 版本要在 jdk 1.6.21及以上 ,wsimport编译后的文件如果在eclipse上运行,也必须使用与之对应的jdk版本,或者比他高一点也可以,但最好是对应版本的jdk
1. wsimport 命令: wsimport [opations] <wsdl_uri> 这个uri是指向wsdl文件的uri
wsimport -s生成java源文件,如果不加默认编译的是class文件
-d表示要输出的文件的位置,默认为当前命令所在的位置
-p定义文件生成的包名,默认为提供服务类的包名。
例:wsimport -s ./ http://192.168.6.148:8987/ws/getInfo?wsdl 将指定的wsdl文件在当前命令位置生成编译的class文件和源文件。
wsimport -keep -p com.union.ws http://192.168.6.148:8987/ws/getInfo?wsdl 在当前位置生成指定包名的class文件。
2.一般情况下会将生成的class文件打成jar包来导入项目中,打jar包的方法:
jar cvf 生成jar包文件名 文件的路径
例: jar cvf wsService.jar ./com 将命令行所在的位置的com文件夹打成名为wsService.jar文件。(这使用的相对对路径,也可以使用绝对的路径.)
4.使用Endpoint来发布服务:
Endpoint.publish(String address, Object implementor):
address 是对外发布服务的地址url 如http://192.168.6.148:8789/ws/webservice/info
implementor指的是提供服务的对象。
要发布的类上必须使用@WebService注解,
关于注解的使用:
@WebSerivce:1.必须使用在类或者接口上(当设置在接口上时,不能设置@WebService的属性,会报错)
2.只会将public类型的非static 和final的方法公开,protected default private不会被发布,
如果想某些public方法不对外方法,则可以在方法使用@WebMethod(exclude=true,默认值为false对外发布。)
3.属性:targetNamespace:定义名称空间,默认为"http://+服务类的包名倒排"
<portType> 元素是最重要的 WSDL 元素。 它可描述一个 web service、可被执行的操作,以及相关的消息。 可以把 <portType> 元素比作传统编程语言中的一个函数库(或一个模块、或一个类)。
<operation>子元素:
对服务中所支持的操作的抽象描述,一般单个Operation描述了一个访问入口的请求/响应消息对。
<message> 元素定义一个操作的数据元素。 每个消息均由一个或多个部件组成。可以把这些部件比作传统编程语言中一个函数调用的参数。
通信消息的数据结构的抽象类型化定义。使用Types所定义的类型来定义整个消息的数据结构。
<types> 元素定义 web service 使用的数据类型。 为了最大程度的平台中立性,WSDL 使用 XML Schema 语法来定义数据类型。
<binding> 元素为每个端口定义消息格式和协议细节。
6.使用cxf框架发布webService服务(Apache CXF = Celtix + XFire)
1.不借助于spring和servlet来发布webService其实和Endpoint一样,都是需要手动开启一个线程来运行服务。这种方式发布在jetty服务器上。
发布服务的两种方式:
1.ServerFactoryBean 类来发布服务,服务类上不需要加注解,其实加上注解也不会有作用。但有弊端,比如不能通过注解来修改服务名,方法名等等。并且不能使用cxf提供的拦截器。
2.JaxWsServerFactoryBean 类来发布服务,服务类必须加注解,如果不加注解虽然不会报错,但是wsdl文件不会描述任何的方法。可以使用cxf框架提供的拦截器。使用这种方式如果是接口来提供方法的话,将注解设置在接口上,如@WebService @WebMethod @WebParams @WebResult
//ServerFactoryBean bean = new ServerFactoryBean();
JaxWsServerFactoryBean bean = new JaxWsServerFactoryBean ();
UserService service = new UserServiceImpl();//对外提供webservcie的业务类或者接口
bean.setAddress(uri);//这个uri是对外暴露的地址
bean.setServiceClass(UserService.class);//设置提供服务的接口的类型,如果没有可以不设置
bean.setServiceBean(service);//设置提供服务的对象
//配置输入时日志拦截器
bean.getInInterceptors().add(new LoggingInInterceptor());
//配置输出时日志拦截器
bean.getOutInterceptors().add(new LoggingOutInterceptor());
bean.create();//发布服务
当线程关闭时,也会停止提供服务。
ServerFactoryBean和JaxWsServerFactoryBean发布的流程基本一致,都是设置提供服务的uri和提供服务的对象。只是ServerFactoryBean不能使用注解和拦截器。
ID: 2
Address: http://127.0.0.1:9999/hello
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml; charset=UTF-8
Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Length=[191], content-type=[text/xml; charset=UTF-8], Host=[127.0.0.1:9999], Pragma=[no-cache], SOAPAction=[""], User-Agent=[Apache CXF 2.4.2]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHi xmlns:ns2="http://jaxws.cxf.g.itcast.cn/"><arg0>test</arg0></ns2:sayHi></soap:Body></soap:Envelope>
从输出的日志可以看出,是通过post方式来接收外界的访问,
ID: 2
Encoding: UTF-8
Content-Type: text/xml
Headers: {}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHiResponse xmlns:ns2="http://jaxws.cxf.g.itcast.cn/">
<return>hello---->test</return>
</ns2:sayHiResponse></soap:Body>
</soap:Envelope>
这是服务器发送出去的数据。
webservice 访问流程:
1. 检测本地代理描述的wsdl是否与服务端的wsdl一致 ,俗称为握手
2. 通过soap协议实现通信 ,采用的是post请求 , 数据封装在满足soap规约的xml中
3. 返回数据 同样采用的是soap通信, 数据封装在满足soap规约的xml中
2.cxf和spring集成:cxf的项目已经集成了Spring(自带了Spring lib)所以CXF的服务都是在Spring的配置文件中完成的
使用的方式:
l 建立一个web项目
2 准备所有jar包,将CXF_HOME\lib项目下的所有jar包,全部都拷贝新项目的lib目录下.其中里面已经包含了Sring3.0的jar包 其中jetty 服务器的包可以不要.因为我们要部署的tomcat服务器中了
3 在web.xml中配置cxf的核心servlet,CXFServlet
4 此配置文件的作用类 拦截/ws/*的所有请求 类似Struts2的过滤器
配置web.xml文件:
<servlet>
<!--配置cxf核心控制器 -->
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/ws/*</url-pattern>
</servlet-mapping>
<!-- Spring 监听添加 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
配置spring.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxws="http://cxf.apache.org/jaxws" //需要这个命令
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">//这里也需要添加
<!-- 这样配置自身的服务也可以使用 -->
<bean id="userServiceImpl" class="cn.itcast.i.cxf.spring.ws."UserServiceImpl" />
<!-- id:逻辑名(既服务名) serviceClass=服务接口类 address:调用的路径 http://localhost:8888/项目名/ws/hello?wsdl> -->
<jaxws:server id="userService" serviceClass="cn.itcast.i.cxf.spring.ws.IUser" address="/hello">//address只需要这样,容器会自动补充uri
<jaxws:serviceBean>
<ref bean="userServiceImpl" />
</jaxws:serviceBean>
<!-- 添加拦截器,这里添加的是输入与输出的日志拦截器 -->
<jaxws:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
</jaxws:outInterceptors>
</jaxws:server>
</beans>
未完待续。。。头疼