问题:xfire上传文件在tomcat中使用正常,当移植到weblogic9是发现上传文件时报空指针
22:37:44,109 ERROR DefaultFaultHandler:35 - Fault occurred!
java.lang.NullPointerException
at org.codehaus.xfire.attachments.AttachmentUtil.getAttachment(AttachmentUtil.java:33)
at org.codehaus.xfire.aegis.type.mtom.AbstractXOPType.readInclude(AbstractXOPType.java:63)
at org.codehaus.xfire.aegis.type.mtom.AbstractXOPType.readObject(AbstractXOPType.java:50)
at org.codehaus.xfire.aegis.type.basic.BeanType.readObject(BeanType.java:159)
at org.codehaus.xfire.aegis.AegisBindingProvider.readParameter(AegisBindingProvider.java:169)
at org.codehaus.xfire.service.binding.AbstractBinding.read(AbstractBinding.java:206)
at org.codehaus.xfire.service.binding.WrappedBinding.readMessage(WrappedBinding.java:51)
at org.codehaus.xfire.soap.handler.SoapBodyHandler.invoke(SoapBodyHandler.java:42)
at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:131)
at org.codehaus.xfire.transport.DefaultEndpoint.onReceive(DefaultEndpoint.java:64)
at org.codehaus.xfire.transport.AbstractChannel.receive(AbstractChannel.java:38)
at org.codehaus.xfire.transport.http.XFireServletController.invoke(XFireServletController.java:281)
at org.codehaus.xfire.transport.http.XFireServletController.doService(XFireServletController.java:130)
at org.codehaus.xfire.transport.http.XFireServlet.doPost(XFireServlet.java:117)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:763)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:225)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:127)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:283)
at weblogic.servlet.internal.TailFilter.doFilter(TailFilter.java:26)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
at weblogic.servlet.internal.RequestEventsFilter.doFilter(RequestEventsFilter.java:26)
at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java:42)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3212)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:1983)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:1890)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1344)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:181)
通过源代码发现,id是null
public static Attachment getAttachment(String id, AbstractMessage msg)
{
int i = id.indexOf("cid:");
if (i != -1) id = id.substring(4).trim();
Attachments atts = msg.getAttachments();
if (atts == null)
return null;
进一步调试发现,在tomcat中与weblogic中初始化的XMLInputFactory(STAXUtils)对象不同。
tomcat为com.ctc.wstx.stax.WstxInputFactory
weblogic为weblogic.xml.stax.XMLStreamInputFactory
正是因为weblogic.jar下有相同的javax.xml.stream.XMLInputFactory与Jsr173_api.jar冲突造成的空指针。
解决方式(1):
在weblogic启动后执行:
System.setProperty("javax.xml.stream.XMLInputFactory", "com.ctc.wstx.stax.WstxInputFactory");
System.setProperty("javax.xml.stream.XMLOutputFactory", "com.ctc.wstx.stax.WstxOutputFactory");
System.setProperty("javax.xml.stream.XMLEventFactory", "com.ctc.wstx.stax.evt.WstxEventFactory");
次修改会影响weblogic的功能,建议不采用
解决方法(2):
修改xfire源码,改变XMLInputFactory,以下是我的做法,仅供参考:
找到org.codehaus.xfire.transport.http.XFireServletController.java
修改invoke方法:
protected void invoke(HttpServletRequest request,
HttpServletResponse response,
String service)
throws ServletException, IOException, UnsupportedEncodingException
{
response.setStatus(200);
response.setBufferSize(1024 * 8);
MessageContext context = createMessageContext(request, response, service);
Channel channel = createChannel(context);
/***add by haoren ***/
WstxInputFactory wstxInputFactory = new WstxInputFactory();
context.setProperty(XFire.STAX_INPUT_FACTORY, wstxInputFactory);
/***add by haoren ***/
将这个新的类拷贝到工程中,保持目录结构,在加载时应用服务器会加载我们编写的类,而忽略xfire包的类。不必去折腾xfire的jar包