我正在使用 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/