stax2-api-3.1.4.jar
woodstox-core-asl-4.4.1.jarpackage com.dcits.portal.system.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* Title:
* Description: weblogic容器部署CXF服务优先加载指定jar包
* Copyright:Copyright(c)2013
* Company:神州数码(深圳)有限公司
* @date 2017-10-30
* @author zhangpeng
*/
public class CXFWeblogicListener implements ServletContextListener{
public CXFWeblogicListener() {
System.setProperty("org.apache.cxf.stax.allowInsecureParser", "1");
}
@Override
public void contextDestroyed(ServletContextEvent arg0) {
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
}
}
在web.xml下配置监听器
com.dcits.portal.system.listener.CXFWeblogicListener
背景:公司有一个新需求需要实现两个系统之间互相跳转,我采用了通过webservice调用接口的方式进行身份验证,但是我调对方系统提供的接口可以,对方调我提供的接口总是报“Cannot create a secure XMLInputFactory”。
上网搜索,说缺少两个jar包,我用的cxf是2.7版本的,故导入stax2-api-3.1.4.jar和woodstox-core-asl-4.4.1.jar,
但是还是会报“Cannot create a secure XMLInputFactory”异常。
按照网上介绍导入两个jar没有用,也试着修改weblogic.xml配置文件,优先加载指定的cxf jar包还是没用,这时我陷入了死胡同。于是认真的看了控制台报错日志:
WARNING: Interceptor for {http://service.demo.sinosoft.com/}UserServiceService#{http://service.demo.sinosoft.com/}deleteThuser has thrown exception, unwinding now
java.lang.RuntimeException: Cannot create a secure XMLInputFactory
at org.apache.cxf.staxutils.StaxUtils.createXMLInputFactory(StaxUtils.java:312)
at org.apache.cxf.staxutils.StaxUtils.getXMLInputFactory(StaxUtils.java:262)
at org.apache.cxf.staxutils.StaxUtils.createXMLStreamReader(StaxUtils.java:1408)
at org.apache.cxf.interceptor.StaxInInterceptor.handleMessage(StaxInInterceptor.java:112)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:835)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1606)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1502)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1309)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:627)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:565)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:474)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:377)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:330)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:135)
at sun.proxy.$Proxy40.deleteThuser(Unknown Source)
at com.sinosoft.demo.service.UserTest.main(UserTest.java:18)
Cannot create a secure XMLInputFactory
javax.xml.ws.soap.SOAPFaultException: Cannot create a secure XMLInputFactory
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:157)
at sun.proxy.$Proxy40.deleteThuser(Unknown Source)
at com.sinosoft.demo.service.UserTest.main(UserTest.java:18)
Caused by: java.lang.RuntimeException: Cannot create a secure XMLInputFactory
at org.apache.cxf.staxutils.StaxUtils.createXMLInputFactory(StaxUtils.java:312)
at org.apache.cxf.staxutils.StaxUtils.getXMLInputFactory(StaxUtils.java:262)
at org.apache.cxf.staxutils.StaxUtils.createXMLStreamReader(StaxUtils.java:1408)
at org.apache.cxf.interceptor.StaxInInterceptor.handleMessage(StaxInInterceptor.java:112)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
at org.apache.cxf.endpoint.ClientImpl.onMessage(ClientImpl.java:835)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponseInternal(HTTPConduit.java:1606)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.handleResponse(HTTPConduit.java:1502)
at org.apache.cxf.transport.http.HTTPConduit$WrappedOutputStream.close(HTTPConduit.java:1309)
at org.apache.cxf.transport.AbstractConduit.close(AbstractConduit.java:56)
at org.apache.cxf.transport.http.HTTPConduit.close(HTTPConduit.java:627)
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:62)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:565)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:474)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:377)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:330)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:135)
... 2 more
找到红色标记处
源码如下
private static boolean allowInsecureParser;
static
{
innerElementLevelThreshold = 100;
innerElementCountThreshold = 50000;
maxAttributeCount = 500;
maxAttributeSize = 65536;
maxTextLength = 134217728;
maxElementCount = 9223372036854775807L;
maxXMLCharacters = 9223372036854775807L;
int i = getInteger("org.apache.cxf.staxutils.pool-size", 20);
NS_AWARE_INPUT_FACTORY_POOL = new ArrayBlockingQueue(i);
OUTPUT_FACTORY_POOL = new ArrayBlockingQueue(i);
innerElementCountThreshold = getInteger("org.apache.cxf.staxutils.innerElementCountThreshold", innerElementCountThreshold);
innerElementLevelThreshold = getInteger("org.apache.cxf.staxutils.innerElementLevelThreshold", innerElementLevelThreshold);
innerElementCountThreshold = getInteger("org.apache.cxf.stax.maxChildElements", innerElementCountThreshold);
innerElementLevelThreshold = getInteger("org.apache.cxf.stax.maxElementDepth", innerElementLevelThreshold);
maxAttributeCount = getInteger("org.apache.cxf.stax.maxAttributeCount", maxAttributeCount);
maxAttributeSize = getInteger("org.apache.cxf.stax.maxAttributeSize", maxAttributeSize);
maxTextLength = getInteger("org.apache.cxf.stax.maxTextLength", maxTextLength);
maxElementCount = getLong("org.apache.cxf.stax.maxElementCount", maxElementCount);
maxXMLCharacters = getLong("org.apache.cxf.stax.maxXMLCharacters", maxXMLCharacters);
String s = SystemPropertyAction.getPropertyOrNull("org.apache.cxf.stax.allowInsecureParser");
if(!StringUtils.isEmpty(s))
allowInsecureParser = "1".equals(s) || Boolean.parseBoolean(s);
XMLInputFactory xif = null;
try
{
xif = createXMLInputFactory(true);
String xifClassName = xif.getClass().getName();
if(!xifClassName.contains("ctc.wstx") && !xifClassName.contains("xml.xlxp") && !xifClassName.contains("xml.xlxp2") && !xifClassName.contains("bea.core"))
xif = null;
}
catch(Throwable t)
{
xif = null;
}
SAFE_INPUT_FACTORY = xif;
XMLOutputFactory xof = null;
try
{
xof = XMLOutputFactory.newInstance();
String xofClassName = xof.getClass().getName();
if(!xofClassName.contains("ctc.wstx") && !xofClassName.contains("xml.xlxp") && !xofClassName.contains("xml.xlxp2") && !xofClassName.contains("bea.core"))
xof = null;
}
catch(Throwable t) { }
SAFE_OUTPUT_FACTORY = xof;
}
}
最关键的部分:
String s = SystemPropertyAction.getPropertyOrNull("org.apache.cxf.stax.allowInsecureParser");
allowInsecureParser = "1".equals(s) || Boolean.parseBoolean(s);
系统参数中 “org.apache.cxf.stax.allowInsecureParser” 不是 1 或者 true 时都会报该异常,故编写了一个监听器,在启动服务的时候就设置该属性值为“1”。这样问题就完美的解决了。
点击打开链接