最近项目组经常的做SOAP接口,给第三方调用;由于经常改动以及为了让新员工快速开发,自己用bat命令做了一个快速生成客户端与服务端的工具,共享给大家。
(本文所提到的Axis2_141文件夹与axis2文件夹,请参考附件目录)
Axis2根据业务类来发布自己的wsdl服务详解
1. 新建自己的web工程,该web应用项目通过下面系列配置,达到向外提供Webservice服务的目的:
(1) 在Axis2_141文件夹下新建名为services.xml的文件,内容:
<service name="SampleServer" scope="application" targetNamespace="http://zzvcom.SampleServer/">
<messageReceivers>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>
</messageReceivers>
<schema schemaNamespace="http://zzvcom.SampleServer/xsd
(这一行是确定命名空间的,可以不加它会自动生成(加上就是自己定义命名"/> 空间)
<parameter name="ServiceClass">
zzvcom.ws.SampleServerImpl(这里是你的业务类路径,发布的业务名称)这里根据具体情况要修改
</parameter>
</service>
这里面也可以配置多个服务:要用到<serviceGroup>这里面可以放置多个(<service></<service>)</serviceGroup>
(2) 双击releaseMySelfWsdl.bat文件我将会把services.xml打包为aar文件放在Axis2_141\axis2\WEB-INF\services目录下。
注意:(打开releaseMySelfWsdl.bat文件,找到下面这行:set serviceName="myService"修改为set serviceName="你自己想生成的aar名称")
(3) 访问axis2的内部文件夹:把axis2-web(为了直观的看到服务界面,真正发布时可删除)和WEB-INF下面的conf、lib、modules、services(为了直观的看到多个服务,真正发布时可删除里面不需要的服务)拷贝到工程中对应的目录下(axis2-web拷贝到工程的WebRoot目录下)。
(4) 修改web.xml(和根据wsdl发布服务里的修改web.xml一样)略。
(5) 在tomcat下发布工程,就可以访问你的服务了。
用axis2根据WSDL快速生成soap服务详解
(此次发布包含了axis2自带的ws)
1. 把你的wsdl文件改名为wsdl.wsdl放在Axis2_141目录下。
2. 双击createServer.bat即可生成服务端代码并放在server目录下。
3. 双击package_arr.bat在server文件中生成了*.arr,这就是你要发布的服务。
4. 新建web工程,把axis2文件中的WEB-INF目录下的conf、lib、modules、serices拷贝到工程对应的WEB-INF下面。
最好也把axis2-web拷贝到工程WebRoot目录下面。
5. 把生成的服务端代码拷贝到工程对应的src目录下,再把*.aar文件拷贝到WEB-INF\services下面。
6. 把一下配置拷贝到web.xml中:
<!--axi2相关配置-->
<display-name>Apache-Axis2</display-name>
<servlet>
<servlet-name>AxisServlet</servlet-name>
<servlet-class>
org.apache.axis2.transport.http.AxisServlet
</servlet-class>
<!--<init-param>-->
<!--<param-name>axis2.xml.path</param-name>-->
<!--<param-value>/WEB-INF/conf/axis2.xml</param-value>-->
<!--<param-name>axis2.xml.url</param-name>-->
<!--<param-value>http://localhost/myrepo/axis2.xml</param-value>-->
<!--<param-name>axis2.repository.path</param-name>-->
<!--<param-value>/WEB-INF</param-value>-->
<!--<param-name>axis2.repository.url</param-name>-->
<!--<param-value>http://localhost/myrepo</param-value>-->
<!--</init-param>-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>AxisAdminServlet</servlet-name>
<servlet-class>
org.apache.axis2.webapp.AxisAdminServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/servlet/AxisServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>*.jws</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>AxisAdminServlet</servlet-name>
<url-pattern>/axis2-admin/*</url-pattern>
</servlet-mapping>
7. 目前你就已经发布成功你的ws了。
8. 我们找到*ServiceSkeleton结尾的类,在哪里你可以调用具体的业务实现。
根据wsdl生成客户端代码
1. 双击createClient.bat文件,在client目录下可以找到你生成的客户端代码。
2. 你可以新建java工程把client目录里的代码拷贝到src目录下(一般只有两个类)
3. 新建一个客户端调用类:
public class Client
{
/**
* @param args
* @author MKF14241
*/
public static void main(String[] args)
{
try
{
//就是刚刚生成的stub类(把你发布的服务地址作为够照参数传进去)
ImsServiceStubStub stub =
new ImsServiceStub("http://10.168.8.169:8066/BmeIMSAxis2Server/services/ImsService");
ImsServiceStub.DeletePrivateNumberingPlan request =
new ImsServiceStub.DeletePrivateNumberingPlan();\\new 内部类(一些bean对象或者是请求响应对象)
request.setPrivateNamberingPIanName("mlml");
request.setPrivateNumberingPlanKey(11111l);
ImsServiceStub.DeletePrivateNumberingPlanResponse response =
stub.deletePrivateNumberingPlan(request);
System.err.println("returnCode is key:" + response.getResultcode());
System.err.println("returnDesc is pnpname:" + response.getResultdesc());
}
catch (AxisFault e)
{
e.printStackTrace();
}
catch (RemoteException e)
{
e.printStackTrace();
}
}
}
注意:
1. 执行package_aar.bat时,打开package_aar.bat文件,找到下面这行:
set serviceName="bmeService" 修改为 set serviceName="你自己的发布服务名称"。
2 . 附件里面的axis2及axis2-1.1里面的内容已清空,分别是开源的axis2.war与axis2-1.1.zip,请从apache网站下载解压覆盖,才可以用。
关于Axis2的SOAP头鉴权处理详解
在项目中做SOAP接口时,为了安全考虑一般都会对调用方作鉴权,这时需要添加鉴权头报文,你有两种方案:
A、你可以在SOAP消息头中添加,这样在服务端可以通过定义handler来对消息头进行统一处理鉴权。----这样处理起来比较统一,但是业务逻辑里得不到头消息体里的内容。
B、你可以在Body消息体里添加,这个就像普通参数一样,在每个方法的入参参数里加个头消息体,服务端需要在每个方法里取出头消息参数,进行鉴权。------这样比较灵活,可以在业务逻辑里运用头消息里明的参数。
下面介绍A方案的实现
1. 首先需要改写wsdl如下片段:
Type元素中头类型定义:
<xsd:element name="MessageHeader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="msgName" type="xsd:string"
maxOccurs="1" minOccurs="1"></xsd:element>
<xsd:element name="transactionID" type="xsd:string"
maxOccurs="1" minOccurs="1">
</xsd:element>
<xsd:element name="version" type="xsd:string"
maxOccurs="1" minOccurs="1"></xsd:element>
<xsd:element name="timeStamp" type="xsd:string"
maxOccurs="1" minOccurs="1"></xsd:element>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
头消息:
<wsdl:message name="MessageHeader">
<wsdl:part element="tns:MessageHeader" name="parameters" ></wsdl:part>
</wsdl:message>
在对应的方法的operation中加入消息头:(一般在入参input中加入)
<wsdl:operation name="IndividualSubscribe">
<soap:operation
soapAction="http://www.example.org/FemtoManagerWS/IndividualSubscribe" />
<wsdl:input>
<soap:body use="literal" />
<soap:header use="literal" part="parameters" message="tns:MessageHeader">
</soap:header>
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
2. 这时候你可以用改过的wsdl,按照上面步骤部署服务端,然后开始写头消息处理handler,并在axis2.xml里配置:
(1)handler处理类:
package com.ml.www.ngin.mo.auth;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.engine.Handler;
import org.apache.axis2.handlers.AbstractHandler;
/**
*
*/
public class LoginAuthHandler extends AbstractHandler implements Handler
{
@SuppressWarnings("unchecked")
public InvocationResponse invoke(MessageContext msgContext)
throws AxisFault
{
// 存储头信息
Map<String, String> map = new HashMap<String, String>();
// 获得soapHeader的对象元素
OMElement header = msgContext.getEnvelope().getHeader()
.getFirstElement();
for (Iterator<OMElement> i = header.getChildElements(); i.hasNext();)
{
OMElement el = i.next();
map.put(el.getLocalName().trim(), el.getText().trim());
}
// 效验SoapHeader信息
if (null == map.get("userName") || !map.get("userName").equals("2012"))
{
throw new SoapException("you input username not right", "121212");
}
if (null == map.get("passWord") || !map.get("passWord").equals("2012"))
{
throw new SoapException("you input password not right", "121212");
}
return InvocationResponse.CONTINUE;
}
public void revoke(MessageContext msgContext)
{
//测试时打印报文
System.out.println(msgContext.getEnvelope().toString());
}
(2)异常处理类:
package com.ml.www.ngin.mo.auth;
import org.apache.axis2.AxisFault;
import org.codehaus.xfire.fault.XFireFault;
/**
* SoapException
*/
public class SoapException extends AxisFault
{
public SoapException(String messageText, String faultCode)
{
super(messageText, faultCode);
// TODO Auto-generated constructor stub
}
/**
* filed description
*/
private static final long serialVersionUID = 1L;
}
(3)在axis2.xml里配置LoginAuthHandler:
<!-- ================================================= --> <!-- Phases --> <!-- ================================================= --> <phaseOrder type="InFlow"> <!-- 配置自定义的handler --> <phase name="loginAuth"> <handler name="auth" class="com.ml.www.ngin.mo.auth.LoginAuthHandler"> </handler> </phase> <!-- System predefined phases --> <phase name="Transport"> <handler name="RequestURIBasedDispatcher" class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher"> <order phase="Transport"/> </handler> <handler name="SOAPActionBasedDispatcher" class="org.apache.axis2.dispatchers.SOAPActionBasedDispatcher"> <order phase="Transport"/> </handler> </phase> <phase name="Addressing"> <handler name="AddressingBasedDispatcher" class="org.apache.axis2.dispatchers.AddressingBasedDispatcher"> <order phase="Addressing"/> </handler> </phase> <phase name="Security"/> <phase name="PreDispatch"/> <phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase"> <handler name="RequestURIBasedDispatcher" class="org.apache.axis2.dispatchers.RequestURIBasedDispatcher"/> <handler name="SOAPActionBasedDispatcher" class="org.apache.axis2.dispatchers.SOAPActionBasedDispatcher"/> <handler name="RequestURIOperationDispatcher" class="org.apache.axis2.dispatchers.RequestURIOperationDispatcher"/> <handler name="SOAPMessageBodyBasedDispatcher" class="org.apache.axis2.dispatchers.SOAPMessageBodyBasedDispatcher"/> <handler name="HTTPLocationBasedDispatcher" class="org.apache.axis2.dispatchers.HTTPLocationBasedDispatcher"/> <handler name="GenericProviderDispatcher" class="org.apache.axis2.jaxws.dispatchers.GenericProviderDispatcher"/> <handler name="MustUnderstandValidationDispatcher" class="org.apache.axis2.jaxws.dispatchers.MustUnderstandValidationDispatcher"/> </phase> <phase name="RMPhase"/> <!-- System predefined phases --> <!-- After Postdispatch phase module author or service author can add any phase he want --> <phase name="OperationInPhase"> <handler name="MustUnderstandChecker" class="org.apache.axis2.jaxws.dispatchers.MustUnderstandChecker"> <order phase="OperationInPhase"/> </handler> </phase> <phase name="soapmonitorPhase"/> </phaseOrder>
本文详细介绍如何使用Axis2发布SOAP服务,包括根据业务类发布wsdl服务、根据wsdl生成服务端代码、生成客户端代码的过程,以及SOAP头鉴权处理方法。
6690

被折叠的 条评论
为什么被折叠?



