简体   繁体   English

具有参数化类型的Apache CXF

[英]Apache CXF with Parameterized types

I have a bunch of classes that all look the same and consist merely of an Id and a few String attributes. 我有一堆看起来都一样的类,仅由一个Id和一些String属性组成。 So I tried to generalize the creation of WebServices using Generics: 因此,我尝试使用泛型来概括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);
}

Implementation: 实现方式:

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

}

And this would be a concrete implementation: @Service("metodologiaService") public class MetodologiaService extends BasicCRUDService implements IMetodologiaService { 这将是一个具体的实现:@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);
}

The problem is when doing it like this it seems CXF is unable to properly map the attributes of the WebServices. 问题是这样做时似乎CXF无法正确映射WebServices的属性。 For instance, when calling the findById method, I get this: 例如,当调用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>

However, if I declare the methods directly in my IMetodologiaService, it works: 但是,如果我直接在我的IMetodologiaService中声明方法,则它可以工作:

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

So it seems somehow extending interfaces is not working when using Parameterized types. 因此,在使用参数化类型时,似乎扩展接口不起作用。 Is there any way around this? 有没有办法解决?

You'll probably need to use something like TypeTools to resolve the type arguments in this case: 在这种情况下,您可能需要使用诸如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