Apache CXF 整合 Map

在进行编码前有必要对一些基本的认识进行介绍,以便后面的讲解。

1、JAXB:

JAXB能够使用Jackson对JAXB注解的支持实现(jackson-module-jaxb-annotations),既方便生成XML,也方便生成JSON,这样一来可以更好的标志可以转换为JSON对象的JAVA类。JAXB允许JAVA人员将JAVA类映射为XML表示方式,常用的注解包括:@XmlRootElement,@XmlElement等等。

JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档。从另一方面来讲,JAXB提供了快速而简便的方法将XML模式绑定到Java表示,从而使得Java开发者在Java应用程序中能方便地结合XML数据和处理函数。

2、Java SE中的JAXB

JAXB 2.0是JDK 1.6的组成部分。JAXB 2.2.3是JDK 1.7的组成部分。

2.1 JDK中JAXB相关的重要Class和Interface:
    JAXBContext类,是应用的入口,用于管理XML/Java绑定信息。
    Marshaller接口,将Java对象序列化为XML数据。
    Unmarshaller接口,将XML数据反序列化为Java对象。

2.2 JDK中JAXB相关的重要Annotation:
    @XmlType,将Java类或枚举类型映射到XML模式类型
    @XmlAccessorType(XmlAccessType.FIELD) ,控制字段或属性的序列化。FIELD表示JAXB将自动绑定Java类中的每个非静态的(static)、非瞬态的(由@XmlTransient标注)字段到XML。其他值还有XmlAccessType.PROPERTY和XmlAccessType.NONE。
    @XmlAccessorOrder,控制JAXB 绑定类中属性和字段的排序。
    @XmlJavaTypeAdapter,使用定制的适配器(即扩展抽象类XmlAdapter并覆盖marshal()和unmarshal()方法),以序列化Java类为XML。
    @XmlElementWrapper ,对于数组或集合(即包含多个元素的成员变量),生成一个包装该数组或集合的XML元素(称为包装器)。
    @XmlRootElement,将Java类或枚举类型映射到XML元素。
    @XmlElement,将Java类的一个属性映射到与属性同名的一个XML元素。
    @XmlAttribute,将Java类的一个属性映射到与属性同名的一个XML属性。

3、解组和编组

解组:( unmarshalling )把数据从存储媒介上转化到内存中的过程,正好与编组相反。因此需要把 xml 文档解组到 Java VM 中。这里的复杂性不是在扁平数据中,因为这不是必需的,而在于从正确的数据到正确 Java 代码变量的映射。如果映射是错误的,就不可能正确的访问数据。当然,如果再尝试重新编组还会造成更大的问题,并且问题传播的很快。
    编组:( marshalling )是把内存中的数据转化到存储媒介上的过程。因此在 java 和 XML 环境中,编组就是把一些 Java 对象转换成一个或多个 XML 文档。在数据库环境中,则是把 Java 表示的数据存入数据库。显然,编组的秘密在于把 Java 实例中的面向对象结构转化成适用于 XML 的扁平结构,或者 RDBMS 中的关系结构

好的,下面开始编码了。工程以上一篇的为基础。

一、创建Person类

其代码为:

package com.yao.spring.bean;

import java.io.Serializable;

public class Person implements Serializable{

	private static final long serialVersionUID = -283567759187941425L;

	private String name;

	private int age;

	@Override
	public String toString() {
		return "Person [age=" + age + ", name=" + name + "]";
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

}

二、因为我们其中要返回一个Map<String,Person>的类型,所以我们要实现一个解组和编组的适配器工具。

2.1 创建Map转换器类:MapConvertor,@XmlType注释标明该类可以转化为xml类型,@XmlAccessorType(XmlAccessType.FIELD) ,控制字段或属性的序列化。

package com.yao.spring.util;

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.XmlType;

@XmlType(name = "MapConvertor")
@XmlAccessorType(XmlAccessType.FIELD)
public class MapConvertor {
    private List<MapEntry> entries = new ArrayList<MapEntry>();

    public void addEntry(MapEntry entry) {
        entries.add(entry);
    }

    public List<MapEntry> getEntries() {
        return entries;
    }

    public static class MapEntry {

        private String key;

        private Object value;

        public MapEntry() {
            super();
        }

        public MapEntry(Map.Entry<String, Object> entry) {
            super();
            this.key = entry.getKey();
            this.value = entry.getValue();
        }

        public MapEntry(String key, Object value) {
            super();
            this.key = key;
            this.value = value;
        }

        public String getKey() {
            return key;
        }

        public void setKey(String key) {
            this.key = key;
        }

        public Object getValue() {
            return value;
        }

