1、首先在myeclipse中新建一个web项目 webserviceAxis1
2、为项目 webserviceAxis1 引入 axis1 必须的几个jar包
3、创建实体类 TheUser.java 注意需要序列化即实现接口Serializable,这对于在webservice 中传递实体类型是必须的
TheUser.java 的内容如下
package com.demo.model; import java.io.Serializable; public class TheUser implements Serializable { /** * 提供序列化编号,远程调用时要用到 */ private static final long serialVersionUID = -971720598087640397L; private String username; private int age; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { // TODO Auto-generated method stub return "username="+username+" ;age="+age; } }
4、然后是编写webservice要发布的方法所在的类 TheUserWsddAction.java
TheUserWsddAction.java 的代码如下:
package com.demo.action; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import javax.xml.registry.infomodel.User; import com.demo.model.TheUser; /** * 提供webservice方法 * 将操作各种复杂的数据类型 * @author WuJieJecket * */ public class TheUserWsddAction { /** * 提供一个简单类型的方法,便于比对 * @param username * @return */ public String getEasyEg(String username){ return "You write "+username; } /** * webservice中仅返回一个实体类型 * @param username * @param age * @return TheUser */ public TheUser getTheUser(String username,int age){ TheUser theu=new TheUser(); theu.setUsername(username); theu.setAge(age); return theu; } /** * webservice中返回 List<TheUser> 类型 * @param username * @param length * @return List TheUser */ public List<TheUser> getTheUserList(String username,int size){ List<TheUser> theuserlist=new ArrayList<TheUser>(); for(int i=0;i<size;i++){ TheUser tuser=new TheUser(); tuser.setUsername(username+size); tuser.setAge(i); theuserlist.add(tuser); } return theuserlist; } /** * webservice中返回 User[]数据 类型 * @param username * @param length * @return User[] */ public TheUser[] getTheUserGroup(String username,int length){ TheUser[] usergroups =new TheUser[length]; for(int i=0;i<length;i++){ TheUser tuser=new TheUser(); tuser.setUsername(username+length); tuser.setAge(i); usergroups[i]=(TheUser) tuser; } return usergroups; } /** * webservice中返回 Map<String,TheUser>数据 类型 * @return */ public Map<String,TheUser> getTheUserMap(){ Map<String, TheUser> theusermap=new LinkedHashMap<String, TheUser>(); TheUser tusera=new TheUser(); TheUser tuserb=new TheUser(); tusera.setAge(20); tuserb.setAge(20); tusera.setUsername("namea"); tuserb.setUsername("nameb"); theusermap.put("tusera", tusera); theusermap.put("tuserb", tuserb); return theusermap; } }
4、为了把webservice服务发布出去,我们需要修改项目的web.xml 的内容,具体参考
http://blog.csdn.net/bestcxx/article/details/52300248 中的
8、在自己的项目中使用WSDD方式发布webservice服务,如其所言
如果你还记得axis 这个项目,把他的web.xml文件找出来,复制里面的内容,替换掉helloworld的web.xml (头部可以保留编码格式<?xml version="1.0" encoding="UTF-8"?>,内部的AdminServlet可以注释掉,尽管没有啥影响)
这里我把我的项目的文件贴出来,如果你看的看上面的文章,可以直接复制粘贴到你的web.xml文件中
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name>Apache-Axis</display-name> <listener> <listener-class>org.apache.axis.transport.http.AxisHTTPSessionListener</listener-class> </listener> <servlet> <servlet-name>AxisServlet</servlet-name> <display-name>Apache-Axis Servlet</display-name> <servlet-class> org.apache.axis.transport.http.AxisServlet </servlet-class> </servlet> <servlet> <servlet-name>SOAPMonitorService</servlet-name> <display-name>SOAPMonitorService</display-name> <servlet-class> org.apache.axis.monitor.SOAPMonitorService </servlet-class> <init-param> <param-name>SOAPMonitorPort</param-name> <param-value>5001</param-value> </init-param> <load-on-startup>100</load-on-startup> </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>SOAPMonitorService</servlet-name> <url-pattern>/SOAPMonitor</url-pattern> </servlet-mapping> <!-- uncomment this if you want the admin servlet --> <session-config> <!-- Default to 5 minute session timeouts --> <session-timeout>5</session-timeout> </session-config> <!-- currently the W3C havent settled on a media type for WSDL; http://www.w3.org/TR/2003/WD-wsdl12-20030303/#ietf-draft for now we go with the basic 'it's XML' response --> <mime-mapping> <extension>wsdl</extension> <mime-type>text/xml</mime-type> </mime-mapping> <mime-mapping> <extension>xsd</extension> <mime-type>text/xml</mime-type> </mime-mapping> <welcome-file-list id="WelcomeFileList"> <welcome-file>index.jsp</welcome-file> <welcome-file>index.html</welcome-file> <welcome-file>index.jws</welcome-file> </welcome-file-list> </web-app>
5、编写 wsdd 文件,目录是WEB-INF 目录下
其实只需要一个加载服务的wsdd和一个去处服务的wsdd即可,我这里有4个是自己做其他实验用的(名字什么不重要,必须是wsdd结尾)。
我做的一个实验是看在一个wsdd文件中是否可以同时发布两个service方法,所以添加了一个HelloWorldWSDD.java
HelloWorldWSDD.java 的内容如下
package com.demo.action; /** * Axis1 * WSDD发布webservice 测试 * @author WuJieJecket * */ public class HelloWorldWSDD { /** * 方法1 * param String name * return "your name is "+name */ public String getName(String name){ return "Your name is "+name; } /** * 方法2 * param int age * return age+10 */ public int getAge(int age){ return 10+age; } }
然后是wsdd 文件
deployall.wsdd
<?xml version="1.0" encoding="UTF-8"?> <deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <service name="HelloWorldWSDD" provider="java:RPC"> <parameter name="className" value="com.demo.action.HelloWorldWSDD" /> <!-- 指定方法名暴露 --> <parameter name="allowedMethods" value="getName" /> <parameter name="scope" value="request" /> </service> <service name="TheUserWsddAction" provider="java:RPC"> <parameter name="className" value="com.demo.action.TheUserWsddAction" /> <!-- * 代表所有的方法都暴露 --> <parameter name="allowedMethods" value="*" /> <parameter name="scope" value="request" /> <!-- 这里的urn:TheUser和new QName("urn:TheUser", "TheUser")这里是对应的 --> <beanMapping qname="myNSD:TheUser" xmlns:myNSD="urn:TheUser" languageSpecificType="java:com.demo.model.TheUser"/> </service> </deployment>
undeploy.wsdd
<undeployment xmlns="http://xml.apache.org/axis/wsdd/"> <service name="HelloWorldWSDD"/> <service name="TheUserWsddAction"/> </undeployment>
6、启动服务,为了更为真实的实现那种效果,我把目前的项目打了war包,丢到了本地的tomcat服务器
然后在DOS环境中执行wsdd服务加载的命令-注意项目名和端口号
java -Djava.ext.dirs=lib org.apache.axis.client.AdminClient -l http://localhost:8080/webserviceAxis1/servlet/AxisServlet deployall.wsdd
然后访问一下,看发布是否成功
http://localhost:8080/webserviceAxis1/services
如下就成功了
7.生成客户端代码,还是再DOS环境下运行
D:\tomcat7\webapps\webserviceAxis1\WEB-INF>Java -Djava.ext.dirs=lib org.apache.axis.wsdl.WSDL2Java http://localhost:8080/webserviceAxis1/services/TheUserWsddAction?wsdl
8、将客户端代码复制到另外的一个项目中,同时需要引入那8个jar包
你会发现,相较而言,多了一个TheUser.java 当然这个类的位置你是可以自己决定的
因为本次发布的webservice方法含有复杂的返回类型
然后对代码做一点更改,即报错的地方有两种
一个是 TheUser_pkg.TheUser 改为TheUser
另一个是org.apache.xml.xml_soap.MapItem.class;改为 Map.class
9.最后是测试类
TheAxis1Test.java
import java.rmi.RemoteException; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.xml.namespace.QName; import javax.xml.rpc.ParameterMode; import javax.xml.rpc.ServiceException; import localhost.webserviceAxis1.services.TheUserWsddAction.TheUser; import localhost.webserviceAxis1.services.TheUserWsddAction.TheUserWsddActionService; import localhost.webserviceAxis1.services.TheUserWsddAction.TheUserWsddActionServiceLocator; import org.apache.axis.client.Call; import org.apache.axis.client.Service; import org.apache.axis.encoding.XMLType; import org.apache.axis.encoding.ser.BeanDeserializerFactory; import org.apache.axis.encoding.ser.BeanSerializerFactory; import org.junit.Ignore; import org.junit.Test; public class TheAxis1Test { private static final String url="http://localhost:8080/webserviceAxis1/services/TheUserWsddAction"; /** * 最简单的,入参为一个 string , 反参为一个 string * @throws ServiceException * @throws RemoteException */ @Test //@Ignore public void testgetEasyEg() throws ServiceException, RemoteException{ //获取Service 对象-创建服务 Service service=new Service(); //通过 Service 对象获取远程调用对象Call-创建调用句柄 Call call=(Call) service.createCall(); //设置远程调用桩-设置请求地址 call.setTargetEndpointAddress(url); //设置远程操作方法名 /** * 设置调用的方法和方法的命名空间; * 因为这里是手动发布到webroot目录下的,所以命名空间和请求地址一致 * 当然null也可以,因为本身它就没有设置命名空间,一般方法的命名空间是 * 包名倒写组成,如com.hoo.service,ns=http://service.hoo.com * getSayHello 是要调用的方法名 */ call.setOperationName(new QName(null,"getEasyEg")); //设置参数,执行远程方法 String result=(String)call.invoke(new Object[]{"Jecket"}); System.out.println(result); } /** * 入参为 String,int * 反参为 TheUser * @throws ServiceException * @throws RemoteException */ /** * @throws ServiceException * @throws RemoteException */ /** * @throws ServiceException * @throws RemoteException */ @Test //@Ignore public void testgetTheUser() throws ServiceException, RemoteException{ //获取Service 对象-创建服务 Service service=new Service(); //通过 Service 对象获取远程调用对象Call-创建调用句柄 Call call=(Call) service.createCall(); //设置远程调用桩-设置请求地址 call.setTargetEndpointAddress(url); //这里的QName的ns和wsdd文件中的对应 QName qn = new QName("urn:TheUser", "TheUser"); //这里是将对象序列化和反序列化的配置 call.registerTypeMapping(TheUser.class, qn, BeanSerializerFactory.class, BeanDeserializerFactory.class); //设置要调用的方法的名字 call.setOperationName("getTheUser"); /* * 这里客户端和服务器端共用一个User,在实际开发中 * 客户端和服务器端在不同的机器上,所以User对象可能不一样 * 需要我们根据WebService的wsdl分析对象的属性 */ call.addParameter("username", XMLType.XSD_STRING, ParameterMode.IN); call.addParameter("age", XMLType.XSD_INTEGER, ParameterMode.IN); call.setReturnClass(TheUser.class); TheUser tuser = (TheUser) call.invoke(new Object[] {"Jecket",20}); System.out.println("你获取了tuser ,名字是:"+tuser.getUsername()+" 年龄是 "+ tuser.getAge()+" 其他信息 "+tuser.getClass()); } /** * 入参为 String , int * 反参为 List<TheUser> * @throws ServiceException * @throws RemoteException * */ @Test //@Ignore public void testgetTheUserList() throws ServiceException, RemoteException{ //获取Service 对象-创建服务 Service service=new Service(); //通过 Service 对象获取远程调用对象Call-创建调用句柄 Call call=(Call) service.createCall(); //设置远程调用桩-设置请求地址 call.setTargetEndpointAddress(url); //这里的QName的ns和wsdd文件中的对应 QName qn = new QName("urn:TheUser", "TheUser"); //这里是将对象序列化和反序列化的配置 call.registerTypeMapping(TheUser.class, qn, BeanSerializerFactory.class, BeanDeserializerFactory.class); //设置要调用的方法的名字 call.setOperationName("getTheUserList"); /* * 这里客户端和服务器端共用一个User,在实际开发中 * 客户端和服务器端在不同的机器上,所以User对象可能不一样 * 需要我们根据WebService的wsdl分析对象的属性 */ call.addParameter("username", XMLType.XSD_STRING, ParameterMode.IN); call.addParameter("age", XMLType.XSD_INTEGER, ParameterMode.IN); //设置返回值属性 call.setReturnClass(List.class); List<TheUser> tus = (List<TheUser>) call.invoke(new Object[] {"Jecket",20}); for(TheUser tu: tus){ System.out.println("调用 getTheUserList() 你获取了tu ,名字是:"+tu.getUsername()+" 年龄是 "+ tu.getAge()+" 其他信息 "+tu.getClass()); } } /** * 入参为:String , int * 反参为:数组 * @throws ServiceException * @throws RemoteException */ /** * @throws ServiceException * @throws RemoteException */ @Test //@Ignore public void testgetTheUserGroup() throws ServiceException, RemoteException{ //获取Service 对象-创建服务 Service service=new Service(); //通过 Service 对象获取远程调用对象Call-创建调用句柄 Call call=(Call) service.createCall(); //设置远程调用桩-设置请求地址 call.setTargetEndpointAddress(url); //这里的QName的ns和wsdd文件中的对应 QName qn = new QName("urn:TheUser", "TheUser"); //这里是将对象序列化和反序列化的配置 call.registerTypeMapping(TheUser.class, qn, BeanSerializerFactory.class, BeanDeserializerFactory.class); //设置要调用的方法的名字 call.setOperationName("getTheUserGroup"); /* * 这里客户端和服务器端共用一个User,在实际开发中 * 客户端和服务器端在不同的机器上,所以User对象可能不一样 * 需要我们根据WebService的wsdl分析对象的属性 */ call.addParameter("username", XMLType.XSD_STRING, ParameterMode.IN); call.addParameter("age", XMLType.XSD_INTEGER, ParameterMode.IN); //设置返回值属性 call.setReturnClass(TheUser[].class); TheUser[] tu=(TheUser[]) call.invoke(new Object[] {"Jecket",20}); for(TheUser tus:tu){ System.out.println("调用了getTheUserGroup() 方法 ,年龄:"+tus.getAge()+" 姓名:"+tus.getUsername()+" 所属的类:"+tus.getClass()); } //理解数据的类型 /*String[] a={"1","2"}; for(String b:a){ System.out.println(b); }*/ } @Test //@Ignore public void testgetTheUserMap() throws ServiceException, RemoteException{ //获取Service 对象-创建服务 Service service=new Service(); //通过 Service 对象获取远程调用对象Call-创建调用句柄 Call call=(Call) service.createCall(); //设置远程调用桩-设置请求地址 call.setTargetEndpointAddress(url); //这里的QName的ns和wsdd文件中的对应 QName qn = new QName("urn:TheUser", "TheUser"); //这里是将对象序列化和反序列化的配置 call.registerTypeMapping(TheUser.class, qn, BeanSerializerFactory.class, BeanDeserializerFactory.class); //设置要调用的方法的名字 call.setOperationName("getTheUserMap"); //设置返回值属性 call.setReturnClass(Map.class); Map<String, TheUser> maps = (Map<String, TheUser>) call.invoke(new Object[]{}); /* TheUser ta=(TheUser)maps.get("tusera"); TheUser tb=(TheUser)maps.get("tuserb"); System.out.println("调用了getTheUserMap() 方法 ,年龄:"+ta.getAge()+" 姓名:"+ta.getUsername()+" 所属的类:"+ta.getClass()); System.out.println("调用了getTheUserMap() 方法 ,年龄:"+tb.getAge()+" 姓名:"+tb.getUsername()+" 所属的类:"+tb.getClass()); */ //遍历 Map 的方法 Iterator it=maps.keySet().iterator(); while(it.hasNext()){ TheUser ta=maps.get(it.next()); System.out.println("调用了getTheUserMap() 方法 ,年龄:"+ta.getAge()+" 姓名:"+ta.getUsername()+" 所属的类:"+ta.getClass()); } } /** * 使用webservice客户端进行调用 * 返回的对象都是 object * @throws ServiceException * @throws RemoteException */ @Test //@Ignore public void testhere() throws ServiceException, RemoteException{ TheUserWsddActionService tuwas=new TheUserWsddActionServiceLocator(); localhost.webserviceAxis1.services.TheUserWsddAction.TheUserWsddAction tuwa=tuwas.getTheUserWsddAction(); String r=tuwa.getEasyEg("nihao"); System.out.println(r); Object[] a=tuwa.getTheUserList("Jecket", 10); for(Object ob:a){ TheUser ta=(TheUser)ob; System.out.println("年龄:"+ta.getAge()+" 姓名:"+ta.getUsername()+" 所属的类:"+ta.getClass()); } } }
欢迎加入我们的qq小组 371680593