我尝试使用JAXB将XML(String)解析为对象,但是我找不到调用创建的方法的方法,因为我不知道如何用BasicRequest<G>
指定类SomeRequest
G
public class XMLParser {
public <G extends BaseRequest> BasicRequest<G> xmlToRequest(String xml,
Class<BasicRequest<G>> t) {
BasicRequest<G> request = null;
try {
JAXBContext context = JAXBContext.instance(t);
Unmarshaller m = context.createUnmarshaller();
StringReader reader = new StringReader(xml);
JAXBElement<BasicRequest<G>> unmarshal = m.unmarshal(new
StreamSource(reader), t);
request = unmarshal.getValue();
} catch (JAXBException ex) {
//write log
}
return request;
}
}
这是我的课程:
public abstract class BaseRequest {
protected String version;
//getter & setter
}
,
public class SomeRequest extends BaseRequest {
protected Integer id;
//getter & setter
}
和
public class BasicRequest<G extends BaseRequest> {
protected String user;
protected G data;
//getter & setter
}
实际上,所有类都正确地具有JAXB批注。
如果有人可以帮助我,我应该如何调用该方法或更好的定义方法,我将不胜感激。
最佳答案
也许某个精通JAXB的人有一个聪明的以JAXB为中心的解决方案,但是从泛型的角度来看,我不相信有一种方法可以做您想做的事情。封闭的BasicRequest
类的类型参数信息在运行时会被删除(请参见Class object of generic class (java)),因此任何表示Class
的BasicRequest
对象都将简单地反映原始类型。 (相应地,Unmarshaller
将无法知道该参数的意图。)
您可以尝试以下解决方案之一:
如果确定Unmarshaller返回的内容符合BasicRequest,则可以将结果转换为JAXBElement<BasicRequest<G>>
。强制转换将产生未经检查的强制转换警告(同样由于类型擦除),可以根据需要使用封闭方法上的@SuppressWarnings("unchecked")
注释将其取消。
对于可以代替G的每个类,您可以创建一个子类,该子类扩展使用该类参数化的BasicRequest,即:
public class SomeBasicRequest extends BasicRequest<SomeRequest> {
...
}
但是,无法从
SomeBasicRequest
分配Class<BasicRequest<G>>
,因此您必须按如下方式更改方法标题:public <G extends BaseRequest> BasicRequest<G> xmlToRequest(String xml, Class<? extends BasicRequest<G>> t) {
...
}