Hprose for Java客户端(一)
同步调用
Hprose客户端在与服务器通讯时,分同步调用和异步调用两种方式。同步调用的概念和用法相对简单一些,所有我们先来介绍同步调用方式。
在同步调用方式下,如果服务器执行出错,或者通讯过程中出现问题(例如连接中断,或者调用的服务器不存在等),则客户端会抛出异常。
直接使用HproseHttpClient上的invoke方法或者采用代理接口方式都可以进行同步调用,但是只有通过invoke方法才能进行引用参数传递。
在下面的例子中,我们以调用前一章中第一节第一小节最后发布的服务为例来进行说明讲解。
通过invoke方法进行同步调用
通过invoke方法调用是最直接、最基本的方式,所以我们先来介绍它。
带名称空间(别名前缀)方法
先来看调用最简单的例子:
package hprose.exam;import hprose.client.HproseHttpClient;import java.io.IOException;import java.util.List;public class ClientExam4 { public static void main(String[] args) throws IOException { HproseHttpClient client = new HproseHttpClient(); client.useService("http://localhost:8084/HproseExamServer/Methods"); List<User> userList = (List<User>)client.invoke("ex2_getUserList"); for (User user : userList) { System.out.printf("name: %s, ", user.getName()); System.out.printf("age: %d, ", user.getAge()); System.out.printf("sex: %s, ", user.getSex()); System.out.printf("birthday: %s, ", user.getBirthday()); System.out.printf("married: %s.", user.isMarried()); System.out.println(); } System.out.println(); User[] users = (User[])client.invoke("ex2_getUserList", User[].class); for (User user : users) { System.out.printf("name: %s, ", user.getName()); System.out.printf("age: %d, ", user.getAge()); System.out.printf("sex: %s, ", user.getSex()); System.out.printf("birthday: %s, ", user.getBirthday()); System.out.printf("married: %s.", user.isMarried()); System.out.println(); } }}运行结果:
引用name: Amy, age: 26, sex: Female, birthday: 1983-12-03, married: true.
name: Bob, age: 20, sex: Male, birthday: 1989-06-12, married: false.
name: Chris, age: 29, sex: Unknown, birthday: 1980-03-08, married: true.
name: Alex, age: 17, sex: InterSex, birthday: 1992-06-14, married: false.
name: Amy, age: 26, sex: Female, birthday: 1983-12-03, married: true.
name: Bob, age: 20, sex: Male, birthday: 1989-06-12, married: false.
name: Chris, age: 29, sex: Unknown, birthday: 1980-03-08, married: true.
name: Alex, age: 17, sex: InterSex, birthday: 1992-06-14, married: false.
上例中,返回结果默认是ArrayList,所以我们用List接收结果没有问题,另外,为了后面for循环时不用手动转型,我们使用的是泛型的List,但是要注意,泛型中所标明的User类必须与服务器端的User类定义完全一致,包括名称空间(包名),否则在运行时会发生类型转换错误。
不过可以通过指定User数组类型作为返回结果,这种情况下,客户端的User类可以与服务器的User类名空间不同(甚至类名不同也可以),只需要其内部序列化的字段和属性相同就可以啦。通常,如果在不需要对返回的结果作增删的时候,指定数组类型作为返回结果更高效和方便一些。