axis1.4发布返回复杂类型的webservice服务+代码访问+客户端访问
2017-11-30 14:52
549 查看
本文转载自:http://blog.csdn.net/bestcxx/article/details/52434817
axis1-myeclipse/eclipse-入门级别-资源、流程、常见问题
TheUser.java 的内容如下
[java] view
plain copy
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;
}
}
TheUserWsddAction.java 的代码如下:
[java] view
plain copy
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;
}
}
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文件中
[html] view
plain copy
<?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>
其实只需要一个加载服务的wsdd和一个去处服务的wsdd即可,我这里有4个是自己做其他实验用的(名字什么不重要,必须是wsdd结尾)。
我做的一个实验是看在一个wsdd文件中是否可以同时发布两个service方法,所以添加了一个HelloWorldWSDD.java
HelloWorldWSDD.java 的内容如下
[java] view
plain copy
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
[html] view
plain copy
<?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
[html] view
plain copy
<undeployment xmlns="http://xml.apache.org/axis/wsdd/">
<service name="HelloWorldWSDD"/>
<service name="TheUserWsddAction"/>
</undeployment>
然后在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
如下就成功了
D:\tomcat7\webapps\webserviceAxis1\WEB-INF>Java -Djava.ext.dirs=lib org.apache.axis.wsdl.WSDL2Java http://localhost:8080/webserviceAxis1/services/TheUserWsddAction?wsdl
你会发现,相较而言,多了一个TheUser.java 当然这个类的位置你是可以自己决定的
因为本次发布的webservice方法含有复杂的返回类型
然后对代码做一点更改,即报错的地方有两种
一个是 TheUser_pkg.TheUser 改为TheUser
另一个是org.apache.xml.xml_soap.MapItem.class;改为 Map.class
TheAxis1Test.java
[java] view
plain copy
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());
}
}
}
本例子为后续补充,不再赘述发布过程,只写出方法和调用方法
被调用的方法代码:
[java] view
plain copy
/**
* 入参为 实体类
* @param theUser
* @return
*/
public TheUser getByTheUser(TheUser theUser){
return theUser;
}
/**
* 入参为list类型
* @param list
* @return
*/
public TheUser getByListTheUser(List<TheUser> list){
return list.get(0);
}
/**
* 入参为map类型
* @param map
* @return
*/
public TheUser getByMapTheUser(Map<String,TheUser> map){
return map.get("theUser0");
}
调用webservice方法的代码
[java] view
plain copy
/**
* 入参为实体类
* @throws ServiceException
* @throws RemoteException
*/
@Test
//@Ignore
public void testGetByTheUser() 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("getByTheUser");
call.addParameter("TheUser", XMLType.XSD_ANYTYPE, ParameterMode.IN);
//设置返回值属性
call.setReturnClass(TheUser.class);
TheUser theUser=new TheUser();
theUser.setAge(10);
theUser.setUsername("jecket");
TheUser theUser2=new TheUser();
theUser2 = (TheUser)call.invoke(new Object[]{theUser});
System.out.println("theUser2.name="+theUser2.getUsername());
}
/**
* 入参为List类型
* @throws ServiceException
* @throws RemoteException
*/
@Test
//@Ignore
public void testGetByListTheUser() 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("getByListTheUser");
call.addParameter("list", XMLType.XSD_ANYTYPE, ParameterMode.IN);
//设置返回值属性
call.setReturnClass(TheUser.class);
TheUser theUser=new TheUser();
theUser.setAge(10);
theUser.setUsername("jecket");
List<TheUser> list=new ArrayList<TheUser>();
list.add(theUser);
TheUser theUser2=new TheUser();
theUser2 = (TheUser)call.invoke(new Object[]{list});
System.out.println("theUser2.name="+theUser2.getUsername());
}
/**
* 入参为Map类型
* @throws ServiceException
* @throws RemoteException
*/
@Test
//@Ignore
public void testGetByMapTheUser() 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("getByMapTheUser");
call.addParameter("map", XMLType.XSD_ANYTYPE, ParameterMode.IN);
//设置返回值属性
call.setReturnClass(TheUser.class);
TheUser theUser=new TheUser();
theUser.setAge(10);
theUser.setUsername("jecket");
Map<String,TheUser> map=new HashMap<String,TheUser>();
map.put("theUser0", theUser);
TheUser theUser2=new TheUser();
theUser2 = (TheUser)call.invoke(new Object[]{map});
System.out.println("theUser2.name="+theUser2.getUsername());
}
特别需要强调的是,在以实体类作为入参或者反参的时候,需要将建立的实体类序列化,即实体类是这样的,implements Serializable
[html] view
plain copy
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;
}
}
如果还没有接触过axis,可以先看入门文章
axis1-myeclipse/eclipse-入门级别-资源、流程、常见问题
0、首先在myeclipse中新建一个web项目 webserviceAxis1
1、为项目 webserviceAxis1 引入 axis1 必须的几个jar包
2、创建实体类 TheUser.java 注意需要序列化即实现接口Serializable,这对于在webservice 中传递实体类型是必须的
TheUser.java 的内容如下
[java] view
plain copy
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;
}
}
3、然后是编写webservice要发布的方法所在的类 TheUserWsddAction.java
TheUserWsddAction.java 的代码如下:
[java] view
plain copy
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文件中
[html] view
plain copy
<?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 的内容如下
[java] view
plain copy
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
[html] view
plain copy
<?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
[html] view
plain copy
<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[java] view
plain copy
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());
}
}
}
10、以上的例子入参都是简单的参数,比如String、int,如果是实体类、list等呢?
本例子为后续补充,不再赘述发布过程,只写出方法和调用方法被调用的方法代码:
[java] view
plain copy
/**
* 入参为 实体类
* @param theUser
* @return
*/
public TheUser getByTheUser(TheUser theUser){
return theUser;
}
/**
* 入参为list类型
* @param list
* @return
*/
public TheUser getByListTheUser(List<TheUser> list){
return list.get(0);
}
/**
* 入参为map类型
* @param map
* @return
*/
public TheUser getByMapTheUser(Map<String,TheUser> map){
return map.get("theUser0");
}
调用webservice方法的代码
[java] view
plain copy
/**
* 入参为实体类
* @throws ServiceException
* @throws RemoteException
*/
@Test
//@Ignore
public void testGetByTheUser() 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("getByTheUser");
call.addParameter("TheUser", XMLType.XSD_ANYTYPE, ParameterMode.IN);
//设置返回值属性
call.setReturnClass(TheUser.class);
TheUser theUser=new TheUser();
theUser.setAge(10);
theUser.setUsername("jecket");
TheUser theUser2=new TheUser();
theUser2 = (TheUser)call.invoke(new Object[]{theUser});
System.out.println("theUser2.name="+theUser2.getUsername());
}
/**
* 入参为List类型
* @throws ServiceException
* @throws RemoteException
*/
@Test
//@Ignore
public void testGetByListTheUser() 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("getByListTheUser");
call.addParameter("list", XMLType.XSD_ANYTYPE, ParameterMode.IN);
//设置返回值属性
call.setReturnClass(TheUser.class);
TheUser theUser=new TheUser();
theUser.setAge(10);
theUser.setUsername("jecket");
List<TheUser> list=new ArrayList<TheUser>();
list.add(theUser);
TheUser theUser2=new TheUser();
theUser2 = (TheUser)call.invoke(new Object[]{list});
System.out.println("theUser2.name="+theUser2.getUsername());
}
/**
* 入参为Map类型
* @throws ServiceException
* @throws RemoteException
*/
@Test
//@Ignore
public void testGetByMapTheUser() 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("getByMapTheUser");
call.addParameter("map", XMLType.XSD_ANYTYPE, ParameterMode.IN);
//设置返回值属性
call.setReturnClass(TheUser.class);
TheUser theUser=new TheUser();
theUser.setAge(10);
theUser.setUsername("jecket");
Map<String,TheUser> map=new HashMap<String,TheUser>();
map.put("theUser0", theUser);
TheUser theUser2=new TheUser();
theUser2 = (TheUser)call.invoke(new Object[]{map});
System.out.println("theUser2.name="+theUser2.getUsername());
}
特别需要强调的是,在以实体类作为入参或者反参的时候,需要将建立的实体类序列化,即实体类是这样的,implements Serializable
[html] view
plain copy
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;
}
}
相关文章推荐
- axis1.4发布返回复杂类型的webservice服务+代码访问+客户端访问
- axis1.4发布返回复杂类型的webservice服务+代码访问+客户端访问
- 服务端使用Axis2-1.6.3发布webservice服务、客户端使用Axis1.4实现调用
- Axis1.4 快速入门 发布WebService服务端、生成WebService客户端
- axis客户端调用jws发布的webservice要5分钟才能返回问题解决
- Axis1.4 快速入门 发布WebService服务端、生成WebService客户端
- webservice知识一、SOAP风格的webservice——通过JDK的API发布一个webservice服务和创建一个webservice客户端用于访问该服务
- jdk annotation发布webservice服务 及生成客户端调用代码
- JDK发布webservice服务,并生成客户端代码实战
- 使用CXF框架,发布webservice服务,并使用客户端远程访问webservice
- 传递、返回复杂类型的对象(axis服务端/axis客户端)
- 普元 EOS Platform 7.2开发环境生成webservice客户端代码调用BPS发布的服务,报错
- Axis1.4调用Cxf发布的webservice服务
- Android通过ksoap2传递复杂数据类型,服务端为CXF发布的webservice,亲手写的代码
- axis1.4 wsdd 方式发布webservice 服务配置文件以及常用的DOS执行语句
- axis1.4 客户端调用webservice接口返回错误:no SOAPAction header!
- 使用CXF开发WebService程序的总结(五):基于Map数据类型处理的的客户端和服务端代码的编写
- WebService:Axis客户端调用需要身份验证的CXF服务
- 使用axis1.4发布WebService简单示例
- Spring boot 集成Axis1.4 ,使用wsdd文件发布webservice