繁体   English   中英

具有参数化类型的Apache CXF

[英]Apache CXF with Parameterized types

我有一堆看起来都一样的类,仅由一个Id和一些String属性组成。 因此,我尝试使用泛型来概括Web服务的创建:

@WebService
public interface IBasicCRUDService<E extends AbstractEntity, D extends AbstractEntityDTO, ID, DAO extends IGenericDAO<E, ID>>{

    public List<D> findAll(BasicFilters filters);
    public D findById(ID id);

    @WebMethod(exclude = true)
    public void setBaseDao(DAO dao);
}

实现方式:

public abstract class BasicCRUDService<E extends AbstractEntity, D extends AbstractEntityDTO, ID, DAO extends IGenericDAO<E, ID>> extends AbstractService implements IBasicCRUDService<E, D, ID, DAO> {

    private IGenericDAO<E, ID> dao;
    private Class<E> persistentClass;
    private Class<D> dataTransferClass;


    public final DAO getDao() {
        return (DAO) dao;
    }


    public void setDao(DAO dao) {
        this.dao = (IGenericDAO<E, ID>) dao;
    }


    @SuppressWarnings("unchecked")
    public Class<E> getPersistentClass() {
        if (persistentClass == null) {
            this.persistentClass = (Class<E>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        }
        return persistentClass;
    }

    @SuppressWarnings("unchecked")
    public Class<D> getDataTransferClass() {
        if(dataTransferClass == null) {
            this.dataTransferClass = (Class<D>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
        }
        return dataTransferClass;
    }


    @Override
    @Transactional(readOnly=true)
    @WebMethod(operationName="findAll")
    public List<D> findAll(BasicFilters filters) {
        List<E> pList = dao.findAll(filters);
        List<D> dList = new ArrayList<D>();
        for(E e:pList) {
            dList.add(this.map(e, getDataTransferClass()));
        }
        return dList;
    }

    @Override
    @Transactional(readOnly=true)
    @WebMethod(operationName="findAll")
    public D findById(ID id) {
        return this.map(dao.findById(id), getDataTransferClass());
    }

}

这将是一个具体的实现:@Service(“ metodologiaService”)公共类MetodologiaService扩展了BasicCRUDService实现了IMetodologiaService {

    @Override
    @Autowired
    @Qualifier("metodologiaDAO")
    public void setBaseDao(IMetodologiaDAO dao) {
        super.setDao(dao);
    }

}

@WebService
public interface IMetodologiaService extends IBasicCRUDService<Metodologia, MetodologiaDTO, Integer, IMetodologiaDAO>{
    public List<MetodologiaDTO> findAll(BasicFilters filters);
    public MetodologiaDTO findById(Integer id);
}

问题是这样做时似乎CXF无法正确映射WebServices的属性。 例如,当调用findById方法时,我得到以下信息:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <soap:Fault>
         <faultcode>soap:Server</faultcode>
         <faultstring>com.sun.org.apache.xerces.internal.dom.ElementNSImpl cannot be cast to java.lang.Integer</faultstring>
      </soap:Fault>
   </soap:Body>
</soap:Envelope>

但是,如果我直接在我的IMetodologiaService中声明方法,则它可以工作:

@WebService
public interface IMetodologiaService extends IBasicCRUDService<Metodologia, MetodologiaDTO, Integer, IMetodologiaDAO>{
    public List<MetodologiaDTO> findAll(BasicFilters filters);
    public MetodologiaDTO findById(Integer id);
}

因此,在使用参数化类型时,似乎扩展接口不起作用。 有没有办法解决?

在这种情况下,您可能需要使用诸如TypeTools之类的方法来解析类型参数:

public BasicCRUDService() {
  Class<?>[] typeArgs = TypeResolver.resolveRawArguments(IBasicCRUDService.class, getClass());
  persistentClass = typeArgs[0];
  dataTransferClass = typeArgs[1];
  dao = typeArgs[3];
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM