传递、返回复杂类型的对象
来源:互联网 发布:小米电视3怎么样 知乎 编辑:程序博客网 时间:2024/05/18 22:56
1、首先看看JavaBean模式的参数和返回值的WebService,JavaBean代码如下:
- package com.hoo.entity;
- import java.io.Serializable;
- /**
- * <b>function:</b>User Entity
- * @author hoojo
- * @createDate Dec 16, 2010 10:20:02 PM
- * @file User.java
- * @package com.hoo.entity
- * @project AxisWebService
- * @blog http://blog.csdn.net/IBM_hoojo
- * @email hoojo_@126.com
- * @version 1.0
- */
- public class User implements Serializable {
- private static final long serialVersionUID = 677484458789332877L;
- private int id;
- private String name;
- private String email;
- private String address;
- //Constractor
- //getter、setter
- @Override
- public String toString() {
- return this.id + "#" + this.name + "#" + this.email + "#" + this.address;
- }
- }
没有上面特别就是一个普通的Java对象,里面提供一些属性及getter、setter方法和toString方法(在显示数据的时候有用),值 得注意的是在远程调用的Java对象都需要实现Serializable接口,这样在网络中传递对象的时候就不会出现重复的JavaBean。用过或是了 解EJB、RMI的朋友应该知道这点。序列化后的对象可以用io进行序列化写入到文件中,也可以反序列化解析到对象中的数据。
2、好,回正题。下面编写WebService的服务器端代码。
- package com.hoo.service;
- import java.util.ArrayList;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import com.hoo.entity.User;
- /**
- * <b>function:</b>axis WebService传递复杂类型数据
- * @author hoojo
- * @createDate Dec 16, 2010 10:21:06 PM
- * @file ManagerUser.java
- * @package com.hoo.service
- * @project AxisWebService
- * @blog http://blog.csdn.net/IBM_hoojo
- * @email hoojo_@126.com
- * @version 1.0
- */
- @SuppressWarnings("deprecation")
- public class ManagerUser {
- public User getUserByName(String name) {
- User user = new User();
- user.setId(new Date().getSeconds());
- user.setName(name);
- user.setAddress("china");
- user.setEmail(name + "@hoo.com");
- return user;
- }
- public void setUser(User user) {
- System.out.println(user);
- }
- public List<User> getUsers(int i) {
- List<User> users = new ArrayList<User>();
- for (int j = 0; j <= i; j++) {
- User user = new User();
- user.setId(new Date().getSeconds());
- user.setName("jack#" + j);
- user.setAddress("china");
- user.setEmail("jack" + j + "@hoo.com");
- users.add(user);
- }
- return users;
- }
- public void setUserMap(Map<String, User> maps) {
- System.out.println(maps);
- }
- public User[] getUserArray(int i) {
- User[] users = new User[i];
- for (int j = 0; j < i; j++) {
- User user = new User();
- user.setId(new Date().getSeconds());
- user.setName("jack#" + j);
- user.setAddress("china");
- user.setEmail("jack" + j + "@hoo.com");
- users[j] = user;
- }
- return users;
- }
- public void setUserArray(User[] users) {
- for (User u : users) {
- System.out.println(u);
- }
- }
- public Map<String, User> getUserMap() {
- Map<String, User> users = new HashMap<String, User>();
- User user = new User();
- user.setId(new Date().getSeconds());
- user.setName("jack#");
- user.setAddress("china");
- user.setEmail("jack@hoo.com");
- users.put("A", user);
- user = new User();
- user.setId(new Date().getSeconds());
- user.setName("tom");
- user.setAddress("china");
- user.setEmail("tom@hoo.com");
- users.put("B", user);
- return users;
- }
- public void setUsers(List<User> users) {
- for (User u : users) {
- System.out.println(u);
- }
- }
- }
3、编写wsdd文本发布当前WebService,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="ManagerUser" provider="java:RPC">
- <parameter name="className" value="com.hoo.service.ManagerUser" />
- <parameter name="allowedMethods" value="*" />
- <parameter name="scope" value="request" />
- <!-- 这里的urn:User和new QName("urn:User", "User")这里是对应的 -->
- <beanMapping qname="myNSD:User" xmlns:myNSD="urn:User" languageSpecificType="java:com.hoo.entity.User"/>
- </service>
- </deployment>
和上面的wsdd文件不同的是,这里多了beanMapping的配置。Qname是xml中规范限定名称,由命名空间url、本地名称、前缀组 成,本地名称是必需的且qname是不可变的。后面的myNSD(namespace)是必需的,是通过前面的qname指定的,myNSD后面的 urn:User就和程序中的QName对应的第一个参数,第二个参数对应配置文件中的qname的myNSD冒号后面的值。 languageSpecificType是javaBean的类路径。
4、发布WebService,还是允许命令行:
java -Djava.ext.dirs=lib org.apache.axis.client.AdminClient -lhttp://localhost:8080/AxisWebService/services/AdminService deployComplex.wsdd
发布后,在浏览器中请求:
http://localhost:8080/AxisWebService/servlet/AxisServlet
就可以看到发布的WebService和暴露的方法了。
5、客户端代码的编写,这次客户端和以前有些不一样。因为这里设置了参数和返回值都是复杂类型,而不是简单的类型了。代码如下:
- package com.hoo.client;
- import java.rmi.RemoteException;
- import java.util.Date;
- import java.util.List;
- import java.util.Map;
- import javax.xml.namespace.QName;
- import javax.xml.rpc.ParameterMode;
- import javax.xml.rpc.ServiceException;
- 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 com.hoo.entity.User;
- /**
- * <b>function:</b>axis WebService传递复杂对象,客户端
- * @author hoojo
- * @createDate Dec 16, 2010 10:32:57 PM
- * @file UserServiceClient.java
- * @package com.hoo.client
- * @project AxisWebService
- * @blog http://blog.csdn.net/IBM_hoojo
- * @email hoojo_@126.com
- * @version 1.0
- */
- @SuppressWarnings("unchecked")
- public class UserServiceClient {
- private static final String url = "http://localhost:8080/AxisWebService/services/ManagerUser";
- private static Service service = new Service();
- public static User getUser(String name) throws ServiceException, RemoteException {
- Call call = (Call) service.createCall();
- call.setTargetEndpointAddress(url);
- QName qn = new QName("urn:User", "User");
- //call.registerTypeMapping(User.class, qn, new BeanSerializerFactory(User.class, qn), new BeanDeserializerFactory(User.class, qn));
- call.registerTypeMapping(User.class, qn, BeanSerializerFactory.class, BeanDeserializerFactory.class);
- call.setOperationName("getUserByName");
- /*
- * 这里客户端和服务器端共用一个User,在实际开发中
- * 客户端和服务器端在不同的机器上,所以User对象可能不一样
- * 需要我们根据WebService的wsdl分析对象的属性
- */
- call.addParameter("name", XMLType.XSD_STRING, ParameterMode.IN);
- call.setReturnClass(User.class);
- User user = (User) call.invoke(new Object[] { "jackson" });
- return user;
- }
- public static void setUser(User user) throws ServiceException, RemoteException {
- Call call = (Call) service.createCall();
- call.setTargetEndpointAddress(url);
- //这里的QName的ns和wsdd文件中的对应
- QName qn = new QName("urn:User", "User");
- //这里是将对象序列化和反序列化的配置
- call.registerTypeMapping(User.class, qn, new BeanSerializerFactory(User.class, qn), new BeanDeserializerFactory(User.class, qn));
- call.setOperationName("setUser");
- //设置参数类型
- call.addParameter("user", qn, ParameterMode.IN);
- call.invoke(new Object[] { user });
- }
- public static List<User> getUsers(int i) throws ServiceException, RemoteException {
- Call call = (Call) service.createCall();
- call.setTargetEndpointAddress(url);
- //这里的QName的ns和wsdd文件中的对应
- QName qn = new QName("urn:User", "User");
- //这里是将对象序列化和反序列化的配置
- call.registerTypeMapping(User.class, qn, new BeanSerializerFactory(User.class, qn), new BeanDeserializerFactory(User.class, qn));
- call.setOperationName("getUsers");
- call.addParameter("i", XMLType.XSD_INT, ParameterMode.IN);
- call.setReturnClass(List.class);
- List<User> users = (List<User>) call.invoke(new Object[] { i });
- return users;
- }
- public static void setUsers(List<User> users) throws ServiceException, RemoteException {
- Call call = (Call) service.createCall();
- call.setTargetEndpointAddress(url);
- //这里的QName的ns和wsdd文件中的对应
- QName qn = new QName("urn:User", "User");
- //这里是将对象序列化和反序列化的配置
- call.registerTypeMapping(User.class, qn, new BeanSerializerFactory(User.class, qn), new BeanDeserializerFactory(User.class, qn));
- call.setOperationName("setUsers");
- call.addParameter("users", XMLType.XSD_ANYTYPE, ParameterMode.IN);
- call.invoke(new Object[] { users });
- }
- public static void setUserMap(Map<String, User> maps) throws ServiceException, RemoteException {
- Call call = (Call) service.createCall();
- call.setTargetEndpointAddress(url);
- //这里的QName的ns和wsdd文件中的对应
- QName qn = new QName("urn:User", "User");
- //这里是将对象序列化和反序列化的配置
- call.registerTypeMapping(User.class, qn, new BeanSerializerFactory(User.class, qn), new BeanDeserializerFactory(User.class, qn));
- call.setOperationName("setUserMap");
- call.addParameter("maps", XMLType.XSD_ANYTYPE, ParameterMode.IN);
- call.invoke(new Object[] { maps });
- }
- public static Map<String, User> getUserMap() throws RemoteException, ServiceException {
- Call call = (Call) service.createCall();
- call.setTargetEndpointAddress(url);
- //这里的QName的ns和wsdd文件中的对应
- QName qn = new QName("urn:User", "User");
- //这里是将对象序列化和反序列化的配置
- call.registerTypeMapping(User.class, qn, new BeanSerializerFactory(User.class, qn), new BeanDeserializerFactory(User.class, qn));
- call.setOperationName("getUserMap");
- //call.addParameter("null", XMLType.XSD_ANYTYPE, ParameterMode.IN);
- call.setReturnClass(Map.class);
- Map<String, User> maps = (Map<String, User>) call.invoke(new Object[]{});
- return maps;
- }
- public static User[] getUserArray(int i) throws ServiceException, RemoteException {
- Call call = (Call) service.createCall();
- call.setTargetEndpointAddress(url);
- //这里的QName的ns和wsdd文件中的对应
- QName qn = new QName("urn:User", "User");
- //这里是将对象序列化和反序列化的配置
- call.registerTypeMapping(User.class, qn, new BeanSerializerFactory(User.class, qn), new BeanDeserializerFactory(User.class, qn));
- call.setOperationName("getUserArray");
- call.addParameter("i", XMLType.XSD_INT, ParameterMode.IN);
- call.setReturnClass(User[].class);
- User[] users = (User[]) call.invoke(new Object[] { i });
- return users;
- }
- public static void setUserArray(User[] users) throws RemoteException, ServiceException {
- Call call = (Call) service.createCall();
- call.setTargetEndpointAddress(url);
- //这里的QName的ns和wsdd文件中的对应
- QName qn = new QName("urn:User", "User");
- //这里是将对象序列化和反序列化的配置
- call.registerTypeMapping(User.class, qn, new BeanSerializerFactory(User.class, qn), new BeanDeserializerFactory(User.class, qn));
- call.setOperationName("setUserArray");
- call.addParameter("users", XMLType.XSD_ANYTYPE, ParameterMode.IN);
- call.invoke(new Object[] { users });
- }
- @SuppressWarnings("deprecation")
- public static void main(String[] args) throws RemoteException, ServiceException {
- User user = new User();
- user.setId(new Date().getSeconds());
- user.setName("tom");
- user.setAddress("china");
- user.setEmail("tom@hoo.com");
- System.out.println("============getUser=============");
- System.out.println(getUser("jack"));
- System.out.println("============setUser=============");
- setUser(user);//看服务器端控制台
- System.out.println("============getUsers List=============");
- List<User> users = getUsers(3);
- for (User u : users) {
- System.out.println(u);
- }
- System.out.println("============setUsers List=============");
- setUsers(users);
- System.out.println("============getUserMap=============");
- Map<String, User> map = getUserMap();
- System.out.println(map);
- System.out.println("============setUserMap=============");
- setUserMap(map);
- System.out.println("============getUserArray=============");
- User[] arr = getUserArray(3);
- System.out.println("============setUserArray=============");
- setUserArray(arr);
- }
- }
需要说明的是,这里传递的User和服务器端的User是同一个对象,在实际开发中应该不是同一个对象的。如java调用.net的WebService,传递的对象应该不是同一个。需要我们自己根据wsdl文件中的描述创建JavaBean。注意的是对象一个要序列化。
new QName("urn:User", "User")这里的QName的urn:User和wsdd文件中的对应,参数User也是和wsdd文件中的qname="myNSD:User" 对应的
这里是将对象序列化和反序列化的配置
call.registerTypeMapping(User.class, qn, new BeanSerializerFactory(User.class, qn), new BeanDeserializerFactory(User.class, qn));
User是Mapping的对象,也就是更加wsdl中参数描述创建的Java对象
call.addParameter("i", XMLType.XSD_INT, ParameterMode.IN);设置参数信息,ParameterMode.IN代表传递的参数,XMLType.XSD_INT,代表参数的类型,前面的i是参数名称
call.setReturnClass(User[].class);设置返回值的类型
特别说明:
A、 如果你调用的方法有返回值,一定要设置返回值的类型。call.setReturnClass
B、 如果你调用的方法有参数,一定要设置参数的类型call.addParameter
C、 记得添加wsdl4j.jar,序列化转换的时候需要用到,否则会出现找不到类型异常
运行后,效果如下:
客户端:
============getUser=============
41#jackson#jackson@hoo.com#china
============setUser=============
- No returnType was specified to the Call object! You must call setReturnType() if you have called addParameter().
============getUsers List=============
41#jack#0#jack0@hoo.com#china
41#jack#1#jack1@hoo.com#china
41#jack#2#jack2@hoo.com#china
41#jack#3#jack3@hoo.com#china
============setUsers List=============
- No returnType was specified to the Call object! You must call setReturnType() if you have called addParameter().
============getUserMap=============
{A=41#jack##jack@hoo.com#china, B=41#tom#tom@hoo.com#china}
============setUserMap=============
- No returnType was specified to the Call object! You must call setReturnType() if you have called addParameter().
============getUserArray=============
============setUserArray=============
- No returnType was specified to the Call object! You must call setReturnType() if you have called addParameter().
服务器端:
37#tom#tom@hoo.com#china
37#jack#0#jack0@hoo.com#china
37#jack#1#jack1@hoo.com#china
37#jack#2#jack2@hoo.com#china
37#jack#3#jack3@hoo.com#china
{A=37#jack##jack@hoo.com#china, B=37#tom#tom@hoo.com#china}
37#jack#0#jack0@hoo.com#china
37#jack#1#jack1@hoo.com#china
37#jack#2#jack2@hoo.com#china
Map、Array、List、JavaBean都可以顺利转换,不管是参数还是返回值。怎么样,很简单吧!
传递内部类
如果你传递的JavaBean带有内部类,那么你的内部类需要是静态化的,且一样要序列化。为Account对象添加一个属性Birthday,Birthday是一个内部类,
- package com.hoo.entity;
- import java.io.Serializable;
- /**
- * <b>function:</b>Account Entity
- * @author hoojo
- * @createDate Dec 16, 2010 10:18:20 PM
- * @file Account.java
- * @package com.hoo.entity
- * @project AxisWebService
- * @blog http://blog.csdn.net/IBM_hoojo
- * @email hoojo_@126.com
- * @version 1.0
- */
- public class Account {
- private int id;
- private String name;
- private String email;
- private String address;
- private Birthday birthday;
- public Birthday getBrithday() {
- return birthday;
- }
- public void setBrithday(Birthday birthday) {
- this.birthday = birthday;
- }
- //getter、setter
- @Override
- public String toString() {
- return this.id + "#" + this.name + "#" + this.email + "#" + this.address + "#" + this.birthday.getBirthday();
- }
- /**
- * axis中传的的内部类一定要是静态的,且要序列化
- */
- public static class Birthday implements Serializable {
- private static final long serialVersionUID = 1L;
- private String bitthday;
- // getter、setter
- }
- }
同样我们需要在客户端调用的时候,注册类型序列化和反序列化。
QName qn = new QName("urn:Account", "entity.Account");
call.registerTypeMapping(Account.class , qn, new BeanSerializerFactory(Account.class , qn), new BeanDeserializerFactory(Account.class , qn));
QName qn2 = new QName("urn:Birthday", "Account.Birthday");
call.registerTypeMapping(Birthday.class , qn2, new BeanSerializerFactory(Birthday.class , qn2), new BeanDeserializerFactory(Birthday.class , qn2));
而在wsdd文件中和刚才几乎一样
<beanMapping qname="myNSD:entity.Account" xmlns:myNSD="urn:Account" languageSpecificType="java:com.hoo.entity.Account"/>
<beanMapping qname="myNSD:Account.Birthday" xmlns:myNSD="urn:Birthday" languageSpecificType="java:com.hoo.entity.Account$Birthday"/>com.hoo. com.hoo.entity.Account$Birthday是内部类的表示方式
- 六、传递、返回复杂类型的对象
- Axis2传递、返回复杂类型的对象
- 传递、返回复杂类型的对象
- 六、axis1传递、返回复杂类型的对象
- 传递、返回复杂类型的对象(axis服务端/axis客户端)
- CXF WebService中传递复杂类型对象 .
- CXF WebService中传递复杂类型对象
- CXF WebService中传递复杂类型对象
- CXF WebService 4 传递复杂类型对象
- CXF WebService中传递复杂类型对象
- CXF WebService中传递复杂类型对象
- Activity传递复杂类型的数据
- 四、CXF WebService中传递复杂类型对象
- 四、CXF WebService中传递复杂类型对象
- 三、CXF WebService中传递复杂类型对象
- 四、CXF WebService中传递复杂类型对象
- 传递复杂类型对象(CXF服务端/CXF客户端)
- 四、CXF WebService中传递复杂类型对象
- PTA的6-10 二叉树的遍历
- 如何避免团队协作中的无效沟通
- 最大上升、下降、非上升、非下降子序列 -- n²与nlogn
- PullToRefreshListView的布局文件
- CentOS 6.4安装配置LAMP服务器(Apache+PHP5+MySQL)
- 传递、返回复杂类型的对象
- StringBuilder,ArrayList等常用数据结构扩容大小
- win10下Anaconda3配置环境变量
- 使用 CLI 创建 Azure VM 的自定义映像
- LAMP环境搭建系列之一:Oracle VM VirtualBox 安装 CentOS 6.9
- Android Studio打包时,已经混淆的jar文件报错(Unknown verification type [*] in stack map frame)
- Record of circos usage
- 如何使用可用性集
- 声码器简介