        public void setValue(Object value) {
            this.value = value;
        }
    }
}

2.2 创建Map适配器类 MapAdapter,用于编组与解组,重写XmlAdapter的
编组(marshal
)与解组(unmarshal)方法。

package com.yao.spring.util;

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

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

/**
 * 对Map类型做转换的类和适配器类
 * @author Kangjun
 *
 */
public class MapAdapter extends XmlAdapter<MapConvertor, Map<String, Object>> {

    @Override
    public MapConvertor marshal(Map<String, Object> map) throws Exception {
        MapConvertor convertor = new MapConvertor();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            MapConvertor.MapEntry e = new MapConvertor.MapEntry(entry);
            convertor.addEntry(e);
        }
        return convertor;
    }

    @Override
    public Map<String, Object> unmarshal(MapConvertor map) throws Exception {
        Map<String, Object> result = new HashMap<String, Object>();
        for (MapConvertor.MapEntry e : map.getEntries()) {
            result.put(e.getKey(), e.getValue());
        }
        return result;
    }
}

这时的类结构如下:

三、创建要调用的接口:PersonService。注意到public Map<String, Person> getPersonMap()方法有注释@XmlJavaTypeAdapter(MapAdapter.class),此处注释的XmlJavaTypeAdapter是对自定义编组使用实现XmlAdapter的适配器,即MapAdapter这个类,该类实现了XmlAdapter适配器,因此要实现解组和编组两个方法。可能有的初学读者会提到:为什么我们要实现编组和解组呢?原因很简单,CXF不能直接支持Map。

package com.yao.spring.service;

import java.util.Map;

import javax.jws.WebService;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

import com.yao.spring.bean.Person;
import com.yao.spring.util.MapAdapter;

@WebService
public interface PersonService {

	public Person getPerson();

	@XmlJavaTypeAdapter(MapAdapter.class)
	public Map<String, Person> getPersonMap();
}

这时的类结构如下:

四、实现接口的方法类PersonServiceImpl:

package com.yao.spring.service;

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

import javax.jws.WebService;

import com.yao.spring.bean.Person;

@WebService(endpointInterface="com.yao.spring.service.PersonService")
public class PersonServiceImpl implements PersonService {

	@Override
	public Person getPerson() {
		Person p = new Person();
		p.setAge(22);
		p.setName("yaokj");
		return p;
	}

	@Override
	public Map<String, Person> getPersonMap() {
		Person p = new Person();
		p.setAge(25);
		p.setName("yaokj");
		Map<String, Person> map = new HashMap<String, Person>();
		map.put("yaokj", p);
		return map;
	}

}

五、修改cxf-servlet.xml文件,添加:<jaxws:endpoint id="personService" implementor="com.yao.spring.service.PersonServiceImpl" address="/PersonService"/>

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
    <jaxws:endpoint id="helloWorld" implementor="com.yao.spring.service.HelloWorldImpl" address="/HelloWorld"/>
	<jaxws:endpoint id="personService" implementor="com.yao.spring.service.PersonServiceImpl" address="/PersonService"/>
</beans>

六、修改client-beans.xml文件。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd">
    <bean id="client" class="com.yao.spring.service.HelloWorld" factory-bean="clientFactory" factory-method="create"/>
    <bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
        <property name="serviceClass" value="com.yao.spring.service.HelloWorld"/>
        <property name="address" value="http://localhost:8080/HelloSpringCXF/services/HelloWorld"/>
    </bean>

    <bean id="personClient" class="com.yao.spring.service.PersonService" factory-bean="personFactory" factory-method="create" />
    <bean id="personFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
    	<property name="serviceClass" value="com.yao.spring.service.PersonService"/>
    	<property name="address" value="http://localhost:8080/HelloSpringCXF/services/PersonService" />
    </bean>
</beans>

七、编写客户端代码:PersonClient

package com.yao.spring.client;

import java.util.Map;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.yao.spring.bean.Person;
import com.yao.spring.service.PersonService;

public class PersonClient {

	public static void main(String[] args) {
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"client-beans.xml"});

		PersonService personService = (PersonService)ctx.getBean("personClient");

		Person p =  personService.getPerson();
		System.out.println(p);

		Map<String,Person> map = personService.getPersonMap();
		System.out.println("map: "+map.get("yaokj"));

		ctx.close();
		System.exit(0);
	}

}

这时的类结构如下:

八、启动Tomcat

九、运行PersonClient,并打印,成功。

