CXF-05:使用CXF处理返回值的类型为Map、非JavaBean式的复合类
2016-10-15 18:08
417 查看
* 当形参、返回值的类型是String、基本数据类型时,CXF可以处理;
* 当形参、返回值的类型是JavaBean式的复合类、List集合、数组等时,CXF可以处理;
* 还有一些像 Map、非JavaBean式的复合类,CXF不可以处理;
处理思路:提供一个转换器,该转换器负责把CXF不能处理的类型,转换为CXF可以处理的类型
Web Service未加转换器目录图:
* 从头写起,代码不受前面文章的影响( jar 包地址 http://pan.baidu.com/s/1jHJ56BW
(Apache官网上也可以下载))
(一)编写一个返回 Map 的程序,暴露 CXF服务端 时报错
* 1 . 编写要暴露的功能 HelloWorld.java 接口代码,没有相应的实体类编写 User.java 与 Food.java 代码,编写该接口的实现类代码 HelloWorldWs.java
运行结果:编写的程序运行成功
{蟹王汉堡=org.fjava.cxf.model.Food@356f5b17,
海绵金币=org.fjava.cxf.model.Food@21c55e69, 一个汉堡=org.fjava.cxf.model.Food@24b950d1, 火腿肠=org.fjava.cxf.model.Food@268dc2d}
运行结果:暴露该接口 - 编写的程序运行失败,证明当返回值的类型是Map集合时,CXF不可以处理
(二)在CXF开发中,如果遇到系统无法自动处理的类型,就需要程序员自行处理。
处理思路:提供一个转换器,该转换器负责把CXF不能处理的类型,转换为CXF可以处理的类型
[b] Web Service加转换器后目录图:
[/b]
[b]
[/b]
[b]* 1 . 使用 @XmlJavaTypeAdapter
修饰CXF无法处理的类型
[/b]
使用该Annotation时,通过value属性指定一个转换器,这个转换器是XMLAdapter的子类(XmlJavaTypeAdapter在 Java EE 帮助文档里查看)
[b] * 操作为[b] HelloWorld.java
接口中加标签[/b]
[/b]
[b]* 2 . 实现自己的转换器
实现转换器时,需要开发一个CXF能处理的类型,操作为新建转换器 HelloXmlAdepter.java 类,新建CXF能处理的 StringFood.java 类[/b]
3 . 发布Web Service,写完后运行以下代码,若打印出 "Web Service暴露成功!"
则暴露成功;[/b]
[b]* 4 . 调用CXF提供的wsdl2java工具,根据WSDL文档生成相应的Java代码__CXF-02:使用CXF开发Web
Service客户端 http://blog.csdn.net/cheng_feng_xiao_zhan/article/details/52683987[/b]
* 5 . 编写客户端
客户端编写逻辑输出代码:
希望对你有帮助,祝你有一个好心情,加油!
若有错误、不全、可优化的点,欢迎纠正与补充;转载请注明出处!
* 当形参、返回值的类型是JavaBean式的复合类、List集合、数组等时,CXF可以处理;
* 还有一些像 Map、非JavaBean式的复合类,CXF不可以处理;
处理思路:提供一个转换器,该转换器负责把CXF不能处理的类型,转换为CXF可以处理的类型
Web Service未加转换器目录图:
* 从头写起,代码不受前面文章的影响( jar 包地址 http://pan.baidu.com/s/1jHJ56BW
(Apache官网上也可以下载))
(一)编写一个返回 Map 的程序,暴露 CXF服务端 时报错
* 1 . 编写要暴露的功能 HelloWorld.java 接口代码,没有相应的实体类编写 User.java 与 Food.java 代码,编写该接口的实现类代码 HelloWorldWs.java
import java.util.List; import java.util.Map; import javax.jws.WebService; import org.fjava.cxf.model.Food; import org.fjava.cxf.model.User; @WebService//J2EE文档里查看WebService public interface HelloWorld { //还有一些像 Map、非JavaBean式的复合类,CXF不可以处理; Map<String, Food> getAllFoods(); }
public class Food { private Integer id; private String name; private String describe; public Food() { super(); } public Food(Integer id, String name, String describe) { super(); this.id = id; this.name = name; this.describe = describe; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescribe() { return describe; } public void setDescribe(String describe) { this.describe = describe; } }
public class User { private Integer id; private String name; private String tel; private String describe; public Integer getId() { return id; } public User() { super(); } public User(Integer id, String name, String tel, String describe) { super(); this.id = id; this.name = name; this.tel = tel; this.describe = describe; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getTel() { return tel; } public void setTel(String tel) { this.tel = tel; } public String getDescribe() { return describe; } public void setDescribe(String describe) { this.describe = describe; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((describe == null) ? 0 : describe.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; User other = (User) obj; if (describe == null) { if (other.describe != null) return false; } else if (!describe.equals(other.describe)) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } }
import java.util.Date; import java.util.List; import java.util.Map; import javax.jws.WebService; import org.fjava.cxf.model.Food; import org.fjava.cxf.model.User; import org.fjava.cxf.ws.HelloWorld; import org.fjava.cxf.service.UserService; import org.fjava.cxf.service.UserServiceImpl; @WebService(endpointInterface="org.fjava.cxf.ws.HelloWorld", serviceName="HelloWorldWs") //endpointInterface=""表示实现的接口 serviceName是wsdl2java或其他语言后的文件名,可以不和HelloWorldWs相同 public class HelloWorldWs implements HelloWorld { @Override public Map<String, Food> getAllFoods() { UserService userService = new UserServiceImpl(); return userService.getAllFoods(); } }* 2 . 编写功能实现逻辑代码 UserService.java UserServiceImp.java
import java.util.List; import java.util.Map; import org.fjava.cxf.model.Food; import org.fjava.cxf.model.User; public interface UserService { List<Food> getFoodsByUser(User user); Map<String, Food> getAllFoods(); }
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.fjava.cxf.model.Food; import org.fjava.cxf.model.User; public class UserServiceImpl implements UserService { //为简单,不写Dao层,用一个HashMap来模拟内存中的数据库 static Map<User, List<Food>> foodDb = new HashMap<>(); static{ List<Food> catList1 = new ArrayList<Food>(); catList1.add(new Food(1 , "一个汉堡" , "是三层的,有夹层哦!")); catList1.add(new Food(2 , "火腿肠" , "这是章鱼哥从岸上偷运来的,据说很美味!")); foodDb.put(new User(1 , "海绵宝宝" , "123123123" , "开心的海绵宝宝!") , catList1); List<Food> catList2 = new ArrayList<Food>(); catList2.add(new Food(3 , "蟹王汉堡" , "橙色,亮金色,我的宝贝,我的爱!")); catList2.add(new Food(4 , "海绵金币" , "吃着金币样的甜甜饼,想着海绵宝宝赚的钱被扣了,哈哈哈,爽气!")); foodDb.put(new User(2 , "蟹老板" , "321321321" , "哇!好有钱的蟹老板") , catList2); } @Override public List<Food> getFoodsByUser(User user) { return foodDb.get(user); } @Override public Map<String, Food> getAllFoods() { Map<String, Food> map = new HashMap<String, Food>(); for (List<Food> foods : foodDb.values()) { for (Food food : foods) { map.put(food.getName(), food); } } return map; } }* 3 . 编写 Main方法 ServiceMainTest.java 与 CXF服务端暴露Main方法 ServiceMain.java
import java.util.Map; import javax.xml.ws.Endpoint; import org.fjava.cxf.model.Food; import org.fjava.cxf.ws.HelloWorld; import org.fjava.cxf.ws.impl.HelloWorldWs; //测试写的程序没有问题 public class ServiceMainTest { public static void main(String[] args){ HelloWorld helloWorld = new HelloWorldWs(); Map<String, Food> allFoods = helloWorld.getAllFoods(); System.out.println(allFoods); } }
运行结果:编写的程序运行成功
{蟹王汉堡=org.fjava.cxf.model.Food@356f5b17,
海绵金币=org.fjava.cxf.model.Food@21c55e69, 一个汉堡=org.fjava.cxf.model.Food@24b950d1, 火腿肠=org.fjava.cxf.model.Food@268dc2d}
import javax.xml.ws.Endpoint; import org.fjava.cxf.ws.HelloWorld; import org.fjava.cxf.ws.impl.HelloWorldWs; //发布Web Service public class ServiceMain { public static void main(String[] args){ HelloWorld hw = new HelloWorldWs(); //调用Endpoint的publish("本机地址","服务的提供者:一个Web Service对象")方法发布Web Service //如何设置cxf的服务端端口号:这是公司规定或个人设置,不可重复 Endpoint.publish("http://192.168.0.159:6786/sayHello", hw); System.out.println("Web Service暴露成功!"); //暴露成功后可以被任何平台的任何语言调用 //检查调用地址http://192.168.*.*/sayHello?wsdl } }
运行结果:暴露该接口 - 编写的程序运行失败,证明当返回值的类型是Map集合时,CXF不可以处理
(二)在CXF开发中,如果遇到系统无法自动处理的类型,就需要程序员自行处理。
处理思路:提供一个转换器,该转换器负责把CXF不能处理的类型,转换为CXF可以处理的类型
[b] Web Service加转换器后目录图:
[/b]
[b]
[/b]
[b]* 1 . 使用 @XmlJavaTypeAdapter
修饰CXF无法处理的类型
[/b]
使用该Annotation时,通过value属性指定一个转换器,这个转换器是XMLAdapter的子类(XmlJavaTypeAdapter在 Java EE 帮助文档里查看)
[b] * 操作为[b] HelloWorld.java
接口中加标签[/b]
[/b]
import java.util.List; import java.util.Map; import javax.jws.WebService; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import org.fjava.cxf.model.Food; import org.fjava.cxf.model.User; import org.fjava.cxf.ws.util.HelloXmlAdepter; @WebService//J2EE文档里查看WebService public interface HelloWorld { //还有一些像 Map、非JavaBean式的复合类,CXF不可以处理; //CXF不能处理Map<String, Food>类型,我们采用HelloXmlAdepter进行处理 @XmlJavaTypeAdapter(value = HelloXmlAdepter.class) Map<String, Food> getAllFoods(); }
[b]* 2 . 实现自己的转换器
实现转换器时,需要开发一个CXF能处理的类型,操作为新建转换器 HelloXmlAdepter.java 类,新建CXF能处理的 StringFood.java 类[/b]
import java.util.HashMap; import java.util.Map; import javax.xml.bind.annotation.adapters.XmlAdapter; import org.fjava.cxf.model.Food; import org.fjava.cxf.ws.util.StringFood.Entry; //该转换器负责完成StringFood与Map<String, Food>的相互转换 public class HelloXmlAdepter extends XmlAdapter<StringFood, Map<String, Food>> { @Override public Map<String, Food> unmarshal(StringFood v) throws Exception { Map<String, Food> resMap = new HashMap<>(); for (Entry entry : v.getEntries()) { resMap.put(entry.getKey(), entry.getValue()); } return resMap; } @Override public StringFood marshal(Map<String, Food> v) throws Exception { StringFood sf = new StringFood(); for (String key : v.keySet()) { sf.getEntries().add(new Entry(key, v.get(key))); } return sf; } }
import java.util.ArrayList; import java.util.List; import org.fjava.cxf.model.Food; public class StringFood { public static class Entry{ private String key; private Food value; public Entry() { super(); } public Entry(String key, Food value) { super(); this.key = key; this.value = value; } public String getKey() { return key; } public void setKey(String key) { this.key = key; } public Food getValue() { return value; } public void setValue(Food value) { this.value = value; } } private List<Entry> entries = new ArrayList<>(); public List<Entry> getEntries() { return entries; } public void setEntries(List<Entry> entries) { this.entries = entries; } }[b] *
3 . 发布Web Service,写完后运行以下代码,若打印出 "Web Service暴露成功!"
则暴露成功;[/b]
[b]* 4 . 调用CXF提供的wsdl2java工具,根据WSDL文档生成相应的Java代码__CXF-02:使用CXF开发Web
Service客户端 http://blog.csdn.net/cheng_feng_xiao_zhan/article/details/52683987[/b]
* 5 . 编写客户端
客户端编写逻辑输出代码:
public static void main(String[] args) { //这是命令生成的类,该类的实例可当成工厂来使用 HelloWorldWs factory = new HelloWorldWs(); //无参的方法,返回的是远程Web Service服务端的代理,服务端不能关闭。 HelloWorld helloWorld = factory.getHelloWorldWsPort(); StringFood allFoods = helloWorld.getAllFoods(); List<Entry> entries = allFoods.getEntries(); for (Entry entry : entries) { System.out.println(entry.getKey() + " " + entry.getValue().getDescribe()); } }客户端运行结果:
蟹王汉堡 橙色,亮金色,我的宝贝,我的爱! 海绵金币 吃着金币样的甜甜饼,想着海绵宝宝赚的钱被扣了,哈哈哈,爽气! 一个汉堡 是三层的,有夹层哦! 火腿肠 这是章鱼哥从岸上偷运来的,据说很美味!运行成功,解决 '像 Map、非JavaBean式的复合类,CXF不可以处理' 的问题!
希望对你有帮助,祝你有一个好心情,加油!
若有错误、不全、可优化的点,欢迎纠正与补充;转载请注明出处!
相关文章推荐
- 使用CXF处理JavaBean式的复合类型和List集合类型的形参和返回值
- 处理Map、非javabean式的复合类等CXF无法自动转化的类型 (3)
- 10.当形参,返回值类型不是JavaBean式的复合类,Map时,CXF无法处理:客户端执行wsdl2java
- 8.当形参,返回值类型不是JavaBean式的复合类,Map时,CXF无法处理:转换器2
- 6.当形参,返回值类型不是JavaBean式的复合类,Map时,CXF无法处理:服务端发布
- 2.当形参,返回值类型不是JavaBean式的复合类,Map时,CXF无法处理:服务器实现类
- 3.当形参,返回值类型不是JavaBean式的复合类,Map时,CXF无法处理:服务端业务逻辑层接口
- 5.当形参,返回值类型不是JavaBean式的复合类,Map时,CXF无法处理:服务端domain
- 9.当形参,返回值类型不是JavaBean式的复合类,Map时,CXF无法处理:服务端发布成功
- 4.当形参,返回值类型不是JavaBean式的复合类,Map时,CXF无法处理:服务端业务逻辑层实现类
- 1.当形参,返回值类型不是JavaBean式的复合类,Map时,CXF无法处理:服务器接口
- 7.当形参,返回值类型不是JavaBean式的复合类,Map时,CXF无法处理:转换器1
- 11.当形参,返回值类型不是JavaBean式的复合类,Map时,CXF无法处理:客户端主类
- 使用CXF开发WebService程序的总结(五):基于Map数据类型处理的的客户端和服务端代码的编写
- Web service学习cxf版(四)使用cxf处理Map类型----昊哥
- MapStruct处理Java中枚举Enum类型使用与举例
- CXF-03:使用CXF处理 JavaBean 式的复合类型和 List 集合类型的形参和返回值
- CXF学习04---处理MAP等CXF无法自动转换的复合数据类型的形参和返回值
- Map等CXF无法自动转换的复合数据类型的形参和返回值的处理
- WebService-05-WebService(CXF)对Map数据类型的支持