2016-11-15 116 views
0

我在关注migration guide,但我似乎没有把握。Apache FOP:从1.1升级到2.1

在FOP 1.1我有这样的工作代码:

​​

我适应上面的代码坚持FOP 2.1:

public class XsltFactory { 
    private static final String FO_CONFIG_FILE = "/path/to/fop-config.xml"; 

    private static FopFactory fopFactory; 

    private static synchronized void initFopFactory(final ServletContext context) throws Exception { 
     Configuration cfg = new DefaultConfigurationBuilder().build(XsltFactory.class.getResourceAsStream(FO_CONFIG_FILE)); 

     FopFactoryBuilder fopFactoryBuilder = new FopFactoryBuilder(
      new URI(ServletContextURIResolver.SERVLET_CONTEXT_PROTOCOL), 
      new URIResolverAdapter(new ServletContextURIResolver(context)) 
     ); 

     fopFactoryBuilder.setConfiguration(cfg); 
     fopFactory = fopFactoryBuilder.build(); 
    } 
} 

,但我得到了以下错误:

java.lang.Exception: Fail to create PDF 
    at ....web.controller.PrintPdfController.renderPdf(PrintPdfController.java:181) 
    [...] 
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:263) 
Caused by: java.net.URISyntaxException: Expected scheme-specific part at index 16: servlet-context: 
    at java.net.URI$Parser.fail(URI.java:2829) 
    at java.net.URI$Parser.failExpecting(URI.java:2835) 
    at java.net.URI$Parser.parse(URI.java:3038) 
    at java.net.URI.<init>(URI.java:595) 
    [...] 
    ... 42 common frames omitted 

PDF无法加载,因为它在创建时失败。

编辑:

SERVLET_CONTEXT_PROTOCOL上下文后加入+ "///"之后,我现在得到:

Caused by: java.net.MalformedURLException: unknown protocol: servlet-context 
    at java.net.URL.<init>(URL.java:592) 
    at java.net.URL.<init>(URL.java:482) 
    at java.net.URL.<init>(URL.java:431) 
    at java.net.URI.toURL(URI.java:1096) 
    at org.apache.fop.fonts.FontDetectorFactory$DefaultFontDetector.detect(FontDetectorFactory.java:94) 
    ... 59 common frames omitted 
+0

它看起来正确的文件。似乎我们在从1.0变为2.1时有配置更改。它可能是你的URI或解析器。什么是您正在生成的URI的特定示例? –

+0

生成的baseUri是“servlet-context:///”。我正在使用Spring应用程序,无法提供绝对文件系统路径作为baseUri。 –

回答

0

经过调查几天,迁移终于被成功完成。问题来自URI解析器,解决这个问题产生了新的问题,我随后解决了这个问题。

https://xmlgraphics.apache.org/fop/2.1/upgrading.html指南的帮助相对有限。

问题的核心是URI解析器。现在,您必须定义自定义解析,而不是作为例子,在提供: https://xmlgraphics.apache.org/fop/2.0/servlets.html

ResourceResolver resolver = new ResourceResolver() { 
public OutputStream getOutputStream(URI uri) throws IOException { 
    URL url = getServletContext().getResource(uri.toASCIIString()); 
    return url.openConnection().getOutputStream(); 
} 

public Resource getResource(URI uri) throws IOException { 
    return new Resource(getServletContext().getResourceAsStream(uri.toASCIIString())); 
} 
}; 

做的正确的方法是:

ResourceResolver resolver = new ResourceResolver() { 
public OutputStream getOutputStream(URI uri) throws IOException { 
    URL url = context.getResource(uri.getPath()); 
    return url.openConnection().getOutputStream(); 
} 
public Resource getResource(URI uri) throws IOException { 
    return new Resource(context.getResourceAsStream(uri.getPath())); 
} 
}; 

代替uri.toASCIIString(),正确的语法是uri.getPath()。另外,我们不得不删除字体URI(在fop-config.xml中)和图像URI(在任何XSL转换文件或模板中)中的所有“servlet-context:”标记。

最后,我遇到了连字符问题:FOP找不到.hyp文件,因为某些原因,使用baseUri而不是自定义上下文解析器(我不得不深入FOP的源文件中找出) 。所以,我不得不修改我的自定义解析器的getResource方法。我知道这是一个黑客,但它的工作原理,它是足够的我,我已经花了在这个问题上3天):

public OutputStream getOutputStream(URI uri) throws IOException { 
    URL url = context.getResource(uri.getPath()); 
    return url.openConnection().getOutputStream(); 
} 
public Resource getResource(URI uri) throws IOException { 
    InputStream stream = null; 
    /* 
    * For some reason, in FOP 2.x, the hyphenator does not use the 
    * classpath fop-hyph.jar. 
    * 
    * This causes trouble as FOP tries to find "none.hyp" in the 
    * war directory. Setting 
    * <hyphenation-base>/WEB-INF/hyph</hyphenation-base> in the 
    * fop-config.xml file does not solve the issue. The only 
    * solution I could find is to programmatically detect when a 
    * .hyp file is trying to be loaded. When this occurs, I modify 
    * the path so that the resolver gets the right resource. 
    * 
    * This is a hack, but after spending three days on it, I just 
    * went straight to the point and got a workaround. 
    */ 
    if (uri.getPath().endsWith('.hyp')) { 
    String relUri = uri.getPath().substring(uri.getPath().indexOf(baseUri.getPath()) + baseUri.getPath().length()); 
    stream = context.getResourceAsStream(FopManager.HYPH_DIR + relUri); 
    } else { 
    stream = context.getResourceAsStream(uri.getPath()); 
    } 
    Resource res = new Resource(stream); 
    return res; 
} 
}; 

请注意,我也不得不手动创建none.hyp文件,因为它不存在于由OFFO提供的.hyp文件中。我刚刚复制en.hyp并将其更名为none.hyp。这解决了我最后的问题。

我希望这可以节省一些人几天的工作;)