加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

WebService(包括CXF)JAVA介绍

发布时间:2020-12-16 23:11:46 所属栏目:安全 来源:网络整理
导读:WebService(包括CXF)JAVA入门 ? 一. 什么是WedService WebService不是框架,甚至不是一种技术,而是一种跨平台,跨语言的规范,WebService的出现 是为了解决这样的需求场景: 不同平台,不同语言所编写的应用之间相互调用. 二. WedService有什么用? WebService可以

WebService(包括CXF)JAVA入门

?

一. 什么是WedService
WebService不是框架,甚至不是一种技术,而是一种跨平台,跨语言的规范,WebService的出现

是为了解决这样的需求场景: 不同平台,不同语言所编写的应用之间相互调用.

二. WedService有什么用?
WebService可以集中解决以下问题:
1. 远程调用
2. 跨平台调用
3. 跨系统调用

那么WebService在企业中有什么用呢?
1. 同一个公司新旧系统的整合.
2. 不同公司的业务整合: 业务的整合就要带来不同公司的系统整合,而不同公司的系统可能存

在平台不同,语言不同的问题.
3. 内容聚合: 一个应用需要提供天气预报,股票行情,黄金行情等,内容聚合的应用需要调用大

量不同平台,不同语言编写的应用的方法.

三. 面向服务架构(SOA)
1. 什么是面向服务架构: service1,service2,service3 - 所有组件都是"即插即用"的.
?? IBM提倡的SOA架构: 希望以"组装电脑"的方式来开发软件
?? ① 各种提供服务的组件
?? ② 企业服务总线(Enterpise Service Bus - ESB)
2. CXF号称是SOA框架


四. WebService三大技术基础

1. WSDL: web service definition language - web service定义语言

?? - 通俗地说,WSDL文档描述了Web Service如下三个方面:
?? - WHAT: 该Web Service 包含什么操作
?? - HOW: 该Web Service的操纵应该怎样调用
?? - WHERE: 该Web Service的服务地址

2. SOAP: Simple Object Access Protocol: 简单对象访问协议
??? 一次web service的调用,其实并不是方法调用,而是发送SOAP消息(即xml文档片段)


3. UDDI: Universal Description,Discovery and Integration
??? UDDI 是一种目录服务,企业可以使用它对 Web services 进行注册和搜索


※ 调用一次Web Service的本质:
1. 客户端把调用方法参数,转换成XML文档片段(SOAP消息 - input消息) - 该文档片段必须符

合WSDL定义的格式
2. 通过网络,把xml文档片段传给服务器
3. 服务器接收到xml文档片段
4. 服务器解析XML文档片段,提取其中的数据,并把数据转换调用Web Service所需要的参数值
5. 服务器端执行方法
6. 把执行方法得到的返回值,再次转换为生成为XML文档片段(SOAP消息 - output消息)- 该文

档片段必须符合WSDL定义的格式
7. 通过网络,把xml文档片段传给客户端
8. 客户端接受到xml文档片段
9. 客户端解析xml文档片段,并把数据转换调用Web Service的返回值
从上面调用本质来看,要一个语言支持web service唯一的要求是: 该语言支持xml文档的解析,

生成,支持网络传输


五、实际例子如下:

1,建立一个项目名为WebServiceDemo,普通JAVA项目
1.1在建立一个方法属于com.caoyong.webservice.ServiceDemo类:

//别忘了引入webservice
@WebService
public class HelloWord{
?//该方法就是要暴露给其他应用程序调用的方法
?public String sayHelloWord(String words)
?{
??return "HelloWord :" + words;
?}

?//这里我们使用main方法来发布我们的service
?public void static main(String[] args){
??Endpoint.publish("http://localhost:9091/caoyong/service/HelloWord",new

HelloWord());
??System.out.println("Service Publish Success");
?}
}

2.在打出"Service Publish Success"后,说明我们消息发布成功.
不成的话,注意确定服务器端口没有被占用;
成功后,在浏览器地址栏输入:http://localhost:9091/caoyong/service/HelloWord?wsdl就可以看

