由于篇幅有限,此处生出源代码,如有需要的在评论里面留下联系的方式,笔者到时联系你。转载请标明读者链接,谢谢。
一.JAXB简介
JAXB
是
CXF
一个默认的数据绑定,如果你不指定其他数据绑定在你的
Spring
配置中或者在
API
,你可以得到
JAXB
的数据绑定。自从
2.3.x
版本以后默认的使用
JAXB2.2
,
maven
使用者运行在
jdk6
之上将需要使用
java
认证的重写机制来使用
JAXB2.2
来替代
JAXB2.1
。
JAXB
使用
java
注解结合文件路径在
XML
和
Java
之间构建映射。
JAXB
支持编码优先和架构优先编程。架构优先支持创建客户代理、动态、运行时。详解见
CXF
的
DynamicClientFactory
类。
CXF
使用
JAXB
引用实现。为了学习更多关于注解类或者怎样把一个
schema
生成实体类,详见官网。
二. 解组和编组
解组:(
unmarshalling
)把数据从存储媒介上转化到内存中的过程,正好与编组相反。因此需要把
xml
文档解组到
Java VM
中。这里的复杂性不是在扁平数据中,因为这不是必需的,而在于从正确的数据到正确
Java
代码变量的映射。如果映射是错误的,就不可能正确的访问数据。当然,如果再尝试重新编组还会造成更大的问题,并且问题传播的很快。
编组:<!-- [if gte mso 9]><xml>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
</o:OfficeDocumentSettings>
</xml><![endif]-->(
marshalling
)是把内存中的数据转化到存储媒介上的过程。因此在
java
和
XML
环境中,编组就是把一些
Java
对象转换成一个或多个
XML
文档。在数据库环境中,则是把
Java
表示的数据存入数据库。显然,编组的秘密在于把
Java
实例中的面向对象结构转化成适用于
XML
的扁平结构,或者
RDBMS
中的关系结构。
三.代码以及分析
首先需要加入cxf所需要的包,在本次测试中,笔者添加了cxf的lib中全部的包。
下面直接上代码:
package com.syc.jaxb;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlJavaTypeAdapter(UserAdapter.class)
public interface User {
String getName();
}
此处注释的XmlJavaTypeAdapter是对自定义编组使用实现XmlAdapter的适配器,即UserAdapter这个类,该类实现了XmlAdapter适配器,因此要实现解组和编组两个方法。可能有的初学读者会提到:为什么我们要实现编组和解组呢?原因很简单,CXF不能直接支持List、Map等。
package com.syc.jaxb;
import javax.xml.bind.annotation.XmlType;
@XmlType(name="User")
public class UserImpl implements User{
String name;
public UserImpl(){}
public UserImpl(String n){
this.name =n;
}
@Override
public String getName() {
return name;
}
public void setName(String n){
this.name = n ;
}
}
该类是实现了User接口,并且重写getName()方法,此类可以看成一个User实体类,其实也没有什么区别。这里注释的XmlType是将UserImpl映射到 XML 模式类型,即我们得到的客户端的时候显示的类的名字是User。
package com.syc.jaxb;
import java.util.Map;
import javax.jws.WebService;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@WebService
public interface HelloWorld {
String sayHi(String text);
String sayHiToUser(User user);
@XmlJavaTypeAdapter(UserMapAdapter.class)
Map<Integer,User> getUsers();
}
该接口是暴露的服务,该服务有三个方法,暴露的服务必须使用@WebService注释,不然在发布服务的时候找不到不要发布的服务类。由于第三个方法返回的是一个Map类型,但
JAXB
不能将一些
Java
类型自然映射到
XML
表示形式,例如
,HashMap
或者其他非
JavaBean
类。如参数类型为接口,以及
Map
,这需要特殊的
XmlAdapter
类进行处理。因此这里我们需要注释成让XmlAdapter适配器来处理。
package com.syc.jaxb;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.jws.WebService;
@WebService(endpointInterface="com.syc.jaxb.HelloWorld",
serviceName="HelloWorld")
public class HelloWorldImpl implements HelloWorld {
Map<Integer,User> users = new LinkedHashMap<Integer, User>();
@Override
public String sayHi(String text) {
System.out.println("sayHello called...");
return "Hello " +text;
}
@Override
public String sayHiToUser(User user) {
System.out.println("sayUserHello called...");
users.put(users.size()+1, user);
return "Hello"+ user.getName();
}
@Override
public Map<Integer, User> getUsers() {
System.out.println("getMapUsers called...");
return users;
}
}
该类是服务类的一个实现。
package com.syc.jaxb;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class UserAdapter extends XmlAdapter<UserImpl, User>{
@Override
public User unmarshal(UserImpl v) throws Exception {
return v;
}
@Override
public UserImpl marshal(User v) throws Exception {
if(v instanceof UserImpl){
return (UserImpl)v;
}
return new UserImpl(v.getName());
}
}
在这里,UserImpl是value类型,User是alue类型。UserAdapter类继承了XmlAdapter类,因此需要重写marshal()和unmarshal()方法,即编组和解组,在此处,编组就是将bound类型修改为value类型,然后将value类型编组为xml表示形式;解组就是JAXB绑定框架首先将XML表示形式解组为value类型,然后将value类型修改为bound类型。在这里我们可以这么理解,编组即bound->value->xml形式,解组即xml形式->value->bound。
package com.syc.jaxb;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
@XmlType(name="UserMap")
@XmlAccessorType(XmlAccessType.FIELD)
public class UserMap {
@XmlElement(nillable=false,name="entry")
List<UserEntry> entries = new ArrayList<UserEntry>();
public List<UserEntry> getEntries() {
return entries;
}
public void addEntry(UserEntry entry){
entries.add(entry);
}
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name="UserEntry")
static class UserEntry{
public UserEntry(){
super();
}
public UserEntry(Map.Entry<Integer, User> entry){
super();
this.id = entry.getKey();
this.user = entry.getValue();
}
public UserEntry(Integer id,User user){
super();
this.id = id;
this.user = user;
}
@XmlElement(required=true,nillable=false)
Integer id;
User user;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
}
UserMap类是让cxf支持MAP的关键,该类可以将map里面的key-value转换为User实体类,把key当作user的id值,把value当作user的name值,然后再把user保存到一个集合中,即实现了hash值到实体类的转换。
package com.syc.jaxb;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class UserMapAdapter extends XmlAdapter<UserMap, Map<Integer,User>>{
@Override
public Map<Integer, User> unmarshal(UserMap v) throws Exception {
Map<Integer, User> map = new LinkedHashMap<Integer, User>();
for(UserMap.UserEntry e : v.getEntries()){
map.put(e.getId(), e.getUser());
}
return map;
}
@Override
public UserMap marshal(Map<Integer, User> v) throws Exception {
UserMap map = new UserMap();
for(Map.Entry<Integer, User> e : v.entrySet()){
UserMap.UserEntry u = new UserMap.UserEntry();
u.setId(e.getKey());
u.setUser(e.getValue());
map.getEntries().add(u);
}
return map;
}
}
这里即对UserMap和Map对象的编组和解组。
package com.syc.jaxb;
import javax.xml.ws.Endpoint;
public class Server {
public static void main(String[] args) {
System.out.println("Starting Server... ");
String address = "http://localhost:8899/hello";
HelloWorldImpl implementor = new HelloWorldImpl();
Endpoint.publish(address, implementor);
try {
Thread.sleep(5*60*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Exiting Server... ");
System.exit(0);
}
}
用WSDL2JAVA生成的客户端,调用服务端代码
package com.syc.jaxb.client;
import java.util.List;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
public class HelloClient {
public static void main(String[] args) {
JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();
factoryBean.setAddress("http://localhost:8899/hello");
factoryBean.setServiceClass(HelloWorld.class);
HelloWorld h = (HelloWorld) factoryBean.create();
System.out.println(h.sayHi("shenyc"));
User u = new User();
u.setName("syc");
System.out.println(h.sayHiToUser(u));
User u1 = new User();
u1.setName("ssss");
System.out.println(h.sayHiToUser(u1));
User u2 = new User();
u2.setName("aaaaa");
System.out.println(h.sayHiToUser(u2));
UserMap users = h.getUsers();
List<UserEntry> list = users.getEntry();
for(UserEntry ue : list){
System.out.println(ue.getId()+":"+ue.getUser().getName());
}
}
}
分享到:
相关推荐
处理cxf版本和jaxb包中冲突问题,解决webservice中遇到的版本问题
覆盖以下内容:基于JAX-WS规范和CXF自身的前端模式实现,CXF支持的数据绑定(DataBindings),CXF支持的WSDL绑定,CXF支持的传输协议绑定。CXF的调式、配置、日志、发布和工具。CXF实现RESTful服务。CXF对WS-* 的...
简单的webservice+Cxf+Spring数据对接实例以及jar.rar简单的webservice+Cxf+Spring数据对接实例以及jar.rar简单的webservice+Cxf+Spring数据对接实例以及jar.rar简单的webservice+Cxf+Spring数据对接实例以及jar.rar...
WebService CXF 用了一天时间找,官网打不开,国内要积分,下下来又永不了。最后终于搞到手,上传上来分享给大家。 jdk版本 CXF版本 java 9及以上 3.3.x java 8 3.x java 7 2.2x --- 3.2之前版本 java 6 3.1 ...
赠送jar包:cxf-rt-databinding-jaxb-3.0.1.jar; 赠送原API文档:cxf-rt-databinding-jaxb-3.0.1-javadoc.jar; 赠送源代码:cxf-rt-databinding-jaxb-3.0.1-sources.jar; 赠送Maven依赖信息文件:cxf-rt-...
webservice实例 CXF的JAXWS和JAXRS实现 及JAXB标准接口实现带jar包 全部手写,保证质量,导入就可以用
本包为springboot框架 添加了cxf 和根据aop 灵活的使用多数据源 根据自己的需求去添加数据源 只需要在application.yml中添加数据源信息 以别名定义数据源 再在dao层或是service层 方法或者类上方添加@DataSource(...
cxf 完整的服务端客户端
CXF webservice 使用实例,CXF创建webservice以及调用示例;WEBSERVICE输入、输出拦截器设置;用户验证;文件上传等。附带所有使用到的JAR包。
Apache CXF 是一个开源的 Web Services 框架。如果需要轻松实现 Web Services 的发布和使用,可以将其作为其中一种解决方案。
JAVA7和JAVA8对应CXF资源 WebService CXF 用了一天时间找,官网打不开,国内要积分,下下来又永不了。最后终于搞到手,上传上来分享给大家。 jdk版本 CXF版本 java 9及以上 3.3.x java 8 3.x java 7 2.2x --- ...
CXF 客户端最少jar包支持,CXF 客户端最少jar包支持,CXF 客户端最少jar包支持,
支持1.6版本的java 最高版cxf2.6.4 里面包含jar包以及使用说明
CXF 包含了大量的功能特性,但是主要集中在以下几个方面: 支持 Web Services 标准:...支持二进制和遗留协议:CXF 的设计是一种可插拨的架构,既可以支持 XML ,也可以支持非 XML 的类型绑定,比如:JSON 和 CORBA。
通过cxf将多个webServices整合到一起方便管理与维护
spring,cxf,restful发布webservice传递复杂对象,例如List,Map,List<Map>
CXF使用EndpointImpl发布WebService加入拦截器
cxf使用中编码问题,有关于gbk等的编码问题在cxf中的解决方法
cxf框架与jdk6出现冲突的支持包,请大家支持下!
spring 4.2.0 集成的cxf3.1.18的jar包,cxf-core-3.1.18.jar、cxf-rt-bindings-soap-3.1.18.jar、cxf-rt-databinding-jaxb-3.1.18.jar、cxf-rt-frontend-jaxws-3.1.18.jar、cxf-rt-frontend-simple-3.1.18.jar、cxf-...