Javax Transformer 在多线程服务中为 null
Javax Transformer is null in mutli threaded service
我正在使用 Javax Transformer class 来使用 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 is null!!" 的实例。此外,错误是间歇性的。 class 是一个 bean,用于转换的方法 (transformXmlUsingXsltWithParams) 是一个实例方法,很明显。
没有例外
设置这个
transformer = TransformerFactory.newInstance().newTransformer(xslt);
但变压器仍然是空的。
PS:此方法被多个线程高度调用,因此我在函数中使用 transformer 作为局部变量
谁能提供解决方法。
编辑:
@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 class 来使用 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 is null!!" 的实例。此外,错误是间歇性的。 class 是一个 bean,用于转换的方法 (transformXmlUsingXsltWithParams) 是一个实例方法,很明显。 没有例外 设置这个
transformer = TransformerFactory.newInstance().newTransformer(xslt);
但变压器仍然是空的。
PS:此方法被多个线程高度调用,因此我在函数中使用 transformer 作为局部变量
谁能提供解决方法。
编辑:
@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
只能在单个线程中使用。