Map等CXF无法自动转换的复合数据类型的形参和返回值的处理

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;
    }

}


发布服务后会报错:

Map等CXF无法自动转换的复合数据类型的形参和返回值的处理_第1张图片


这实际上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等CXF无法自动转换的复合数据类型的形参和返回值的处理_第2张图片

默认参数是一个类型转换器,需要开发人员自行实现:


一个可以和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,解决这个问题.

你可能感兴趣的:(java,webservice)