简体   繁体   中英

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. So I tried to generalize the creation of WebServices using Generics:

@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 {

    @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. For instance, when calling the findById method, I get this:

<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:

@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:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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