WebService

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://+服务类的包名倒排"

name:webService的名称,默认为发布服务的类名。
portname:设置端口名。
serviceName:ws的服务名,默认为在类名后加Service,一般使用服务会先创建这个对象。
wsdlLocation:还没用。
endpointInterface:如果服务类实现了接口中的服务方法,可以使用这个属性来暴露这个接口,他指定的是接口的全类名。
@WebMethod:此注解用在方法,用于修改对外暴露的方法名和各种属性
exclude:设置该方法是否对外暴露,默认为false对外暴露。
operationName:修改对外暴露的方法名,指定wsdl中显示的方法名

@WebParam:此注解用在参数列表前:例public String getMessage(@WebParam(name="info")String params)。
name:指定wsdl中显示的参数名
@WebResult:用在返回类型前,public@WebResult(name="info") String getMessage(String params)
name属性用于指定wsdl显示的返回值的参数名




5.wsdl描述文件:
copy的资料:
WebService_第1张图片WebService_第2张图片


WebService_第3张图片

<portType>WSDL端口

<portType> 元素是最重要的 WSDL 元素。 它可描述一个 web service、可被执行的操作,以及相关的消息。 可以把 <portType> 元素比作传统编程语言中的一个函数库(或一个模块、或一个类)。 

<operation>子元素:

对服务中所支持的操作的抽象描述,一般单个Operation描述了一个访问入口的请求/响应消息对。

<message> WSDL消息)

<message> 元素定义一个操作的数据元素。 每个消息均由一个或多个部件组成。可以把这些部件比作传统编程语言中一个函数调用的参数。 

通信消息的数据结构的抽象类型化定义。使用Types所定义的类型来定义整个消息的数据结构。

<types>WSDL types

<types> 元素定义 web service 使用的数据类型。 为了最大程度的平台中立性,WSDL 使用 XML Schema 语法来定义数据类型。 

 

<binding> WSDL Bindings

<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.0jar包  其中jetty 服务器的包可以不要.因为我们要部署的tomcat服务器中了

3 在web.xml中配置cxf的核心servletCXFServlet

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>

未完待续。。。头疼







你可能感兴趣的:(WebService)