请帮我解决这个问题,我正在尝试使用Apache FOP编写代码来生成PDF。我开发了XSL-FO,它位于应用程序的资源文件夹中,即src / main / resource。 现在,当我通过Junit进行测试时,它工作正常,但是当我从应用程序中尝试时,我遇到了问题。
java.io.FileNotFoundException: C:\Users\abc\development\Eclipse\eclipse\file:\C:\Users\abc\development\workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\dmu-portal-ui\WEB-INF\lib\XYZservices-1.0.7-SNAPSHOT.jar!\XSLtemplate\templateSummary.xsl (The filename, directory name or volume label syntax is incorrect)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:146)
at java.io.FileInputStream.<init>(FileInputStream.java:101)
at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:90)
at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:188)
at java.net.URL.openStream(URL.java:1037)
代码
public String createPDFFile(ByteArrayOutputStream xmlSource, String templateFile) throws IOException {
File file = File.createTempFile("caseSummary-" + System.currentTimeMillis(), EXTENSION);
URL url = new File(this.getClass().getResource("/" + templateFile).getPath()).toURI().toURL();
//URL url = new File(templateFile).toURI().toURL();
//URL url = new URL(templateFile);
// creation of transform source
//StreamSource transformSource = new StreamSource(getClass().getResourceAsStream("/" + templateFile));
StreamSource transformSource = new StreamSource(url.openStream());
// create an instance of fop factory
FopFactory fopFactory = FopFactory.newInstance();
// a user agent is needed for transformation
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
// to store output
ByteArrayOutputStream pdfoutStream = new ByteArrayOutputStream();
StreamSource source = new StreamSource(new ByteArrayInputStream(xmlSource.toByteArray()));
Transformer xslfoTransformer;
try {
TransformerFactory transfact = TransformerFactory.newInstance();
xslfoTransformer = transfact.newTransformer(transformSource);
// Construct fop with desired output format
Fop fop;
try {
fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, pdfoutStream);
// Resulting SAX events (the generated FO)
// must be piped through to FOP
Result res = new SAXResult(fop.getDefaultHandler());
// Start XSLT transformation and FOP processing
try {
// everything will happen here..
xslfoTransformer.transform(source, res);
// if you want to save PDF file use the following code
OutputStream out = new java.io.FileOutputStream(file);
out = new java.io.BufferedOutputStream(out);
FileOutputStream str = new FileOutputStream(file);
str.write(pdfoutStream.toByteArray());
str.close();
out.close();
} catch (TransformerException e) {
e.printStackTrace();
}
} catch (FOPException e) {
e.printStackTrace();
}
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerFactoryConfigurationError e) {
e.printStackTrace();
}
return file.getPath();
}
我看到的问题 在使用Application进行url.openStream时,路径是重复的,但是从Junit访问它时效果很好。
技术堆栈 JDK:1.7 春天:4.1.5
请帮我解决问题
答案 0 :(得分:1)
首先,正如JB Nizet所说,你不应该使用URL或File来阅读你的模板。你不需要其中任何一个;您只需要从InputStream中读取打包的资源:
try (InputStream xslStream = getClass().getResourceAsStream("/" + templateFile)) {
StreamSource transformSource = new StreamSource(xslStream);
其次,Class.getResource和Class.getResourceAsStream方法(及其ClassLoader等价物)在所有平台上甚至是Windows上都需要a String argument containing forward slashes (/
)。
所以要么改变调用代码,要么传递"XSLTemplate/summary.xsl"
,要么在方法的开头加上这样的东西:
templateFile = templateFile.replace('\\', '/');