到该service的详细信息!

3.建立另外一个项目:WebClientDemo

关键的来了,打开cmd输入以下命令:
wsimport -s src的路径 -p 完整包名 -keep webservice的发布地址 然后回车就OK了,
比如说:
wsimport -s E:WorkBenchEclipseWebClientDemosrc? -p com.caoyong.webservice -

keep http://localhost:9091/caoyong/service/HelloWord
(如果wsimport命令失效,请检查是否把jdk配入环境变量!JAVA_HOME:JDK所在位

置,CLASSPATH:%JAVA_HOME%libtools.jar)
如果运行出现403错误,极有可能是IE中设置了代理,此时就取消代理。生成后可以再设置代

理。
回车后,会出现:
?parsing WSDL...
?generating code...
?compiling code...
恭喜你,成功了,你可以刷新一下你的WebClientDemo项目后会在com.caoyong.webservice包下

会有对应的WebService生成的文件!
然后调用如下:
public void static main(String[] args){
?HelloWord hw =new HelloWordService().getHelloWordPort();
?String str=hw.sayHelloWord("webService!");
?//最后str就是在WebServiceDemo项目下的sayHelloWord方法返回后的字符串。
}


六. 使用CXF开发WebService程序

1. 环境准备:

① 下载Apache cxf2.2.10环境: http://download.csdn.net/detail/zdp072/7429645

② 所需Jar包:

??? cxf-2.2.10.jar

??? geronimo-servlet_2.5_spec-1.2.jar

??? jetty-6.1.21.jar

??? jetty-util-6.1.21.jar

??? wsdl4j-1.6.2.jar

??? XmlSchema-1.4.5.jar

?

③ 配置path环境变量: E:Java_libapachecxfapache-cxf-2.2.10bin (cxf的解压目录)

??? 命令行输入: wsdl2java查看是否配置成功


2. 开发服务端:

① 开发一个Web Service业务接口,该接口要用@WebService修饰


@WebService?
public interface HelloService {?
??? public String sayHello(String name);?
}?


② 开发一个Web Service实现类,实现类也需要用@WebService修饰
//endpointInterface指定生成的接品名称,serviceName指定生成的服务端口类
//targetNamespace 可以指定生成的包路径

@WebService(endpointInterface="com.cy.service.HelloService",serviceName =

"HelloServiceImpl")
public class HelloServiceImpl implements HelloService {?
??? //加入WebParam注解,以保证xml文件中参数名字的正确性????
??? @Override?
??? public String sayHello(@WebParam(name="name") String name) {?
??????? return name + ",您好! 现在的时间是: " + new Date();?
??? }?
}?

?

③ 使用Endpoint类的静态方法发布WebService

public class MyServer {?
??? public static void main(String[] args) {?
??????? HelloService helloService = new HelloServiceImpl();?
??????? Endpoint.publish("http://localhost:9000/HelloService",helloService);?
??????? System.out.println("Web Service public success");?

??????? //被封装后的启动程序??
?????? //Endpoint.publish("http://localhost:9000/HelloService",new HelloServiceImpl());??
?????? // System.out.println("Web Service public success");?

?????? //通过JaxWsServerFactoryBean设置详细参数??
?????? JaxWsServerFactoryBeanjpfb = newJaxWsServerFactoryBean();?
?????? jpfb.setAddress("http://localhost:9000/HelloService");//设置服务器地址?
?????? jpfb.setServiceClass(HelloServiceImpl.class);//服务的提供者(实现类)??
?????? jpfb.getInInterceptors().add(newLoggingInInterceptor());//插入日志(入口)??
?????? jpfb.getOutInterceptors().add(newLoggingOutInterceptor());//插入日志(出口)??
?????? jpfb.create();//启动??

??? }?
}?

注: 每个Web Service组件需要2个部分: 接口(不是必须的)和实现类


④ 运行MyServer(CXF内置了一个Jetty Web服务器),在浏览器中输入以下地址:

