CXF处理复杂类型的数据

今天在学习WebService的时候用到@WebService注解,但是总是报错。因为没有这个包。搞了半个小时,终于解决了。

因为用的是java 10,因为java 9开始加入模块的概念。在java9/10中并没有javax.jws包。

最后还是安了个java8了终于搞好了,maven添加依赖的的形式,高了好久没有搞出来,实在是不推荐。

CXF解决Map等复杂类型

maven依赖:

 <dependency>
		<groupId>org.apache.cxf</groupId>
		<artifactId>cxf-core</artifactId>
		<version>3.1.5</version>
	</dependency>
  	<dependency>
		<groupId>org.apache.cxf</groupId>
		<artifactId>cxf-rt-frontend-jaxws</artifactId>
		<version>3.1.5</version>
	</dependency>
	<dependency>
		<groupId>org.apache.cxf</groupId>
		<artifactId>cxf-rt-transports-http-jetty</artifactId>
		<version>3.1.5</version>
	</dependency>

简单接口:

@WebService
public interface HelloWorld {
	public Map<String,List<Role>> getRoles();
}

实现:

@WebService
public class HelloWorldImpl implements HelloWorld{
	@XmlJavaTypeAdapter(MyAdapter.class);//xmljava类型适配器,自定义MyAdapter类
	public Map<String, List<Role>> getRoles() {
		Map<String,List<Role>> roleMap=new HashMap<String,List<Role>>();
		List<Role> roleList=new ArrayList<Role>();
		roleList.add(new Role(1,"项目经理"));
		roleList.add(new Role(2,"程序员"));
		roleMap.put("yefan", roleList);
		List<Role> roleList2=new ArrayList<Role>();
		roleList2.add(new Role(3,"销售经理"));
		roleList2.add(new Role(4,"需求分析师"));
		roleMap.put("jack", roleList2);
		return roleMap;
	}
}

自定义适配器:

public class MyAdapter extends XmlAdapter<MyMap[], Map<String ,List<Role>>>{//Map类型,通过对象数组实现转换
	@Override
	public Map<String, List<Role>> unmarshal(MyMap[] v) throws Exception {
		Map<String,List<Role>> map=new HashMap<String,List<Role>>();
		for(int i=0;i<v.length;i++) {
			map.put(v[i].getKey(), v[i].getValue());
		}
		return map;
	}
	@Override
	public MyMap[] marshal(Map<String, List<Role>> v) throws Exception {
		MyMap[] myMap=new MyMap[v.size()];
		int i=0;
		for(String key:v.keySet()) {
			myMap[i]=new MyMap();
			myMap[i].setKey(key);
			myMap[i].setValue(v.get(key));
			i++;
		}
		return myMap;
	}
}

自定义实现类:

public class MyMap {
	private String key;
	private List<Role> value;
	·····setter·getter······
}
主方法:
public static void main(String[] args) {
		System.out.println("start");
		
		HelloWorld implementor=new HelloWorldImpl();
		String address="http://192.168.77.1:8120/helloWorld";
		JaxWsServerFactoryBean jaxWsServerFactoryBean=new JaxWsServerFactoryBean();//通过他暴露接口与定义接口及实现
		jaxWsServerFactoryBean.setAddress(address);
		jaxWsServerFactoryBean.setServiceBean(implementor);
		jaxWsServerFactoryBean.setServiceClass(HelloWorld.class);
		jaxWsServerFactoryBean.create();
		
		System.out.println("started");
	}

开发客户端

使用wsdl2java 工具

(1)在http://cxf.apache.org/download.html下载工具包,解压到自定义路径。修改环境变量Path,添加其中bin文件夹的目录地址。

(2)在eclipse中新建maven项目 WS_client,添加依赖

(3)cmd进入上一步项目工作空间 

(4)使用指令 wsdl2java http://198.168.77.1:8120/helloWorld?wsdl

他会自动帮你解析wsdl,生成java文件

(5)测试

public static void main(String[] args) {
		HelloWorldService hws=new HelloWorldService();
		HelloWorld helloWorld=hws.getHelloWorldPort();
		MyMapArray myMapArray=helloWorld.getRoles();
		for(MyMap m:myMapArray.item) {
			System.out.println(m.key);
			for(Role r:m.value) {
				System.out.println(r.getRoleName());
			}
		}
	}

结果:

jack
销售经理
需求分析师
yefan
项目经理
程序员

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在调用 WebService 时,有时候会遇到 CXF 无法自动转化的类型,比如一些自定义类型或者复杂类型。此时,需要手动处理类型转化。 一种常见的方式是使用 JAXB 生成的 Java 类来处理类型转化。具体实现步骤如下: 1. 使用 `wsimport` 工具生成客户端代码。假设 WebService 的 WSDL 地址为 `http://localhost:8080/HelloWebService?wsdl`,则可以使用以下命令生成客户端代码: ``` wsimport -p com.example.client http://localhost:8080/HelloWebService?wsdl ``` 这里的 `-p` 参数指定了生成的 Java 类所在的包名。 2. 在程序中导入生成的 Java 类,然后使用它来处理类型转化。例如,如果 WebService 的方法返回类型为 `com.example.server.User`,而 CXF 无法自动转化这个类型,那么可以使用生成的 `com.example.client.User` 类来代替: ```java import com.example.client.User; import com.example.client.HelloWebService; public class HelloClient { public static void main(String[] args) { // 创建 WebService 客户端 HelloWebService client = createClient(); // 调用 WebService 方法 User user = client.getUserById(1); // 转化类型 com.example.server.User serverUser = convertUser(user); // 处理 serverUser } private static HelloWebService createClient() { // 创建 JaxWsProxyFactoryBean 对象 JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean(); // 设置 WebService 地址 factory.setAddress("http://localhost:8080/HelloWebService"); // 设置接口类型 factory.setServiceClass(HelloWebService.class); // 创建 WebService 代理对象 return (HelloWebService) factory.create(); } private static com.example.server.User convertUser(User user) { com.example.server.User serverUser = new com.example.server.User(); serverUser.setId(user.getId()); serverUser.setName(user.getName()); // 处理其它属性 return serverUser; } } ``` 在这个例子中,我们先调用 WebService 方法获取到一个 `com.example.client.User` 类型的对象,然后使用 `convertUser` 方法将它转化为 `com.example.server.User` 类型的对象。最后,我们可以使用 `serverUser` 对象来处理业务逻辑。 需要注意的是,这种方式需要手动处理类型转化,比较繁琐。如果类型比较复杂,也可能会出现转化错误的问题。因此,在设计 WebService 接口时,建议使用 CXF 支持的类型或者标准的数据交换格式(比如 XML、JSON 等),以避免类型转化的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值