关键代码:
Maven pom.xml
<axis2.version>1.6.2</axis2.version> <dependency> <groupId>org.apache.axis2</groupId> <artifactId>axis2</artifactId> <version>${axis2.version}</version> <type>pom</type> </dependency> <dependency> <groupId>org.apache.axis2</groupId> <artifactId>axis2-adb</artifactId> <version>${axis2.version}</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.axis2</groupId> <artifactId>axis2-kernel</artifactId> <version>${axis2.version}</version> <type>jar</type> <scope>compile</scope> </dependency> <dependency> <groupId>org.apache.axis2</groupId> <artifactId>axis2-transport-http</artifactId> <version>${axis2.version}</version> </dependency> <dependency> <groupId>org.apache.axis2</groupId> <artifactId>axis2-transport-local</artifactId> <version>${axis2.version}</version> </dependency> <dependency> <groupId>org.apache.axis2</groupId> <artifactId>axis2-spring</artifactId> <version>${axis2.version}</version> </dependency>
spring 配置文件加入(使用注解自动扫描)
<bean id="applicationContext" class="org.apache.axis2.extensions.spring.receivers.ApplicationContextHolder" />
web.xml
<servlet> <servlet-name>AxisServlet</servlet-name> <servlet-class>org.apache.axis2.transport.http.AxisServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:conf/axis2.xml</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping>
java代码
public interface HelloService { public String sayHello(String name); }
import org.springframework.stereotype.Service; @Service("helloService") public class HelloServiceImpl implements HelloService { @Override public String sayHello(String name) { // TODO Auto-generated method stub if((name == null) || (name == "")) { name = "anonymous"; } return "hello, " + name; } }
在WebContent/WEB-INF/services/decode/META-INF/services.xml
此路径下建services.xml文件,decode可以自己取名,与则必须一致
<?xml version="1.0" encoding="UTF-8" ?> <serviceGroup> <service name="helloService" scope="application"> <description>simple spring example</description> <module ref="userCheck"/> <!--此处为Axis2身份验证-采用Module方式验证Soap Header实现 稍等介绍--> <parameter name="ServiceObjectSupplier"> org.apache.axis2.extensions.spring.receivers.SpringAppContextAwareObjectSupplier </parameter> <parameter name="SpringBeanName">helloService</parameter> <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> </service> </serviceGroup>
启动项目浏览器输入http://localhost:8080/工程名/services/helloService?wsdl 可以看到显示出webservice的wsdl信息,说明部署成功。
需要注意的一点就是services.xml文件的存放位置是固定的:WEB-INF/services/任意名字的文件夹/META-INF/services.xml
客户端:
import javax.xml.namespace.QName; import org.apache.axis2.AxisFault; import org.apache.axis2.addressing.EndpointReference; import org.apache.axis2.client.Options; import org.apache.axis2.rpc.client.RPCServiceClient; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMFactory; import org.apache.axiom.om.OMNamespace; public class ServiceClient { public static void main(String args[]) throws AxisFault { sendAxis2(); } /** * 添加Header头部验证信息 * * @return */ public static OMElement createHeaderOMElement() { OMFactory factory = OMAbstractFactory.getOMFactory(); OMNamespace SecurityElementNamespace = factory.createOMNamespace( "http://handler.com", "wsse"); OMElement authenticationOM = factory.createOMElement("Authentication", SecurityElementNamespace); OMElement usernameOM = factory.createOMElement("username", SecurityElementNamespace); OMElement passwordOM = factory.createOMElement("password", SecurityElementNamespace); usernameOM.setText("admin"); passwordOM.setText("123456"); authenticationOM.addChild(usernameOM); authenticationOM.addChild(passwordOM); return authenticationOM; } /** * 发送axis2的接口信息 * @throws AxisFault */ private static void sendAxis2() throws AxisFault { // 使用RPC方式调用WebService RPCServiceClient serviceClient = new RPCServiceClient(); // 向Soap Header中添加校验信息 serviceClient.addHeader(createHeaderOMElement()); Options options = serviceClient.getOptions(); // 指定调用WebService的URL EndpointReference targetEPR = new EndpointReference( "http://localhost:8080/工程名/services/helloService"); options.setTo(targetEPR); // 指定sayHello方法的参数值,如果有多个,继续往后面增加即可 Object[] opAddEntryArgs = new Object[] { "axis2" }; // 指定sayHello方法返回值的数据类型的Class对象 Class[] classes = new Class[] { String.class }; // 在创建QName对象时,QName类的构造方法的第一个参数表示WSDL,文件的命名空间名,也就是<wsdl:definitions>元素的targetNamespace属性值 // 第二个参数是要调用的方法名 QName opAddEntry = new QName("http://service.alfred.com", "sayHello"); // 返回参数类型,这个和axis1有点区别 // invokeBlocking方法有三个参数: // 第一个参数的类型是QName对象,表示要调用的方法名; // 第二个参数表示要调用的WebService方法的参数值,参数类型为Object[]; // 第三个参数表示WebService方法的返回值类型的Class对象,参数类型为Class[]; // 当方法没有参数时,invokeBlocking方法的第二个参数值不能是null,而要使用new Object[]{} // 如果被调用的WebService方法没有返回值,应使用RPCServiceClient类的invokeRobust方法, // 该方法只有两个参数,它们的含义与invokeBlocking方法的前两个参数的含义相同 Object ret = serviceClient.invokeBlocking(opAddEntry, opAddEntryArgs, classes)[0]; System.out.println(ret); } }
运行即可
Axis2身份验证-采用Module方式验证Soap Header实现
基于业务用户的身份认证吧。要实现这个功能,我们需要做三件事:
1、实现基于业务用户的身份认证的扩展模块,
2、在服务端加载扩展模块,
3、在客户端调用时,往soap头中添加身份信息。
一、实现基于业务用户的身份认证的扩展模块
需要新建一个普通的Java工程,新建两个类,一个是module另一个是handler。module类必须实现org.apache.axis2.modules.Module接口,可以不用具体实现任何接口方法,除非您的扩展模块有初始化及销毁的操作。这个是AXIS2架构要求的。
1、新建UserCheckModule类
import org.apache.axis2.AxisFault; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.description.AxisDescription; import org.apache.axis2.description.AxisModule; import org.apache.axis2.modules.Module; import org.apache.neethi.Assertion; import org.apache.neethi.Policy; public class UserCheckModule implements Module { @Override public void init(ConfigurationContext configContext, AxisModule module) throws AxisFault { // TODO Auto-generated method stub } @Override public void engageNotify(AxisDescription axisDescription) throws AxisFault { // TODO Auto-generated method stub } @Override public boolean canSupportAssertion(Assertion assertion) { // TODO Auto-generated method stub return false; } @Override public void applyPolicy(Policy policy, AxisDescription axisDescription) throws AxisFault { // TODO Auto-generated method stub } @Override public void shutdown(ConfigurationContext configurationContext) throws AxisFault { // TODO Auto-generated method stub } }
handler类必须继承org.apache.axis2.handlers.AbstractHandler基类。实现invoke方法,具体的用户身份认证逻辑在此方法中实现。
2、UserCheckHandler类
import java.util.Iterator; 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 UserCheckHandler extends AbstractHandler implements Handler { @Override public InvocationResponse invoke(MessageContext msgContext) throws AxisFault { // 获取Head OMElement fistElement = msgContext.getEnvelope().getHeader().getFirstElement(); if (fistElement!=null&&fistElement.getChildren() != null) { Iterator<?> list = (Iterator<?>) fistElement.getChildren(); String Username = ""; String Password = ""; while (list.hasNext()) { OMElement element = (OMElement) list.next(); if (element.getLocalName().equals("username")) { Username = element.getText(); } if (element.getLocalName().equals("password")) { Password = element.getText(); } } if (!Username.equals("admin") || !Password.equals("password")) { throw new AxisFault(" Authentication Fail! Check username/password "); } return InvocationResponse.CONTINUE; } else { throw new AxisFault(" Authentication Fail! Check username/password "); } } }
3、接下来,我们需要编写module.xml,向axis2表明我们扩展的模块的实现是什么。这个文件需要我们在src目录下新建META-INF文件夹,并将这个文件放到META-INF文件夹下。
在module.xml中,除了<InFlow>外,还有<OutFlow>,<InFaultFlow>和<OutFaultFlow>,分别对应入、出、入错误、出错误四个流程,我们可以根据需要进行配置,像本人现在这个需求,只要在请求进入时进行验证,因此只要配置<InFlow>即可。
<?xml version="1.0" encoding="UTF-8"?> <moudle name="userCheck" class="包.UserCheckModule"> <InFlow> <handler name="InFlowLogHandler" class="包.UserCheckHandler"> <order phase="userCheckPhase"/> </handler> </InFlow> </moudle>
4、在axis2.xml的<InFlow>的最后添加phase,像我的这个为<phase name="UserCheckPhase"/>
axis2.xml引用在上面web.xml介绍
5、修改services.xml文件,在需要身份认证的服务中引用身份认证模块,<module ref="logging"/>。
上面services.xml文件中有
客户端调用如上所示.