Javax Transformer 在多线程服务中为空

标签 java spring spring-boot xslt javabeans

我正在使用 Javax Transformer 类通过 xslts 转换 xml。当负载较少时,一切正常。但当负载到来时,事情就开始崩溃。基本上,变压器表现出奇怪的行为,并设置为空,从而引发异常。

代码

@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 is null!!”的实例。 。此外,该错误是间歇性的。该类是一个 bean,用于转换的方法(transformXmlUsingXsltWithParams)是一个实例方法,很明显。 没有异常(exception) 设置此

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;
    }
}

最佳答案

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

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

关于Javax Transformer 在多线程服务中为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58705836/

相关文章:

java - 解析UDP数据包后输出垃圾

java - 在 Spring Batch 中,如何一个接一个地运行 2 个选择查询,我必须将第一个查询结果传递给第二个查询

java - Spring MVC Controller 返回请求

java - Spring启动找不到HIBERNATE_SEQUENCE

java - 为什么 @HeadMapping 在 Spring MVC 中不可用?

java - 修改编辑距离算法以不计算所有距离

java - this.getClass().getFields().length;总是返回 0

java - 集成 Spring 2.5 和遗留 Servlet 应用程序

java - Spring 中由于基于 Profile 的注入(inject)而导致循环引用

Java 泛型和枚举,模板参数丢失