我使用以下代码在Windows 7 x64上使用JAXB w/Java 1.7.0_03解组XML文件:
try (InputStream xsdStream = ConfigurationService.class.getClassLoader().getResourceAsStream(CONFIG_XSD_FILE_NAME)) {
configFile = new File(configFilePath);
if (configFile.exists()) {
context = JAXBContext.newInstance(Config.class);
Unmarshaller unMarshaller = context.createUnmarshaller();
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
StreamSource xsdStreamSource = new StreamSource(xsdStream);
Schema schema = sf.newSchema(xsdStreamSource);
unMarshaller.setSchema(schema);
Object xmlObject = Config.class.cast(unMarshaller.unmarshal(configFile));
myConfig = (Config) xmlObject;
} else {
log.severe(configFile.getAbsolutePath() + " does not exist, can not parse configuration info from it.");
}
}
Run Code Online (Sandbox Code Playgroud)
调用此方法的代码随后会删除XML文件.
如果解组成功,则XML文件将正确删除.但是,如果上面的代码抛出和Exception,例如.在SAXException中,XML文件无限期地保持锁定状态,并且调用代码无法使用File.delete()删除它.
在这种情况下,这感觉就像JAXB没有关闭资源/文件.以某种方式做到这一点是我的责任还是这个错误?
回顾Unmarshaller 的javadoc没有说明这一点,谷歌搜索这个问题揭示了2008年这个古老的,未回答的问题.
我使用Jersey客户端(1.11)并将JSONConfiguration.FEATURE_POJO_MAPPING设置为true时遇到了一些问题.我的测试代码如下所示:
MyFooCollectionWrapper<MyFooDTO> resp
= webResource.accept(MediaType.APPLICATION_JSON)
.get(new GenericType<MyFooCollectionWrapper<MyFooDTO>>() {});
Run Code Online (Sandbox Code Playgroud)
在服务器上:
1)我的web.xml将POJO Mapping设置为true.
2)MyFooDTO只是一个POJO,如下所示:
public class MyFooDTO {
private long id;
private String propA;
pubic long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
pubic String getPropA() {
return propA;
}
public void setPropA(String propA) {
this.propA = propA;
}
public MyFooDTO(MyFoo aFoo) {
this.id = aFoo.getId();
this.propA = aFoo.getPropA();
}
public MyFooDTO() {}
}
Run Code Online (Sandbox Code Playgroud)
3)MyFooCollectionWrapper看起来像这样:
public class MyFooCollectionWrapper<T> extends MyFooCollectionWrapperBase {
Collection<T> aCollection;
public MyFooCollectionWrapper() …Run Code Online (Sandbox Code Playgroud) 我有以下JPQL查询 -
SELECT f.md5
FROM File f, Collection leafCollections, Collection instCollections
WHERE (f.status = com.foo.bar.FileStatus.Happy OR f.status = com.foo.bar.FileStatus.Sad)
AND f.collectionId = leafCollections.collectionId
AND leafCollections.instanceCollectionId = instCollections.collectionId
GROUP BY f.md5, instCollections.collectionId
Run Code Online (Sandbox Code Playgroud)
它基本上返回组织在层次结构(树)中的文件的md5,这样如果相同的MD5出现在层次结构的特定分支中的多个叶子中,它将仅显示一次(由于GROUP BY).
这很好用.假设我得到了100行.每行包含一个md5作为字符串.
现在我想获得返回行的COUNT.我以为我可以做到:
SELECT COUNT(f.md5)
FROM File f, Collection leafCollections, Collection instCollections
WHERE (f.status = com.foo.bar.FileStatus.Happy OR f.status = com.foo.bar.FileStatus.Sad)
AND f.collectionId = leafCollections.collectionId
AND leafCollections.instanceCollectionId = instCollections.collectionId
GROUP BY f.md5, instCollections.collectionId
Run Code Online (Sandbox Code Playgroud)
但是,这会返回100行,每行包含一个long,表示md5出现在分支中的次数.我想要的只是获得1行,其中长值为100,即原始查询返回的总行数.我觉得我错过了一些明显的东西.
建议?
我正在尝试验证在Web应用程序中解组的XML文件.xml文件本身位于Web应用程序部署目录之外,相应的XSD打包在WAR,类路径中的WEB-INF/classes/com/moi中
我一直无法弄清楚如何创建Schema对象,以便它相对于类路径获取XSD文件,而不是相对于工作目录硬编码路径.我想相对于类路径选择它,所以我可以在部署应用程序时(以及从单元测试运行时)找到它.下面的示例代码可以查找相对于工作目录的代码.
JAXBContext context;
context = JAXBContext.newInstance(Foo.class);
Unmarshaller unMarshaller = context.createUnmarshaller();
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = sf.newSchema(new File("src/com/moi/foo.xsd"));
unMarshaller.setSchema(schema);
Object xmlObject = Foo.class.cast(unMarshaller.unmarshal(new File("C:\\foo.xml")));
return (Foo) xmlObject;
Run Code Online (Sandbox Code Playgroud)
环境使用JAXB2/JDK 1.6.0_22/JavaEE6.思考?