Javax Transformer在多线程服务中为null

问题描述 投票:1回答:1

我正在使用Javax Transformer类使用xslts转换xml。负载较小时,一切正常。但是,当负载来临时,事情开始破裂。基本上,transformer表现出奇怪的行为,并将其设置为null从而引发异常。

代码

@Service
public class XmlProcessorUtil {

    private static final ObjectPool<XPath> pool = new GenericObjectPool<XPath>(new 
      XPathPoolFactory());

    public  String transformXmlUsingXsltWithParams(String xsltPath, Document xml, 
          HashMap<String, String> params) {
        Source xslt = new StreamSource(new File(xsltPath));
        Source xmlSource = new DOMSource(xml);
        return transformXmlUsingXsltWithParams(xslt, xmlSource, params);
    }

    public  String transformXmlUsingXsltWithParams(Source xslt, Source xml, HashMap<String, String> params)
    {
        String result = "";
        StringWriter writer = new StringWriter();

        if(xslt == null)
            return null;

        Transformer transformer = null;

        try
        {
            transformer = TransformerFactory.newInstance().newTransformer(xslt);
        }
        catch (Exception e)
        {

            return null;
        }

        if(params != null && !params.isEmpty())
        {
            for(String key : params.keySet())
            {
                if(transformer != null)
                    transformer.setParameter(key, params.get(key));
            }
        }
        try
        {
            if(transformer==null) {
                LOGGER.info("Transformer is null!!");
            }
            if(xml==null) {
                LOGGER.info("XML  is null!!");
            }
            transformer.transform(xml, new StreamResult(writer));
        }
        catch (TransformerException e)
        {
            e.printStackTrace();
            return null;
        }
        result = writer.toString();
        return result;
    }
}

[在日志中搜索时,有很多实例“ Transformer为空!” 。此外,错误是间歇性的。该类是一个bean,用于转换的方法(transformXmlUsingXsltWithParams)是一个明显的实例方法。毫无例外设置此

transformer = TransformerFactory.newInstance().newTransformer(xslt);

但是转换器仍然为空。

PS:此方法被多个线程高度调用,因此我将转换器用作函数中的局部变量

有人可以提供解决方法。

编辑:

@Bean 
    TransformerFactory transformerFactory() {
        return TransformerFactory.newInstance();
    }

@Service
public class XmlProcessorUtil {

    private static final ObjectPool<XPath> pool = new GenericObjectPool<XPath>(new XPathPoolFactory());

    public static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(XmlProcessorUtil.class);

    @Autowired
    TransformerFactory transformerFactory ;

    public  String transformXmlUsingXsltWithParams(String xsltPath, Document xml, HashMap<String, String> params) {
        Source xslt = new StreamSource(new File(xsltPath));
        Source xmlSource = new DOMSource(xml);
        return transformXmlUsingXsltWithParams(xslt, xmlSource, params);
    }

    public  String transformXmlUsingXsltWithParams(Source xslt, Source xml, HashMap<String, String> params)
    {
        String result = "";
        StringWriter writer = new StringWriter();

        if(xslt == null)
            return null;

        Transformer transformer = null;

        try
        {
            transformer = transformerFactory.newTemplates(xslt).newTransformer();
        }
        catch (Exception e)
        {
            LOGGER.warn("Error in setting transformer",e);
            return null;
        }

        if(params != null && !params.isEmpty())
        {
            for(String key : params.keySet())
            {
                if(transformer != null)
                    transformer.setParameter(key, params.get(key));
            }
        }
        try
        {
            if(transformer==null) {
                LOGGER.info("Transformer is null!!");
            }
            if(xml==null) {
                LOGGER.info("XML  is null!!");
            }
            transformer.transform(xml, new StreamResult(writer));
        }
        catch (TransformerException e)
        {
            e.printStackTrace();
            return null;
        }
        result = writer.toString();
        return result;
    }
}

java spring spring-boot xslt javabeans
1个回答
0
投票

尚不完全清楚这里发生了什么,但是您在多线程环境中使用JAXP看起来是错误的。

您应该尝试为整个应用程序创建一个TransformerFactory实例。您应该为每个样式表创建一个Templates对象,如果同一样式表将用于多个转换,则将其缓存。并且您应该为每个转换创建一个Transformer(使用Templates.newTransformer()),请注意Transformer只能在单个线程中使用。

© www.soinside.com 2019 - 2024. All rights reserved.