第一部分 webservice快速概览
Webservice是基于WEB的系统级接口规范,它是一种标准,而不是一种技术,它的特点是:
1 一个普遍适用标准。2 任何网络通信的操作系统。3自包含、自描述、模块化。4 发布、定位、通过web调用
Java早期就有RMI(远程对象调用接口)技术,但必须遵循J2EE的标准,java和java之间是可以继承的。
.NET是com组件去集成,微软平台下的集成。
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.* |
怎么运作的?
UDDI发现服务 -----WSDL自描述文件--------基于SOAP简单对象传输协议------XML+XSD包装------通过HTTP请求---找到TCP/IP指定的服务器
简单的server端程序
public classRunDiscount {
public static void main(String[] args) {
//被封装后的启动程序
//Endpoint.publish("http://127.0.0.1:8080/discount",new DiscountServiceImpl());
//通过JaxWsServerFactoryBean设置详细参数
JaxWsServerFactoryBeanjpfb = newJaxWsServerFactoryBean();
jpfb.setAddress("http://127.0.0.1:8080/discount");//设置服务器地址
jpfb.setServiceClass(DiscountServiceImpl.class);//服务的提供者(实现类)
jpfb.getInInterceptors().add(newLoggingInInterceptor());//插入日志(入口)
jpfb.getOutInterceptors().add(newLoggingOutInterceptor());//插入日志(出口)
jpfb.create();//启动
}
}
@WebService
public interfaceDiscountService {
@WSDLDocumentation(value="根据会员号获取折扣")
public double getDiscount(StringNum);
}
简单的client端程序
通过wsdl2java 获取服务到client端
找到CXFHOME/BIN 通过wsdl2java –p 包名–d 本地保存地址–encoding 编码设置
Eg:
wsdl2java –pcom.boray.ws –d c:\demo –encoding utf-8 http://127.0.0.1:8080/discount
通过命令就可以在本地c盘下面的demo里找到提供服务的所有类。然后放到项目里。
public classDiscountClient {
public static void main(String[] args) {
JaxWsProxyFactoryBeanjpfb = newJaxWsProxyFactoryBean();
//服务地址
jpfb.setAddress("http://127.0.0.1:8080/discount");
//具体提供方法的接口
jpfb.setServiceClass(DiscountService.class);
//获取接口
DiscountServiceds = (DiscountService)jpfb.create();
//执行方法
System.out.println(ds.getDiscount("1000"));
}
}
第二部分JAXB
JAXB(JAVA Architecturefor XML binding)是业界的一个标准,是基于XML Schema 与 java 对象绑定的一种技术。
1. schema 编译器
2. schema 生成器
3. JAXB 运行环境
schema 编译器:schema 编译器以 XMLschema 为输入生成和schema 相对应的Java 类集,生成的Java 类中会根据schema 的结构自动包含了相应的JAXB 注解。
比方说 schema 里的一个元素映射的Java 类会自动用@XmlType 注解加以标注,一个元素的属性所映射的Java 字段会自动用@XmlElement 注解加以标注
schema 生成器:schema 生成器以包含 JAXB 注解的 Java 类集为输入生成相应的 XMLschema。比方说一个包含@XmlType 注解的Java 类在生成的
schema 中会被映射为一个元素;
JAXB 运行环境:JAXB 运行时环境提供了两个基本的操作用于 XML 文档的访问,操作以及验证等等:marshal、unmarshal,这两个操作也是XML 和Java 绑定的基础。Marshal 是指将一个内存对象以XML 文档形式进行编组处理的过程,unmarshal 则是一个相反的过程,将一个XML 文档解析为内存对象的过程。
从Java 到XML schema 的映射开发者可以通过JAXB 提供的注解来完成,在编程Java 类时可以使用JAXB 丰富的注解轻松地完成绑定定制。
在数据绑定和数据接受处理的过程中,需要对java对象进行编组和解组,也就是JAVA对象和XML互转。传递数据的过程中需要marshaller对java对象进行编组成XML传递。而在XML接收到之后需要通过ummarshaller对xml进行解组得到java对象。
l 编组(Marshalling)是把内存中的数据转化到存储媒介上的过程。Java 和XML 环境中,编组就是把一些Java 对象转化成一个(或多个)XML 文档
l 解组(Unmarshalling) 是把数据从存储媒介转换到内存中的过程--正好与编组相反。因此需要把 XML 文档解组到Java VM 中。
JAXB的相关注解元素
} @XmlRootElement 注解用于标注类或枚举类型,用它标注的类在映射后的schema 中会以一个全局元素的形式出现
} 参数:
◦ name 定制映射的 schema 全局元素的名称,一般来说以 @XmlRootElement标注的类在相应的XML 文档中会以最外层或根节点形式出现。
namespace 定义这个根节点命名空间,XML元素的名称空间名
} @XmlAccessorType 定义映射这个类中的何种类型需要映射到XML。
} 可接收四个参数,分别是:
◦ XmlAccessType.FIELD:映射这个类中的 private非静态所有字段到XML
◦ XmlAccessType.PROPERTY:映射这个类中的属性(get/set方法)到XML
◦ XmlAccessType.PUBLIC_MEMBER:将这个类中的所有public的field或property同时映射到XML(默认)
◦ XmlAccessType.NONE:不映射
例如:@XmlAccessorType(XmlAccessType.FIELD)
@XmlAccessorType(value = XmlAccessType.PROPERTY)
} @XmlType 注解用于标注类或枚举类型,用它标注的类在映射后的 schema 中中会以一个XML 复杂数据类型的形式出现
} 参数:
◦ propOrder 指定映射XML时的节点顺序,来指定输出顺序,来定制映射后的复杂数据类型的内容顺序
◦ factoryClass 指定UnMarshal时生成映射类实例所需的工厂类,默认为这个类本身
◦ factoryMethod 指定工厂类的工厂方法
◦ name 定义XML Schema中type的名称,定制映射的 XML数据类型的名称
◦ namespace 指定Schema中的命名空间
xml to wsdl
} 下载Trang
◦ http://www.thaiopensource.com/relaxng/trang.html
} XML -> XSD trang.jar
◦ java -jar trang.jar 源.xml 目标.xsd
} XSD -> WSDLxsd2wsdl.bat
◦ 冗余步骤,CXF无直接XSDtoJava
◦ xsd2wsdl -d 输出目录 -t 目标.xsd 目标.xsd<XSD-URL>
◦ WSDL -> Java wsdl2java
◦ wsdl2java -p 包名 –d 本地保存路径 源.wsdl<URL-路径>
第三部分 CXF (JAX-WS)
} 在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包 点击下载
源码二:webservice spring与CXF结合实现 实例和jar包都有 点击下载