http://localhost:9000/HelloService?wsdl,如果WebService暴露成功将会在浏览器里看到一个

xml文件

?

3. 开发客户端

① 打开命令行,cd进入客户端的src目录,直接在控制台使用 wsdl2java命令,即可在命令所在

目录下( 如笔者在 apache-cxf-2.2.10包的bin目录下调用wsdl2java 命令,生成的类文件就在

这个目录下),
运行: wsdl2java http://localhost:9000/HelloService?wsdl,目的就是通过暴露的wsdl生成Java

生成的HelloWorld类报错,如HelloWorld方法的super(WSDL_LOCATION,SERVICE,features);

这行报错,原因是javax.xml.ws.Service中缺少Service(URL,QName,WebServiceFeature[])

构造方法。我们引入的geronimo-jaxws_2.2_spec-1.1.jar包里,提供了新版本的Service类,

但是需要进行endorse才能够替换掉jre自带的Service类。为尽量较少以后移植的麻烦,我们

可以根据注释中的提示指定-frontend参数,使用JAX-WS 2.1兼容模式重新生成所有的类,顺

便用-p参数指定我们需要的命名空间:
wsdl2java -p com.cy.cxf.client.WSDL2Java -frontend jaxws21

http://localhost:9000/HelloService?wsdl
这样就会在MyClient工程SRC下面的包路径com.cy.cxf.client.WSDL2Java生成客户端代码

下在这个也可以
wsdl2java –pcom.boray.ws –d c:demo –encoding utf-8 http://localhost:9000/HelloService

② 写一个客户端测试类:
public class MyClient {?
??? public static void main(String[] args) {?
??????? HelloServiceImpl server = new HelloServiceImpl();?
??????? HelloService helloService = server.getHelloServiceImplPort(); // 返回一个代理?
??????? System.out.println(helloService.sayHello("zhangsan"));?????

??? }?
}?

4。JAX-WS代理
除了使用使用wsdl2java 直接生成客户端,我们也可以使用 Service.create 来生成服务实例,

下面的代码展示了这一过程:

??????? //方法一
??????? URL url = null;
??????? try {
??????????? url = new URL("http://localhost:9000/HelloService?wsdl");
??????? } catch (MalformedURLException e) {
??????????? java.util.logging.Logger.getLogger(HelloWorld.class.getName())
??????????????? .log(java.util.logging.Level.INFO,
???????????????????? "Can not initialize the default wsdl from {0}",

"http://localhost:9000/helloWorld?wsdl");
??????? }
??????? String? WSDL_LOCATION = url;
?????? QName SERVICE_NAME =???? new QName("http://apache.org/hello_world_soap_http",

?? "HelloServiceImpl");//其中第一个参数是定义服务实现类时指定的targetNamespace
??????? Service service = Service.create(url,SERVICE_NAME);
???????
??????? HelloService hs = service.getPort(HelloService.class);
??????? System.out.println(hs.sayHi("World"));


