`
lbxhappy
  • 浏览: 307314 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

在CXF中用JAXB数据绑定支持HashMap类型

    博客分类:
  • j2ee
阅读更多

SOAP中不支持HashMap,但可以通过适配器将数组转换成HashMap的方式来支持。

这是通过JAXB2.0中一个适配器类来转换的,先看下这个类的说明:

 

javax.xml.bind.annotation.adapters
类 XmlAdapter<ValueType,BoundType>

java.lang.Object








  继承者 javax.xml.bind.annotation.adapters.XmlAdapter<ValueType,BoundType>

类型参数:
BoundType - JAXB 不知道如何处理的一些类型。编写一个适配器,以便允许通过 ValueType 将此类型用作内存表示形式。
ValueType - JAXB 无需其他操作便知道如何处理的类型。


这样,我们先定义一个用来传送数据的通用数组,包含了KEY和VALUE两个成员用来存MAP的项:

public   class  OtherValues  {
    
public  OtherValues ()  {} ;
    
    
public  OtherValues (String key, String value)  {
        
this .key  =  key;
        
this .value  =  value;
    }
;
    
    
public  String key; 
    
    
public  String value;
}


再定义一个转换类:(数组到HashMap的转换)

import  java.util.HashMap;
import  java.util.Map.Entry;
import  org.apache.log4j.Logger;

import  javax.xml.bind.annotation.adapters.XmlAdapter;

public   class  OtherValuesAdapter  extends  XmlAdapter < OtherValues[], HashMap < String,String >>   {
    
static  Logger logger  =  Logger.getLogger (OtherValuesAdapter. class .getName());
    
  
public  HashMap < String, String >  unmarshal(OtherValues[] value )  {
      logger.error(
" unmarshal begin " );
    HashMap
< String, String >  r  =   new  HashMap < String,String > ();
    
for ( OtherValues c : value )
      r.put(c.key, c.value);
    
return  r;
  }

  
  
public  OtherValues[] marshal( HashMap < String,String >  value )  {
      logger.error(
" marshal begin " );
      OtherValues[] pairs 
=   new  OtherValues[value.size ()];
    
int  i  =   0 ;
    
for (Entry < String,String >  entry : value.entrySet())  {
        pairs[i
++ =   new  OtherValues (entry.getKey(), entry.getValue());
    }

    
return  pairs;
  }

}



我们需要在一个结构中来包含使用HashMap的变量,因为必须为这个变量再声明一个@XmlJavaTypeAdapter,这样JAXB才会在收到相应消息时调用我们的转换类。这是结构定义:

import  java.util.HashMap;
import  javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

public   class  MapValue  {
    
private  String devName;
    
private  String devIp;

    @XmlJavaTypeAdapter(OtherValuesAdapter.
class )
    
public  HashMap  < String, String >  otherValues;
    
    
public  String getDevIp()  {
        
return  devIp;
    }

    
public   void  setDevIp(String devIp)  {
        
this .devIp  =  devIp;
    }

    
public  String getDevName()  {
        
return  devName;
    }

    
public   void  setDevName(String devName)  {
        
this .devName  =  devName;
    }


}



最后,在SOAP服务的声明中,使用这个结构:(注意是sendAlarmMap方法)

import  java.util.List;

import  javax.jws. * ;
import  javax.jws.soap. * ;
import  javax.jws.soap.SOAPBinding. * ;

import  java.util.HashMap;
import  java.util.Map;

@WebService
public   interface  NotifyService  {
    
public   int  sendAlarm (DeviceValue alarm);
    
    
public  String sendAlarmString (String stralarm);
    
    
public  List < DeviceValue >  sendAlarmArr (List < DeviceValue >  arr);

    
public   int  sendAlarmMap (MapValue m);
    
}



下面,我们来看如何通过JAVA及PERL的方式调用这个服务:
JAVA的方式:

         NotifyService s  =  (NotifyService) getBean ( " notifyClient " );

             MapValue mv 
=   new  MapValue ();
            mv.otherValues 
=   new  HashMap < String, String >  ();
            mv.otherValues.put (
" hehe2 " " a " );
            mv.otherValues.put (
" 2 " " b " );

            mv.setDevIp (
" he " );
            mv.setDevName (
" hehe2 " );
            
            
int  r  =  s.sendAlarmMap(mv);
            logger.info(
" recv:  "   +  r);



PERL的方式:

{ #  call send map alarm
     my   @params   =  (SOAP :: Data -> name(arg0 => {
        devName
=> " hehe " ,  
        devIp
=> " ip1 " ,
        otherValues
=> [{
            item 
=>  [
               {key
=> " hehe1 " ,  value => " ip1 " } ,  
               {key
=> " hehe1 " ,  value => " ip1 " } ,  
               {key
=> " hehe1 " ,  value => " ip1 " } ,  
               {key
=> " hehe1 " ,  value => " ip1 " } ,  
               {key
=> " hehe1 " ,  value => " ip1 " } ,  
               {key
=> " hehe1 " ,  value => " ip1 " } ,  
               {key
=> " hehe1 " ,  value => " ip1 " } ,  
               {key
=> " hehe1 " ,  value => " ip1 " } ,  
               {key
=> " hehe1 " ,  value => " ip1 " } ,  
               {key
=> " hehe1 " ,  value => " ip1 " } ,  
               {key
=> " hehe2 " ,  value => " ip2 " }]
        }]
    }));
    
    
my   $method   =  SOAP :: Data -> name( ' sendAlarmMap ' );
    
    
my   $result   =   $soap -> call( $method   =>   @params );
    
    
print   " \nsend map alarm result:\n " ;
    
if  ( $result -> fault)
    {
       
print   $result -> faultstring;
    }
    
else
    {
       
print   $result -> result;
    }
    
print   " \n\n " ;
}



产生的SOAP消息如下:

请求:
<? xml version="1.0" encoding="UTF-8" ?> < soap:Envelope  xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance"  xmlns:soapenc ="http://schemas.xmlsoap.org/soap/encoding/"  xmlns:xsd ="http://www.w3.org/2001/XMLSchema"  soap:encodingStyle ="http://schemas.xmlsoap.org/soap/encoding/"  xmlns:soap ="http://schemas.xmlsoap.org/soap/envelope/" >< soap:Body >< sendAlarmMap >< arg0 >< devName > hehe </ devName >< otherValues >< item >< value > ip1 </ value >< key > hehe1 </ key ></ item >< item >< value > ip1 </ value >< key > hehe1 </ key ></ item >< item >< value > ip1 </ value >< key > hehe1 </ key ></ item >< item >< value > ip1 </ value >< key > hehe1 </ key ></ item >< item >< value > ip1 </ value >< key > hehe1 </ key ></ item >< item >< value > ip1 </ value >< key > hehe1 </ key ></ item >< item >< value > ip1 </ value >< key > hehe1 </ key ></ item >< item >< value > ip1 </ value >< key > hehe1 </ key ></ item >< item >< value > ip1 </ value >< key > hehe1 </ key ></ item >< item >< value > ip1 </ value >< key > hehe1 </ key ></ item >< item >< value > ip2 </ value >< key > hehe2 </ key ></ item ></ otherValues >< devIp > ip1 </ devIp ></ arg0 ></ sendAlarmMap ></ soap:Body ></ soap:Envelope >


回应:
< soap:Envelope  xmlns:soap ="http://schemas.xmlsoap.org/soap/envelope/" >< soap:Body >< ns1:sendAlarmMapResponse  xmlns:ns1 ="http://magic.nms.exchangebit.com/" >< return > 99 </ return ></ ns1:sendAlarmMapResponse ></ soap:Body ></ soap:Envelope >



总结:
有了转换器这个工具,我们可以在SOAP的JAXB绑定里支持各种JAVA的COLLECTION类型,以及自定义类型,打破了SOAP原始支持类型的限制。

 

分享到:
评论

相关推荐

    cxf-webservice复杂类型

    2. **自定义数据类型**:对于像Map这样的复杂类型,开发者可以创建自定义的数据类型来映射XML元素。这通常涉及到创建一个Java类,该类具有一个或多个属性,用于存储Map的键值对,并通过注解这些属性来指示CXF如何...

    CXF-JAXB包的处理问题

    而JAXB(Java Architecture for XML Binding)是Java平台的标准,用于将XML数据与Java对象之间进行绑定,使得开发者可以方便地在XML文档和Java对象之间转换。在处理CXF与JAXB的集成时,有时会遇到版本冲突的问题,...

    apache-cxf-3.1.18.zip

    - **强大的数据绑定**:CXF使用JAXB进行XML到Java对象的自动转换,简化了数据处理。 - **良好的社区支持**:由于是开源项目,Apache CXF拥有活跃的开发者社区,能及时解决用户遇到的问题。 总的来说,Apache CXF是...

    webservice实例 CXF的JAXWS和JAXRS实现 及JAXB标准接口实现带jar包

    在提供的压缩包“ws_test”中,很可能包含了使用CXF实现的Web服务示例,包括JAX-WS和JAX-RS的服务端点,以及使用JAXB进行数据交换的类。这个实例可能是全部手写的,意味着它提供了一整套从创建服务到处理请求和响应...

    cxf 完整的服务端客户端

    - Aegis:CXF 内置的数据绑定引擎,支持非标准的 Java 对象序列化。 通过这个“cxf 完整的服务端客户端”示例,你可以深入理解 CXF 如何处理服务发布、服务消费、数据绑定、异常处理等核心功能,并能更好地掌握 Web...

    07.处理Map等CXF无法自动转换的复合数据类型的形参和返回值

    然而,CXF在默认情况下并不支持所有类型的复杂数据类型,尤其是如Map、List这样的集合类型。当我们在服务接口中使用这些类型作为参数或返回值时,可能会遇到问题,因为CXF可能无法正确地序列化和反序列化它们。 ...

    04.使用CXF处理JavaBean式的复合类型和List集合类型的形参和返回值

    在实际应用中,我们需要在CXF服务端创建服务接口和实现,然后通过JAXB(Java Architecture for XML Binding)进行数据绑定。JAXB会自动将Java对象转换为XML,反之亦然。在服务接口中,可以定义如下的方法: ```java...

    cxf-core-3.2.4_cxf_源码

    CXF支持JAXB、Aegis等多种数据绑定机制。 6. **Message**:CXF中的消息模型用于表示通信中的数据,包括请求和响应。 在源码`cxf-core-3.2.4`中,我们可以看到以下几个关键模块: 1. **spi**:服务提供接口,定义了...

    Apache CXF之结合Spring配置发布WebServices(Aegis数据绑定)

    Aegis数据绑定支持基本的数据类型、集合、Map以及自定义的Java类,为开发者提供了一种灵活的方式来处理Java对象和服务之间的转换。 以下是使用Apache CXF结合Spring发布Web Services(Aegis数据绑定)的基本步骤: ...

    jaxb-api.jar.jaxws-api.zip_ jaxb-api.jar_cxf_jax-ws.jar_jaxb-api

    **JAXB(Java Architecture for XML Binding)** 是Java平台的一个标准,它允许开发者将XML文档和Java对象进行绑定,从而简化XML数据的处理。在Java 6中,JAXB是内置的API,但在更新的JDK版本中,它被移除了,转而...

    cxf-rt-databinding-jaxb-3.0.1-API文档-中文版.zip

    赠送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-...

    基于Apache CXF构建SOA应用 随书源代码

    覆盖以下内容:基于JAX-WS规范和CXF自身的前端模式实现,CXF支持的数据绑定(DataBindings),CXF支持的WSDL绑定,CXF支持的传输协议绑定。CXF的调式、配置、日志、发布和工具。CXF实现RESTful服务。CXF对WS-* 的...

    Cxf转换器示例

    1. **转换器实现**:开发者可能会定义一个或多个类,这些类实现了`org.apache.cxf.converters.Converter`接口,以便处理特定数据类型的转换。 2. **注册转换器**:为了让CXF知道如何使用这些转换器,开发者需要在...

    基于CXF的webService本地数据交互----PC端与Android端(二)

    - CXF的JAXB和XML绑定工具:用于处理数据序列化和反序列化。 总结,通过Apache CXF,我们可以轻松地在PC端和Android端之间建立Web Service通信,实现数据的高效交互。理解并掌握这些知识点对于跨平台应用开发至关...

    cxf基本jar包

    - `cxf-rt-databinding-jaxb.jar`:JAXB数据绑定支持。 - `cxf-rt-rs-extension-providers.jar`:RESTful服务的额外提供者。 以上就是关于CXF基本jar包的详细说明。在实际开发中,根据项目的具体需求,可能还需要...

    cxf与axis2区别

    Apache CXF目前仅支持JAXB和Aegis,默认是JAXB 2.0,但CXF 2.1版本中将支持XMLBeans、JiBX和Castor等数据绑定。 语言支持 Axis2支持多种语言,它有C/C++版本,能够满足更多的语言需求。Apache CXF目前暂不支持多...

    apache-cxf2.7.18官方版最稳定版本

    5. **数据绑定**:CXF支持多种数据绑定技术,如JAXB(Java Architecture for XML Binding)用于XML到Java对象的映射,以及Aegis绑定,用于非JAXB对象的XML处理。 6. **安全功能**:CXF提供了全面的安全性支持,包括...

    cxf多数据源配置

    在这样的背景下,"cxf多数据源配置"指的是如何在CXF项目中配置并管理多个数据源,以便灵活地访问和操作不同来源的数据。 【描述】:“通过cxf将多个webServices整合到一起方便管理与维护” 这个描述意味着我们正在...

    cxf-rt.zip

    2. **数据绑定**:CXF支持多种数据绑定技术,如JAXB(Java Architecture for XML Binding)用于将XML数据转换为Java对象,以及JAX-RPC(Java API for XML-based Remote Procedure Calls)。 3. **WS-*协议实现**:...

    apache-cxf-3.1.1跟3.1.6所有jar包

    4. **数据绑定**:CXF支持多种数据绑定技术,如JAXB(Java Architecture for XML Binding)用于XML和Java对象之间的转换,以及Aegis绑定,用于非JAXB对象的处理。 5. **MTOM和SwA支持**:CXF实现了Message ...

Global site tag (gtag.js) - Google Analytics