2014-8-21 2:12:02 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org[email protected]735cda3f: startup date [Thu Aug 21 02:12:02 CST 2014]; root of context hierarchy
2014-8-21 2:12:02 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [client-beans.xml]
2014-8-21 2:12:03 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.s[email protected]28e70e30: defining beans [client,clientFactory,personClient,personFactory]; root of factory hierarchy
2014-8-21 2:12:03 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromClass
信息: Creating Service {http://service.spring.yao.com/}HelloWorldService from class com.yao.spring.service.HelloWorld
2014-8-21 2:12:04 org.apache.cxf.wsdl.service.factory.ReflectionServiceFactoryBean buildServiceFromClass
信息: Creating Service {http://service.spring.yao.com/}PersonServiceService from class com.yao.spring.service.PersonService
Person [age=22, name=yaokj]
map: Person [age=25, name=yaokj]
2014-8-21 2:12:04 org.springframework.context.support.AbstractApplicationContext doClose
信息: Closing org[email protected]735cda3f: startup date [Thu Aug 21 02:12:02 CST 2014]; root of context hierarchy
2014-8-21 2:12:04 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
信息: Destroying singletons in org.s[email protected]28e70e30: defining beans [client,clientFactory,personClient,personFactory]; root of factory hierarchy

Apache CXF 整合 Map,布布扣,bubuko.com

时间: 2024-10-29 19:10:08

Apache CXF 整合 Map的相关文章

Apache CXF 整合Spring

一.创建一个 Java Web 工程,目录最终的结构如下图,下面我们将遂一说明: 二.把我们要用到的jar包全部放到lib目录下. 三.修改web.xml文件,整合CXF. <?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2e

Apache cxf 整合 Spring MVC

1.添加依赖pom.xml <?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://maven.apache.o

springMVC3+apache CXF+spring security3+mybatis3(proxool)整合项目

整合出现很多问题,这里就不例举了,大家各自修炼吧,这里我只提供demo架包,可以在里面折腾.这里我说一下为什么会有这样的框架:我们项目要求是为子系统提供权限认证和管理(web service),同时对这些web service进行权限管理.所以demo中对security做了url和方法级的认证做了扩展,但没做具体实现. 1.web.xml <?xml version="1.0" encoding="UTF-8" ?> <web-app xmlns

Apache CXF 3.0: CDI 1.1 Support as Alternative to Spring--reference

With Apache CXF 3.0 just being released a couple of weeks ago, the project makes yet another important step to fulfill the JAX-RS 2.0 specification requirements: integration with CDI 1.1. In this blog post we are going to look on a couple of examples

【Apache CXF】CXF对JAX-WS的支持

相关dependency,我使用的版本是2.7.11: <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>${cxf.version}</version> </dependency> <dependency> <groupId>org

【Java EE 学习第81天】【CXF框架】【CXF整合Spring】

一.CXF简介 CXF是Apache公司下的项目,CXF=Celtix+Xfire:它支持soap1.1.soap1.2,而且能够和spring进行快速无缝整合. 另外jax-ws是Sun公司发布的一套开发WebService服务的标准.早期的标准如jax-rpc已经很少使用,而cxf就是在新标准jax-ws下开发出来的WebService,jax-ws也内置到了jdk1.6当中. CXF官方下载地址:http://cxf.apache.org/download.html 下载完成之后,解压开压

Apache CXF+Spring开发环境搭建小试

最近手上一个项目要开发webservice,而原有系统使用了spring,所以在选择框架的时候,我选择了cxf,这样在开发整合的时候就比较方便了.在搭建开发环境的过程中发现这篇文章写得比较详细,所以就搬到自己博客里,希望给自己和同行做参考. CXF 应用开发 下面就将开始我们的 CXF Web Services 的开发之旅!首先,要有一个基于 Eclipse 的开发环境:然后,我们将利用这个开发环境开发一个简单的“调查投票”示例,同时我们将解释一些 CXF 在开发中进行配置的基本方法. 开发环境

cxf整合spring实现webservice

前面一篇文章中,webservice的服务端与客户端都是单独启动,但是在现实项目中,服务端单独启动太没有实际意义了,还是要整合框架启动,所以今天将记录如何整合spring框架. jar包下载地址如下: http://yun.baidu.com/share/link?shareid=547689626&uk=2836507213 (一).web.xml中添加spring与cxf的配置 <?xml version="1.0" encoding="UTF-8"

Apache CXF实现Web Service(2)——不借助重量级Web容器和Spring实现一个纯的JAX-RS(RESTful) web service

实现目标 http://localhost:9000/rs/roomservice 为入口, http://localhost:9000/rs/roomservice/room为房间列表, http://localhost:9000/rs/roomservice/room/001/ 为001号房间的信息, http://localhost:9000/rs/roomservice/room/001/person 为在001号房间主的人的列表 在Eclipse中新建一个Java Project (可