[英]Managed bean with a parameterized bean class must be @Dependent: class org.apache.cxf.jaxrs.provider.DataSourceProvider
[英]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.