首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >具有Quartz作业的XSL样式表路径

具有Quartz作业的XSL样式表路径
EN

Stack Overflow用户
提问于 2021-04-06 01:31:52
回答 1查看 25关注 0票数 0

我有一个动作,可以将XML数据转换为基于XSL的报告,可以在网页上查看。用户调用的单独操作可用于将此报告转换为PDF并将其保存到某个位置。

我希望使用Quartz Scheduler每天运行报告并将其保存为PDF。我已经确认Quartz Scheduler成功运行,但是当它尝试将数据转换为PDF报告时失败。

代码语言:javascript
运行
复制
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尝试按计划调用它时,它会在

代码语言:javascript
运行
复制
    URL resource = ServletActionContext.getServletContext().getResource(path);

线路。有没有一种方法可以让Quartz使用这个转换操作?

EN

回答 1

Stack Overflow用户

发布于 2021-04-08 01:30:27

您的代码抛出NPE,因为它是由Quartz在Struts操作之外执行的,因此ServletActionContext.getServletContext()返回null。您需要找到一种不同的方法来获取ServletContext。最简单的方法是实现一个在调用ServletContext实例的contextInitialized方法时将其保存在私有静态字段中的ServletContextListener。然后,在Quartz作业代码中,您将使用类似以下内容:

MyServletContextListener.getServletContext().getResource(path);

getServletContext是一个需要添加到ServletContextListener中的静态方法,它只返回保存的ServletContext实例。

您需要确保在调用ServletContextListener's contextInitialized方法之后启动Quartz。最简单的方法是从contextInitialized方法启动Quartz。这确保了当Quartz执行任何作业时,ServletContext字段将被初始化,并且MyServletContextListener.getServletContext()不会返回null。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66957143

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档