??????? //方法二。
?????? JaxWsProxyFactoryBeanjpfb = newJaxWsProxyFactoryBean();?
?????? //服务地址??
?????? jpfb.setAddress("http://localhost:9000/HelloService");?
?????? //具体提供方法的接口??
?????? jpfb.setServiceClass(HelloService.class);?
?????? //获取接口???
?????? HelloService hs = (HelloService)jpfb.create();?
?????? //执行方法??
?????? System.out.println(hs.sayHi(("ADMIN"));?


七 CXF(JAX-WS)
Jax-ws(jax-rpc)基于soap协议,底层支持三JAXB。
Jax-rs()是java针对REST(Representationstate Transfer)风格制定的web服务规范,基于http协议。狭义的WebService主要指RPC式

JAVA服务规范??? API包
JAX-RPC?????????? Javax.xml.rpc.*
JAX-WS??????????? Javax.xml.ws.*
JAX-M????????????? Javax.messaging.*
SAAJ?????????????? Javax.xml.soap.*
JAX-RS??????????? Javax.ws.rs.*
?


在SOAP 中方法的参数是有流向的

@WebParam 注解中的mode 属性

?????? javax.jws.WebParam.Mode 枚举

?????? IN(默认),OUT、INOUT 类型

如果是OUT、INOUT 类型的参数类型,客户端生成代码时会被变为

javax.xml.ws.Holder<T>类型

方法参数将会被当做返回值在Web服务调用完成后返回给客户端

注意不要导错包,不是javax.xml.rpc.Holder类型(JDK1.6 已经没有这个类型,但是

MyEclipse 还有

@javax.jws.Oneway 指定该方法只具有输入参数,但无返回值,不允许抛出非运行时异常

?????? 此批注必须只与@WebMethod 批注一起使用

如果条件不符JAX-WS 规范要求应该报告错误

但CXF 的策略是:

?????? 如果方法存在返回值,生成客户端时将被改为void;

?????? 如果方法参数含有OUT 类型,生成客户端时将被忽略;

?????? 如果方法含有INOUT类型参数,生成客户端时将只作为IN 类型参数被保留

javax.xml.ws.WebServiceContext 接口用于在Web 服务实现类中访问与服务请求有关的消

息上下文和安全信息

?????? 使用javax.annotation.Resource 标准注解启用这个接口

?????? EJB 等JAVA EE规范中的一些资源都使用这个注解注入

接口的getMessageContext()方法返回javax.xml.ws.handler.MessageContext接口,这是一

个实现了Map 接口的接口,它包含了一组属性集

服务端发布Web 服务可以使用javax.xml.ws.Endpoint接口发布Web 服务,

这样可以在开发JAX-WS的服务端时完全避开使用底层实现的API,统一使用标准的JAX-WS

的接口、注解等

但是在客户端访问Web 服务时我们使用了CXF 的JaxWsProxyFactoryBean来进行操作

?????? 其实也可以使用标准的JAX-WS 的API 完成客户端调用

JAX-WS 中的服务端的自定义异常使用javax.xml.ws.WebFault 注解来完成,这样的异常会

在WSDL 文件中的<wsdl:operation …中的子元素生成<wsdl:fault …

MTOM(SOAP Message Transmission Optimization Mechanism)SOAP 消息传输优化机制

,可以在SOAP消息中发送二进制数据,与SAAJ 传输附件不同,MTOM需要XOP(XML-

binaryOptimized Packing)来传输二进制数据

MTOM 允许将消息中包含的大型数据元素外部化,并将其作为无任何特殊编码的二进制数

据随消息一起传送

MTOM 消息会打包为多部分相关MIME 序列,放在SOAP 消息中一起传送

MTOM已经得到了大多数厂商的支持,包括微软等,所以使用这种方式处理SOAP 中的附件

,可以获得较大的通用性。

CXF? (JAX-RS)

REST 是一种软件架构模式,是基于HTTP协议的软件架构

REST 中重要的两个概念就是资源定位和资源操作

资源定位????? URL

资源操作????? HTTP(GET,POST,PUT,DELETE)

??????? 数据传输? 资源定位 资源操作
RPC?? HTTP?????? SOAP????? SOAP
REST HTTP????? HTTP?????? HTTP

?

REST 是一种软件架构理念,被移植到Web 服务

在开发Web 服务上,偏于面向资源的服务适用于REST,偏于面向活动的服务适用于SOAP

REST 简单易用,效率高,SOAP 成熟度较高,安全性较好

JAX-RS标准是将REST设计风格应用到Web 服务

JAX-RS(Java API for RESTful Web Service,JSR-311)是Java提供用于开发RESTfulWeb服

务基于注解(annotation)的API

Java EE 6中发布,旨在定义一个统一的规范,在javax.ws.rs.*包中,其中大部分也是注解

同时JAX-RS使用POJO编程模型和基于注解的配置并集成JAXB,有效缩短了REST应用的开

发周期

JAX-RS定义的包结构如下,包含近五十多个接口,注解和抽象类:

javax.ws.rs:包含用于创建RESTful服务资源的高层次(High-level)接口和注解;

javax.ws.rs.core:包含用于创建RESTful服务资源的低层次(Low-level)接口和注解;

javax.ws.rs.ext:包含用于扩展JAX-RS API支持类型的APIs;

JAX-RS规范只是定义API,真正开发RESTful Web服务需要引入具体实现,具体实现由第三

方提供

如Sun的参考实现Jersey,ApacheCXF,Jboss RESTEasy;

RESTful Web Services Java API (JAX-RS)

JAX-RS为在Java中构建RESTful Web服务提供了标准化API

API提供了一组注解

API提供相关的类和接口

对POJO应用注解允许你暴露Web资源

在JAX-RS中,一个Resource类代表一个网络资源,对该网络资源的任何请求被Resource类

中定义的方法处理

在Java中,一个Resource是一个POJO类,其中的方法至少有一个被@Path或HTTP方法指示

器(如@GET,@POST,@PUT,@DELETE,@OPTIONS)标注;

@Path注解指定了资源的相对路径

类资源URI是基于应用程序上下文的

例如:

@Path(/items)

如果应用程序上下文在这个例子中是http://example.com,

那么类资源的URI就是http://example.com/items

@Produces 用于服务方法描述上

用于指定返回值的类型

例如:

application/xml、application/json、image/jpeg 等)

@Produces(“application/xml”) 返回XML

默认值是*/*?? CXF 默认返回的是JSON 字符串

@QueryParam 注解用于指定将URL 上的查询参数传递给使用这个注解的属性值;

@PathParam 注解用于指定将URL 上的路径参数作为使用这个注解的属性值。

查询参数? url?key=value

路径参数? @Path(/items/{变量名})

@Path 的变量可以使用符合正则表达式“[^/]+?”

例如:

@Path("users/{username: [a-zA-Z][a-zA-Z_0-9]}")

@Produces 用于指示一个资源类(或服务接口)或者MessageBodyWriter 可以产出的

MIME 类型

@Consumes 用于指示资源类(或服务接口)或者MessageBodyReader 可以接受的MIME

类型

例如:

@Produces(“application/xml”)

@Produces("application/json")

Response 接口返回Http 的响应代码、响应头或者是一种实体

javax.ws.rs.ext.MessageBodyWriter 类负责marshall 响应实体,响应实体被直接输出(自定

义类型)或者是作为Response 的一部分

javax.ws.rs.ext.MessageBodyReader 类负责Unmarshall 响应实体,也就是读取实体

JAX-RS 中你有如下三种方式处理异常

直接使用Response 返回HTTP 响应代码,例如:400、500 等表示错误的响应代码。

将异常或错误代码包装为javax.ws.rs.WebApplicationException

throw new WebApplicationException(new MyException(“***”)); // 这是一个运行时异常

将异常转换为响应结果

注解??????????????????? 描述?????????????????? 例子
@QueryParam????? 查询参数
@PathParam??????? 路径参数
@MatrixParam???? 获取Martix 参数 info2/matrix;id=2;name=m.j
?????????????????????????????????????????????? getStudent(@MatrixParam("") Student student);
?
@FormParam?????? POST 提交参数
@HeadParam?????? HTTP 请求头参数
@CookieParam??? Cookie 参数
@DefaultValue???? 前六个注解未取到值时默认值
?
@Encoded????????? 禁用前四种注解自动解码
?

CXF WebClient 提供便捷的调用方案

XML | json? 转换? Object

?

看完此文应该基本还是不明白,那就download这两个程序源码研究一下吧。希望有帮助

源码一:webservice实例 CXF的JAXWS和JAXRS实现 及JAXB标准接口实现带jar包 点击下载
http://download.csdn.net/detail/johnstrive/6550893

源码二:webservice spring与CXF结合实现 实例和jar包都有 点击下载
http://download.csdn.net/detail/johnstrive/6551189

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读