当前位置 : 主页 > 网页制作 > Nodejs >

axis1发布返回复杂类型的webservice服务+代码访问+客户端访问

来源:互联网 收集:自由互联 发布时间:2021-06-24
1、首先在myeclipse中新建一个web项目 webserviceAxis1 2、为项目 webserviceAxis1 引入 axis1 必须的几个jar包 3、创建实体类 TheUser.java 注意需要序列化即实现接口Serializable,这对于在webservice 中传递

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文件找出来,复制里面的内容,替换掉helloworldweb.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

网友评论