URL.openStream会引发错误

时间:2015-03-31 16:57:34

标签: java spring url

请帮我解决这个问题,我正在尝试使用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

请帮我解决问题

1 个答案:

答案 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('\\', '/');