由于篇幅有限,此处生出源代码,如有需要的在评论里面留下联系的方式,笔者到时联系你。转载请标明读者链接,谢谢。
一.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());
}
}
}
分享到:
相关推荐
3. **使用`DataBinding`**:CXF还提供了数据绑定机制,允许开发者自定义XML到Java对象的转换规则。通过实现`Unmarshaller`和`Marshaller`接口,可以完全控制复杂类型的序列化和反序列化过程。 **三、CXF Web服务...
而JAXB(Java Architecture for XML Binding)是Java平台的标准,用于将XML数据与Java对象之间进行绑定,使得开发者可以方便地在XML文档和Java对象之间转换。在处理CXF与JAXB的集成时,有时会遇到版本冲突的问题,...
- **强大的数据绑定**:CXF使用JAXB进行XML到Java对象的自动转换,简化了数据处理。 - **良好的社区支持**:由于是开源项目,Apache CXF拥有活跃的开发者社区,能及时解决用户遇到的问题。 总的来说,Apache CXF是...
在提供的压缩包“ws_test”中,很可能包含了使用CXF实现的Web服务示例,包括JAX-WS和JAX-RS的服务端点,以及使用JAXB进行数据交换的类。这个实例可能是全部手写的,意味着它提供了一整套从创建服务到处理请求和响应...
Aegis数据绑定支持基本的数据类型、集合、Map以及自定义的Java类,为开发者提供了一种灵活的方式来处理Java对象和服务之间的转换。 以下是使用Apache CXF结合Spring发布Web Services(Aegis数据绑定)的基本步骤: ...
CXF支持JAXB、Aegis等多种数据绑定机制。 6. **Message**:CXF中的消息模型用于表示通信中的数据,包括请求和响应。 在源码`cxf-core-3.2.4`中,我们可以看到以下几个关键模块: 1. **spi**:服务提供接口,定义了...
- Aegis:CXF 内置的数据绑定引擎,支持非标准的 Java 对象序列化。 通过这个“cxf 完整的服务端客户端”示例,你可以深入理解 CXF 如何处理服务发布、服务消费、数据绑定、异常处理等核心功能,并能更好地掌握 Web...
赠送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-...
4. **数据绑定配置**:为了使CXF能够识别和使用我们的自定义JAXB类,我们需要在CXF的配置中指定数据绑定。这通常在服务的XML配置文件或者通过Java代码进行。 5. **使用CXF扩展**:CXF提供了许多扩展点,如...
4. **数据绑定**:CXF支持多种数据绑定技术,如JAXB(Java Architecture for XML Binding)和XMLBeans,将XML数据自动映射为Java对象,简化了开发过程。 5. **安全机制**:CXF提供了丰富的安全特性,包括WS-...
**JAXB(Java Architecture for XML Binding)** 是Java平台的一个标准,它允许开发者将XML文档和Java对象进行绑定,从而简化XML数据的处理。在Java 6中,JAXB是内置的API,但在更新的JDK版本中,它被移除了,转而...
覆盖以下内容:基于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...
Axis2支持更多的数据绑定,包括XMLBeans、JiBX、JaxMe和JaxBRI,以及它原生的数据绑定(ADB)。Apache CXF目前仅支持JAXB和Aegis,默认是JAXB 2.0,但CXF 2.1版本中将支持XMLBeans、JiBX和Castor等数据绑定。 语言...
5. **数据绑定**:CXF支持多种数据绑定技术,如JAXB(Java Architecture for XML Binding)用于XML到Java对象的映射,以及Aegis绑定,用于非JAXB对象的XML处理。 6. **安全功能**:CXF提供了全面的安全性支持,包括...
总之,处理CXF中的编码问题需要对字符编码有深入的理解,并且熟悉CXF框架的配置和API。通过正确配置和使用各种工具,可以有效地避免和解决编码相关的问题,确保服务的正常运行和数据的准确传递。
3. **数据绑定**:CXF支持JAXB(Java Architecture for XML Binding)和其他数据绑定技术,允许对象模型与XML文档之间进行自动转换。在示例中,源码可能展示了如何利用这些绑定技术。 4. **测试用例**:为了验证...
4. **数据绑定**:CXF支持多种数据绑定技术,如JAXB(Java Architecture for XML Binding),用于将XML数据与Java对象之间进行自动转换。 5. **WS-Security**:CXF提供了对Web服务安全标准(如WS-Security、WS-...
2. **Data Binding**:CXF支持多种数据绑定机制,如JAXB(Java Architecture for XML Binding)用于将XML与Java对象相互转换,简化了Web服务的处理。 3. **WS-* Stack**:提供了对各种Web服务规范的支持,如WS-...
6. **数据绑定**:CXF支持JAXB(Java Architecture for XML Binding)和XMLBeans,用于将XML数据与Java对象之间进行自动转换。 7. **安全特性**:CXF提供了WS-Security和其他安全标准的实现,确保服务的安全性,如...