今天帮同事处理问题 ,web service调用SAP里的东东,基于axis 上的web service,web 服务器为weblogic ,以前没整过在axis上的 web service ,都是用我们公司的中间产品 或xfire框架 ,借此也熟悉下流行的axis 。记录下遇到的问题,以便后查。
1、异常报错java.lang.ClassCastException: weblogic.webservice.core.rpc.ServiceFactoryImpl
at javax.xml.rpc.ServiceFactory.newInstance(ServiceFactory.java:63)
at services.FinancingUpdatelogService.sentFinacingUpdatelog(FinancingUpdatelogService.java:52)
一开始很纳闷,类型转换错误,但不知道weblogic.webservice.core.rpc.ServiceFactoryImpl 从何而来,看了下原代码(具体见jaxrpc.jar 下ServiceFactory),查找服务实现类的方式:
首先从系统属性里找,system.getProperty("javax.xml.rpc.ServiceFactory"); 找不到就到Java jre 环境 lib下jaxrpc.properties文件中找,还没有就到META-INF/services/
下找服务实现类 ,还是没有的话axis就默认的实例化org.apache.axis.client.ServiceFactory 类 实现了Service类。
weblogic默认的system.getProperty("javax.xml.rpc.ServiceFactory") 为weblogic.webservice.core.rpc.ServiceFactoryImpl ,所以就报了以上错误。我们只要修改这个系统属性值就可以,在程序中添加 System.setProperty("javax.xml.rpc.ServiceFactory", "org.apache.axis.client.ServiceFactory"); 直接用axis的服务实现类。
当然,你要坚决使用weblogic的默认实现应该也可以吧,保证jar在classpath里,该类在webservices.jar中可以在网上找到,同样实现了Services类,作为服务类的实现。
2、异常java.io.FileNotFoundException: Response: '401: Unauthorized' for url: 'http://xxxx:8077/sap/xi/engine?type=entry&version=3.0&Sender.Service=BC_FINANCING?WSDL'
at weblogic.net.http.HttpURLConnection.getInputStream(HttpURLConnection.java:472)
at weblogic.net.http.SOAPHttpURLConnection.getInputStream(SOAPHttpURLConnection.java:36)
at org.apache.xerces.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
at org.apache.xerces.impl.XMLVersionDetector.determineDocVersion(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at org.apache.axis.utils.XMLUtils.newDocument(XMLUtils.java:369)
at org.apache.axis.utils.XMLUtils.newDocument(XMLUtils.java:420)
at org.apache.axis.wsdl.symbolTable.SymbolTable.populate(SymbolTable.java:482)
at org.apache.axis.wsdl.gen.Parser$WSDLRunnable.run(Parser.java:361)
at java.lang.Thread.run(Thread.java:595)
java.lang.Exception: JAX-RPC ServiceException caught: javax.xml.rpc.ServiceException: Error processing WSDL document:
尝试了很多种方式一直报这个错误,客户端调用程序用的是axis自动生成的Stub,估计原因是这些程序在weblogic部署冲突等原因,虽然设置了用户名 密码但却传不到目标系统,导致报错。没有找到好的办法,直接去掉axis的生成代码,用普通客户端调用如下:
String endpoint = url_lsconf + "?WSDL";
Service service = new Service();
Call call = (Call) service.createCall();
call.setUseSOAPAction(true);
call.setSOAPActionURI("actionName");
call.setTargetEndpointAddress( new java.net.URL(endpoint) );
call.setOperationName(new QName("", "OperationName"));
call.setUsername("username");
call.setPassword("password");
call.invoke(new Object[] { mdmLogParam });
这样调用就没有问题了。
其他类似问题(如安全验证):
http://objectmix.com/weblogic/528585-webservice-dynamic-proxy-clients-using-axis-weblogic.html
http://www.blogjava.net/jinn/archive/2008/07/18/215750.html
http://www.blogjava.net/Leslies2/archive/2012/09/14/387680.html#t3
http://blog.csdn.net/bibitoo712/article/details/1361122
http://stackoverflow.com/questions/4002497/testing-weblogic-webservices-using-soap-ui
http://www.ibm.com/developerworks/cn/webservices/ws-secaxis1/index.html (实现安全的axis,侧重服务端)