您的位置:首页 > 其它

修改JAX-WS的序列化行为以及web service中传递Map对象

2013-12-09 17:15 435 查看
使用JAX-WS创建web service时,大部分对象都能通过JAXB序列化成xml,包括基本的java类型、普通的javabean、list,数组等。那么对于JAXB 不知道如何处理的一些类型需要编写一个适配器,该适配器继承javax.xml.bind.annotation.adapters.XmlAdapter<ValueType,BoundType>抽象类。

XmlAdapter类型参数:

BoundType
- JAXB 不知道如何处理的一些类型。编写一个适配器,以便允许通过ValueType 将此类型用作内存表示形式。

ValueType
- JAXB 无需其他操作便知道如何处理的类型

XmlAdapter方法:

XmlAdapter.marshal(...):编组过程中,JAXB 绑定框架调用 XmlAdapter.marshal(..) 将 bound 类型修改为 value 类型,然后将 value 类型编组为 XML 表示形式。XmlAdapter.unmarshal(...):解组过程中,JAXB 绑定框架首先将 XML 表示形式解组为 value 类型,然后调用
XmlAdapter.unmarshal(..) 将 value 类型修改为 bound 类型。

下面以Date对象说明如何自定义序列化的适配器

默认情况下,Java 绑定规则模式将Date 绑定到 XmlGregorianCalendar,现在我们将Date对象直接序列化成string的表示形式:

//实现适配器
public class DateXmlAdapter extends XmlAdapter<String, Date>
{
@Override
public String marshal(Date v) throws Exception
{
SimpleDateFormat fmt=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
return fmt.format(v);
}

@Override
public Date unmarshal(String v) throws Exception
{
SimpleDateFormat fmt=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
return fmt.parse(v);
}
}
@XmlAccessorType(XmlAccessType.FIELD)
public class UserInfo implements Serializable
{
private int id;
private String userName;
//适配器注解
@XmlJavaTypeAdapter(DateXmlAdapter.class)
private Date birthday;

public int getId()

public void setId(int id)

public String getUserName()

public void setUserName(String userName)

public Date getBirthday()

public void setBirthday(Date birthday)

}

这样就完成了转换。这里要注意的是XmlJavaTypeAdapter是注解在元素上而不是方法上,如果形参是Date类型应该是setBirthday(@XmlJavaTypeAdapter(DateXmlAdapter.class) Date myDate)

JAXB 中传递是不支持接口的,所以不能直接传递map对象,CXF默认是使用JAXB 序列化对象的所以也是不支持传递map对象的。

通常会有IllegalAnnotationException java.util.Map is an interface, and JAXB can't handle interfaces这样的异常提示。那么根据上面的原理,我们需要自定义一个适配器来解决这个问题。

首先定义一个web service接口,定义了两个方法一个是返回Map<String, UserInfo>,另一个接收Map<String, UserInfo>参数

@WebService
public interface IQueryUser
{
@XmlJavaTypeAdapter(value=UserMapAdapter.class)
Map<String, UserInfo> getUserMap();

void setUserMap(@XmlJavaTypeAdapter(value=UserMapAdapter.class) @WebParam(name="userMap")Map<String, UserInfo> userMap);
}
这里需要模拟一个Map类:

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

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

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

public static class UserEntry
{
private String key;
private UserInfo users;

public UserEntry() {
}

public UserEntry(String key, UserInfo users) {
this.key = key;
this.users = users;
}

public UserEntry(Map.Entry<String, UserInfo> entry) {
this.key = entry.getKey();
this.users = entry.getValue();
}

public String getKey()
{
return key;
}

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

public UserInfo getUsers()
{
return users;
}

public void setUsers(UserInfo users)
{
this.users = users;
}

}
}
实现适配器

public class UserMapAdapter extends XmlAdapter<UserMap, Map<String, UserInfo>>
{
@Override
public UserMap marshal(Map<String, UserInfo> v) throws Exception
{
UserMap uMap=new UserMap();
for (Map.Entry<String, UserInfo> element : v.entrySet())
{
uMap.addEntry(new UserMap.UserEntry(element));
}
return uMap;
}

@Override
public Map<String, UserInfo> unmarshal(UserMap v) throws Exception
{
List<UserMap.UserEntry> lstEntry=v.getEntries();
Map<String, UserInfo> uMap=new HashMap<String,UserInfo>();
for (UserMap.UserEntry userEntry : lstEntry)
{
uMap.put(userEntry.getKey(), userEntry.getUsers());
}
return uMap;
}

}
使用工具生成客户端代理类后,客户端调用代码如下:

JaxWsProxyFactoryBean soapFactoryBean = new JaxWsProxyFactoryBean();
soapFactoryBean.setAddress("http://localhost:8080/WebServiceDemo/queryuser");
soapFactoryBean.setServiceClass(IQueryUser.class);
IQueryUser queryService = (IQueryUser) soapFactoryBean.create();

UserMap uMapWrapper = queryService.getUserMap();//取得map
List<UserEntry> userList = uMapWrapper.getEntries();
for (UserEntry userEntry : userList)
{
System.out.println(userEntry.key + "  " + userEntry.users.getUserName());
}

queryService.setUserMap(uMapWrapper);//传入map
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: