CXF并非能处理任何类型,向Map<String,Object>这样的复杂类型不能帮助开发人员处理,需要开发人员自行处理.
服务端接口和服务组件:
package com.lin.ws.intf; import java.util.Map; import javax.jws.WebService; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import com.lin.ws.entity.Order; import com.lin.ws.entity.User; import com.lin.ws.util.MapXmlHandler; /** * 服务的接口 * @author lin * */ //暴露的事这个接口 @WebService public interface IUserService { public void addUser(User user); public User getUserById(Integer id); public Integer countOfUser(); public Map<String,Order> getOrdersByUser(User user); }
package com.lin.ws.impl; import java.util.HashMap; import java.util.Map; import java.util.Random; import javax.jws.WebService; import com.lin.ws.entity.Order; import com.lin.ws.entity.User; import com.lin.ws.intf.IUserService; /** * 服务实现类 * @author lin * */ //注解指定该服务的接口,和服务的名称 @WebService(endpointInterface="com.lin.ws.intf.IUserService",serviceName="UserService") public class UserServiceImpl implements IUserService { @Override public void addUser(User user) { System.out.println("Add a user:"+user.toString()); } @Override public User getUserById(Integer id) { System.out.println("Get a user by id:"+id); return null; } @Override public Integer countOfUser() { Integer count = (new Random()).nextInt(); System.out.println("Return the count of users: "+count); return count; } @Override public Map<String, Order> getOrdersByUser(User user) { if(user != null) { Map<String, Order> orders = new HashMap<>(); orders.put("order1", new Order(1, "order1", user.getId())); orders.put("order2", new Order(2, "order2", user.getId())); orders.put("order3", new Order(3, "order3", user.getId())); return orders; } return null; } }
发布服务后会报错:
这实际上CXF无法处理接口方法中的那个Map<String,Order>类型:
public Map<String,Order> getOrdersByUser(User user);
那么,需要将Map<String,Order>转化成CXF能帮助处理的类型,在该类型前面加上@XmlJavaTypeAdapter这个annotation
package com.lin.ws.intf; import java.util.Map; import javax.jws.WebService; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import com.lin.ws.entity.Order; import com.lin.ws.entity.User; import com.lin.ws.util.MapXmlHandler; /** * 服务的接口 * @author lin * */ //暴露的事这个接口 @WebService public interface IUserService { public void addUser(User user); public User getUserById(Integer id); public Integer countOfUser(); //CXF 框架无法处理Map<String,Order>类型,需要工程师自行处理 //需要提供一个转换器,把CXF无法处理的类型转化成CXF可以处理的类型 //value是需要提供的转换器 public @XmlJavaTypeAdapter(MapXmlHandler.class) Map<String,Order> getOrdersByUser(User user); }
@XmlJavaTypeAdapter的api:
默认参数是一个类型转换器,需要开发人员自行实现:
一个可以和map转化的类:
package com.lin.ws.entity; import java.util.ArrayList; import java.util.List; public class StringOrder { private List<Entry> entries = new ArrayList<>(); public List<Entry> getEntries() { return entries; } public void setEntries(List<Entry> entries) { this.entries = entries; } public static class Entry{ private String key; private Order value; public Entry() { super(); } public Entry(String key, Order value) { super(); this.key = key; this.value = value; } public String getKey() { return key; } public void setKey(String key) { this.key = key; } public Order getValue() { return value; } public void setValue(Order value) { this.value = value; } } }
转化器类:
package com.lin.ws.util; import java.util.HashMap; import java.util.Map; import javax.xml.bind.annotation.adapters.XmlAdapter; import com.lin.ws.entity.Order; import com.lin.ws.entity.StringOrder; import com.lin.ws.entity.StringOrder.Entry; /** * StringOrder与,Map<String,Order>相互转换 * @author lin * */ public class MapXmlHandler extends XmlAdapter<StringOrder, Map<String, Order>> { @Override public Map<String, Order> unmarshal(StringOrder v) throws Exception { //将StringOrder转化成Map<String,Order> Map<String, Order> map = new HashMap<String, Order>(); for(StringOrder.Entry entry : v.getEntries()) { map.put(entry.getKey(), entry.getValue()); } return map; } @Override public StringOrder marshal(Map<String, Order> v) throws Exception { //将Map<String,Order>转化成StringOrder StringOrder stringOrder = new StringOrder(); for(String key : v.keySet()) { stringOrder.getEntries().add(new Entry(key, v.get(key))); } return stringOrder; } }
重新发布服务,OK,解决这个问题.