Apache CXF实战之八 Map类型绑定

xiaoxiao2021-02-28  23

在CXF中,如果Web Service返回类型是Map的时候,比如方法签名如下

[java]  view plain  copy @WebMethod  @WebResult Map<String, User> getUserMap();   此时如果运行程序会得到类似下面的异常 [java]  view plain  copy ...  Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions  java.util.Map is an interface, and JAXB can't handle interfaces.      this problem is related to the following location:          at java.util.Map          at private java.util.Map com.googlecode.garbagecan.cxfstudy.type.sample2.jaxws_asm.GetUserMapResponse._return          at com.googlecode.garbagecan.cxfstudy.type.sample2.jaxws_asm.GetUserMapResponse  java.util.Map does not have a no-arg default constructor.      this problem is related to the following location:          at java.util.Map          at private java.util.Map com.googlecode.garbagecan.cxfstudy.type.sample2.jaxws_asm.GetUserMapResponse._return          at com.googlecode.garbagecan.cxfstudy.type.sample2.jaxws_asm.GetUserMapResponse      at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:102)      at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:472)      at com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:302)      at com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1136)      at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:154)      at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:121)      at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)      at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)      at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)      at java.lang.reflect.Method.invoke(Unknown Source)      at javax.xml.bind.ContextFinder.newInstance(Unknown Source)      at javax.xml.bind.ContextFinder.newInstance(Unknown Source)      at javax.xml.bind.ContextFinder.find(Unknown Source)      at javax.xml.bind.JAXBContext.newInstance(Unknown Source)      at org.apache.cxf.jaxb.JAXBDataBinding.createContext(JAXBDataBinding.java:560)      at org.apache.cxf.jaxb.JAXBDataBinding.createJAXBContextAndSchemas(JAXBDataBinding.java:500)      at org.apache.cxf.jaxb.JAXBDataBinding.initialize(JAXBDataBinding.java:320)      ... 25 more  ...   如果把方法签名改为如下时

[java]  view plain  copy @WebMethod  @WebResult HashMap<String, User> getUserMap();   运行程序会发现返回的结果总是一个空的HashMap。

对于以上问题,此时需要对Map类型做一下数据绑定或者说转换,看下面详细例子

1. 首先是一个实体类

[java]  view plain  copy package com.googlecode.garbagecan.cxfstudy.type.sample2;    public class User {      private String id;      private String name;      private String password;      public String getId() {          return id;      }      public void setId(String id) {          this.id = id;      }      public String getName() {          return name;      }      public void setName(String name) {          this.name = name;      }      public String getPassword() {          return password;      }      public void setPassword(String password) {          this.password = password;      }  }   2. 对Map类型做转换的类和适配器类

[java]  view plain  copy package com.googlecode.garbagecan.cxfstudy.type.sample2;    import java.util.HashMap;  import java.util.Map;    import javax.xml.bind.annotation.adapters.XmlAdapter;    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;      }  }    package com.googlecode.garbagecan.cxfstudy.type.sample2;    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;          }      }  }   3. 下面是WebService接口类,注意其中的@XmlJavaTypeAdapter注解部分

[java]  view plain  copy package com.googlecode.garbagecan.cxfstudy.type.sample2;    import java.util.List;  import java.util.Map;    import javax.jws.WebMethod;  import javax.jws.WebResult;  import javax.jws.WebService;  import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;    @WebService  public interface UserService {        @WebMethod      @WebResult List<User> getUserList();        @WebMethod      @XmlJavaTypeAdapter(MapAdapter.class)      @WebResult Map<String, User> getUserMap();  }   4. WebService接口实现类

[java]  view plain  copy package com.googlecode.garbagecan.cxfstudy.type.sample2;    import java.util.ArrayList;  import java.util.LinkedHashMap;  import java.util.List;  import java.util.Map;    public class UserServiceImpl implements UserService {        public List<User> getUserList() {          List<User> userList = new ArrayList<User>();          for (int i = 0; i < 10; i++) {              User user = new User();              user.setId("" + i);              user.setName("user_" + i);              user.setPassword("password_" + i);              userList.add(user);          }          return userList;      }        public Map<String, User> getUserMap() {          Map<String, User> userMap = new LinkedHashMap<String, User>();          for (int i = 0; i < 10; i++) {              User user = new User();              user.setId("" + i);              user.setName("user_" + i);              user.setPassword("password_" + i);              userMap.put(user.getId(), user);          }          return userMap;      }  }   5. 最后是一个单元测试类

[java]  view plain  copy package com.googlecode.garbagecan.cxfstudy.type.sample2;    import java.util.List;  import java.util.Map;    import javax.xml.ws.Endpoint;    import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;  import org.junit.After;  import org.junit.Assert;  import org.junit.Before;  import org.junit.BeforeClass;  import org.junit.Test;    public class UserServiceTest {        private static final String address = "http://localhost:9000/ws/type/sample2/userService";            private UserService userService;            @BeforeClass      public static void setUpBeforeClass() throws Exception {          Endpoint.publish(address, new UserServiceImpl());      }            @Before      public void setUp() throws Exception {          JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();          factoryBean.setAddress(address);          factoryBean.setServiceClass(UserService.class);          Object obj = factoryBean.create();          userService = (UserService)obj;      }        @After      public void tearDown() throws Exception {          userService = null;      }        @Test      public void testGetUserList() {          Assert.assertNotNull(userService);          List<User> users = userService.getUserList();          Assert.assertNotNull(users);          Assert.assertEquals(10, users.size());      }        @Test      public void testGetUserMap() {          Assert.assertNotNull(userService);          Map<String, User> users = userService.getUserMap();          Assert.assertNotNull(users);          Assert.assertEquals(10, users.size());      }    }   6. 运行单元测试类验证上面的实现。

版权声明:本文为博主原创文章,未经博主允许不得转载。 本文已收录于以下专栏:Apache CXF实战
转载请注明原文地址: https://www.6miu.com/read-2400002.html

最新回复(0)