带有 Quartz 作业的 XSL 样式表路径
Posted
技术标签:
【中文标题】带有 Quartz 作业的 XSL 样式表路径【英文标题】:XSL Stylesheet Path with Quartz Job 【发布时间】:2021-07-01 13:23:57 【问题描述】:我有一个将 XML 数据转换为基于 XSL 的报告的操作,该报告可以在网页上查看。用户调用的单独操作可用于将此报告转换为 PDF 并将其保存到某个位置。
我希望每天使用 Quartz Scheduler 来运行报告并将报告另存为 PDF。我已经确认 Quartz Scheduler 运行成功,但是当它尝试将数据转换为 PDF 报告时失败了。
public byte[] render(Action action, String location) throws Exception
// Transform the source XML to System.out.
ByteArrayOutputStream out = new ByteArrayOutputStream();
try
// configure fopFactory as desired
FopFactory fopFactory = FopFactory.newInstance();
// configure foUserAgent as desired
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
// Create a transformer for the stylesheet.
Templates templates = null;
Transformer transformer;
if (location != null)
templates = getTemplates(location);
transformer = templates.newTransformer();
else
transformer = TransformerFactory.newInstance().newTransformer();
transformer.setURIResolver(getURIResolver());
Object result = action;
Source xmlSource = getDOMSourceForStack(result);
// Construct fop with desired output format
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out);
Result res = new SAXResult(fop.getDefaultHandler());
transformer.transform(xmlSource, res);
return out.toByteArray();
catch (Exception e)
throw e;
finally
out.close(); // ...and flush...
protected Templates getTemplates(String path) throws TransformerException, IOException
if (path == null)
throw new TransformerException("Stylesheet path is null");
Templates templates = null;
URL resource = ServletActionContext.getServletContext().getResource(path);
if (resource == null)
throw new TransformerException("Stylesheet " + path + " not found in resources.");
TransformerFactory factory = TransformerFactory.newInstance();
templates = factory.newTemplates(new StreamSource(resource.openStream()));
return templates;
protected Source getDOMSourceForStack(Object value)
throws IllegalAccessException, InstantiationException
return new DOMSource(getAdapterFactory().adaptDocument("result", value));
protected AdapterFactory getAdapterFactory()
if (adapterFactory == null)
adapterFactory = new AdapterFactory();
return adapterFactory;
protected void setAdapterFactory(AdapterFactory adapterFactory)
this.adapterFactory = adapterFactory;
protected URIResolver getURIResolver()
return new ServletURIResolver(
ServletActionContext.getServletContext());
action 参数是运行要转换的报告的操作,location 参数是格式化报告的 XSL 样式表的位置。此操作在用户调用时起作用,但是当 Quartz 尝试按计划调用它时,它会在
处抛出 NullPointerException 错误 URL resource = ServletActionContext.getServletContext().getResource(path);
线。有没有办法让 Quartz 使用这个转换操作?
【问题讨论】:
【参考方案1】:您的代码抛出 NPE,因为它是由 Quartz 在 Struts 操作之外执行的,因此 ServletActionContext.getServletContext()
返回 null。您需要找到一种不同的方式来获取ServletContext
。最简单的方法是实现一个ServletContextListener
,在调用contextInitialized
方法时将ServletContext
实例保存在私有静态字段中。然后在您的 Quartz 作业代码中,您将使用如下内容:
MyServletContextListener.getServletContext().getResource(path);
getServletContext
是一个静态方法,您需要将其添加到您的ServletContextListener
中,它只会返回保存的ServletContext
实例。
您需要确保在调用 ServletContextListener's
contextInitialized
方法后启动 Quartz。最简单的方法是从 contextInitialized
方法启动 Quartz。这确保当 Quartz 执行任何作业时,ServletContext
字段将被初始化,MyServletContextListener.getServletContext()
不会返回 null。
【讨论】:
以上是关于带有 Quartz 作业的 XSL 样式表路径的主要内容,如果未能解决你的问题,请参考以下文章