客户端必须具备以下几点:
- java客户端包含Hessian.jar的包。
- 具有和服务器端结构一样的接口。
- 利用HessianProxyFactory调用远程接口。
- 使用spring方式需要配置HessianProxyFactoryBean
注意:使用resin容器时,resin已经包含了hessian.jar包
JAVA服务器端必须具备以下几点:
- 包含Hessian的jar包。
- 设计一个接口,用来给客户端调用。
- 实现该接口的功能。
- 配置web.xml,配好相应的servlet。
- 对象必须实现Serializable 接口。
- 对于spring方式DispatcherServlet拦截url,HessianServiceExporter提供Bean服务
完整代码下载
引入必要jar包
<dependency>
<groupId>com.caucho</groupId>
<artifactId>hessian</artifactId>
<version>4.0.51</version>
</dependency>
定义接口
package top.wuyongshi.service;
/**
* Created by zml2015 on 2017/10/10 16:28.
*/
import java.util.List;
import top.wuyongshi.model.CommonVO;
import top.wuyongshi.model.PageInfo;
import top.wuyongshi.model.TaskEntity;
/**
* @author zml2015
* @version 1.0
* @time 2017/10/10 16:28
* @description <p> </p>
*/
public interface ITaskRPC {
/**
* 根据作业名称查询作业信息
* @param taskName
* @return
*/
PageInfo<TaskEntity> queryTaskByName(String taskName, CommonVO commonVO);
/**
* 查询作业列表
* @return
*/
PageInfo<TaskEntity> queryAll(CommonVO commonVO);
List<TaskEntity> queryAll();
/**
* 查询 源连接池 列表
* @return
*/
List<String> querySourcePools();
/**
* 查询 目标连接池 列表
* @return
*/
List<String> queryTargetPools();
}
实现接口
package top.wuyongshi.service.impl;
/**
* Created by zml2015 on 2017/10/10 16:27.
*/
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import top.wuyongshi.model.CommonVO;
import top.wuyongshi.model.PageInfo;
import top.wuyongshi.model.TaskEntity;
import top.wuyongshi.service.ITaskRPC;
/**
* @author zml2015 @email mpro@vip.qq.com
* @version 1.0
* @time 2017/10/10 16:27
* @description <p> </p>
*/
public class TaskRPCImpl implements ITaskRPC {
@Override
public PageInfo<TaskEntity> queryTaskByName(String taskName, CommonVO commonVO) {
return null;
}
@Override
public PageInfo<TaskEntity> queryAll(CommonVO commonVO) {
return getTask(commonVO);
}
@Override
public List<TaskEntity> queryAll() {
return getTask();
}
static final String frequentness[] = {"日报","月报","季报","半年报","年报"};
@Override
public List<String> querySourcePools() {
return getSourcePools();
}
@Override
public List<String> queryTargetPools() {
return getTargetPools();
}
/**
* 模拟作业数据
* @return
*/
public static List<TaskEntity> getTask(){
List<TaskEntity> list = new ArrayList<>();
Random random = new Random();
initTask(list, frequentness[random.nextInt(1000) % 5]);
return list;
}
private static void initTask(List<TaskEntity> list, String frequentness) {
for (int i = 0; i < 30; i++) {
TaskEntity task = new TaskEntity();
task.setId(""+i);
task.setTaskName("task"+ getRandomCode(4));
task.setTaskDesc("作业描述"+ UUID.randomUUID().toString());
task.setTaskCreator("zml2015");
task.setTaskFrequentness(frequentness);
task.setLimitTime(10);
list.add(task);
}
}
public static PageInfo<TaskEntity> getTask(CommonVO commonVO){
List<TaskEntity> list = new ArrayList<>();
Random random = new Random();
initTask(list, frequentness[random.nextInt(1000)%5]);
PageInfo pageInfo = new PageInfo();
pageInfo.setList(list);
pageInfo.setPageSize(commonVO.getPageSize());
pageInfo.setTotal(30);
pageInfo.setPages(((int) Math.ceil(30.0 / commonVO.getPageSize())));
pageInfo.setPageNum(commonVO.getPageNo());
return pageInfo;
}
public static List<String> getSourcePools() {
List<String> soucePools = new ArrayList<>();
for (int i = 0; i < 10; i++) {
soucePools.add("源连接池"+(i+1));
}
return soucePools;
}
public List<String> getTargetPools() {
List<String> targetPools = new ArrayList<>();
for (int i = 0; i < 10; i++) {
targetPools.add("目标连接池"+(i+1));
}
return targetPools;
}
public static String getRandomCode(int number) {
String codeNum = "";
int[] code = new int[3];
Random random = new Random();
for (int i = 0; i < number; i++) {
int num = random.nextInt(10) + 48;
int uppercase = random.nextInt(26) + 65;
int lowercase = random.nextInt(26) + 97;
code[0] = num;
code[1] = uppercase;
code[2] = lowercase;
codeNum += (char) code[random.nextInt(3)];
}
System.out.println(codeNum);
return codeNum;
}
}
传输对象
需要实现java.io.Serializable接口进行序列化
package top.wuyongshi.model;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;
@Table(name = "T_TASK")
public class TaskEntity implements Serializable {
/**
* 任务ID,32位uuid
*/
@Id
@Column(name = "ID")
@GeneratedValue(generator = "UUID")
private String id;
/**
* 调度任务id
*/
@Column(name = "SCHEDULE_ID")
private String scheduleId;
/**
* 任务名称
*/
@Column(name = "TASK_NAME")
private String taskName;
/**
* 任务描述
*/
@Column(name = "TASK_DESC")
private String taskDesc;
/**
* 任务频度描述||如月报、季报、年报
*/
@Column(name = "TASK_FREQUENTNESS")
private String taskFrequentness;
/**
* 源连接池
*/
@Column(name = "SOURCE_POOL")
private String sourcePool;
/**
* 目标连接池
*/
@Column(name = "TARGET_POOL")
private String targetPool;
/**
* 任务创建者
*/
@Column(name = "TASK_CREATOR")
private String taskCreator;
/**
* 任务创建时间
*/
// @JSONField(format = "yyyy-MM-dd HH:mm:ss")
@Column(name = "CREATE_TIME")
private Date createTime;
/**
* 任务修改者
*/
@Column(name = "TASK_MENDER")
private String taskMender;
/**
* 任务修改时间
*/
// @JSONField(format = "yyyy-MM-dd HH:mm:ss")
@Column(name = "TASK_UPDATE_TIME")
private Date taskUpdateTime;
/**
* 任务参数 以json集合形式存储;类型为List<Map>
*/
@Column(name = "TASK_PARAMS")
private String taskParams;
/**
* 超时时间,时间单位分钟,默认值 10分钟
*/
@Column(name = "LIMIT_TIME")
private Integer limitTime;
/**
* 记录id,主要用于标记调度任务计划执行过程中,某次运行的记录id
*/
@Transient
private String scheduleRecordId;
private static final long serialVersionUID = 1L;
/**
* 获取 任务ID,32位uuid
*/
public String getId() {
return this.id;
}
/**
* 设置 任务ID,32位uuid
*/
public void setId(String id) {
this.id = id;
}
/**
* 获取 任务名称
*/
public String getTaskName() {
return this.taskName;
}
/**
* 设置 任务名称
*/
public void setTaskName(String taskName) {
this.taskName = taskName;
}
/**
* 获取 任务描述
*/
public String getTaskDesc() {
return this.taskDesc;
}
/**
* 设置 任务描述
*/
public void setTaskDesc(String taskDesc) {
this.taskDesc = taskDesc;
}
/**
* 获取 任务频度描述||如月报、季报、年报
*/
public String getTaskFrequentness() {
return this.taskFrequentness;
}
/**
* 设置 任务频度描述||如月报、季报、年报
*/
public void setTaskFrequentness(String taskFrequentness) {
this.taskFrequentness = taskFrequentness;
}
/**
* 获取 任务创建者
*/
public String getTaskCreator() {
return this.taskCreator;
}
/**
* 设置 任务创建者
*/
public void setTaskCreator(String taskCreator) {
this.taskCreator = taskCreator;
}
/**
* 获取 任务创建时间
*/
public Date getCreateTime() {
return this.createTime;
}
/**
* 设置 任务创建时间
*/
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
/**
* 获取 任务修改者
*/
public String getTaskMender() {
return this.taskMender;
}
/**
* 设置 任务修改者
*/
public void setTaskMender(String taskMender) {
this.taskMender = taskMender;
}
/**
* 获取 任务修改时间
*/
public Date getTaskUpdateTime() {
return this.taskUpdateTime;
}
/**
* 设置 任务修改时间
*/
public void setTaskUpdateTime(Date taskUpdateTime) {
this.taskUpdateTime = taskUpdateTime;
}
/**
* 获取 任务参数 以json集合形式存储;类型为List<Map>
*/
public String getTaskParams() {
return this.taskParams;
}
/**
* 设置 任务参数 以json集合形式存储;类型为List<Map>
*/
public void setTaskParams(String taskParams) {
this.taskParams = taskParams;
}
/**
* 获取 源连接池
*/
public String getSourcePool() {
return this.sourcePool;
}
/**
* 设置 源连接池
*/
public void setSourcePool(String sourcePool) {
this.sourcePool = sourcePool;
}
/**
* 获取 源连接池
*/
public String getTargetPool() {
return this.targetPool;
}
/**
* 设置 源连接池
*/
public void setTargetPool(String targetPool) {
this.targetPool = targetPool;
}
/**
* 获取 调度任务id
*/
public String getScheduleId() {
return this.scheduleId;
}
/**
* 设置 调度任务id
*/
public void setScheduleId(String scheduleId) {
this.scheduleId = scheduleId;
}
/**
* 获取 超时时间 时间单位分钟,默认值 10分钟
*/
public Integer getLimitTime() {
// if (this.limitTime == null){
// limitTime = 10;
// }
return this.limitTime;
}
/**
* 设置 超时时间 时间单位分钟,默认值 10分钟
*/
public void setLimitTime(Integer limitTime) {
this.limitTime = limitTime;
}
@Override
public String toString() {
return "TaskEntity{" +
"id='" + id + '\'' +
", scheduleId='" + scheduleId + '\'' +
", taskName='" + taskName + '\'' +
", taskDesc='" + taskDesc + '\'' +
", taskFrequentness='" + taskFrequentness + '\'' +
", sourcePool='" + sourcePool + '\'' +
", targetPool='" + targetPool + '\'' +
", taskCreator='" + taskCreator + '\'' +
", createTime=" + createTime +
", taskMender='" + taskMender + '\'' +
", taskUpdateTime=" + taskUpdateTime +
", taskParams='" + taskParams + '\'' +
", limitTime=" + limitTime +
"} " + super.toString();
}
/**
* 获取 记录id,主要用于标记调度任务计划执行过程中,某次运行的记录id
*/
public String getScheduleRecordId() {
return this.scheduleRecordId;
}
/**
* 设置 记录id,主要用于标记调度任务计划执行过程中,某次运行的记录id
*/
public void setScheduleRecordId(String scheduleRecordId) {
this.scheduleRecordId = scheduleRecordId;
}
}
web.xml配置hessian
- 注意要将对外暴露的
接口
和接口实现
声明到配置文件中,接口
可以缺省配置,这个网上的好多资料都比较坑,说多了都是泪...- 查看过HessianServlet其实就会注意到,它里面方法
public void init(ServletConfig config)
在实例化的时候默认会取的初始化参数名为home-class、service-class、object-class
(接口实现类)、home-api、api-class、object-api
(接口)
<servlet>
<servlet-name>hessianServlet</servlet-name>
<servlet-class>com.caucho.hessian.server.HessianServlet</servlet-class>
<init-param>
<!--接口实现类,此处param-name可配置的名称有:home-class、service-class、object-class-->
<param-name>home-class</param-name>
<param-value>top.wuyongshi.service.impl.TaskRPCImpl</param-value>
</init-param>
<init-param>
<!--接口,param-name可配置的名称有:home-api、api-class、object-api(可不配置)-->
<param-name>home-api</param-name>
<param-value>top.wuyongshi.service.ITaskRPC</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>hessianServlet</servlet-name>
<url-pattern>/hessian</url-pattern>
</servlet-mapping>
客户端调用
先启动服务器端,浏览器访问配置的路径,出现以下图片内容,说明配置成功
private String url;
@Test
public void testQueryAll() throws MalformedURLException {
HessianProxyFactory factory = new HessianProxyFactory();
url = "http://localhost:8088/HessianDemo2/hessian";
// url = "http://localhost:8087/ScheduleTask/hessian";
ITaskRPC taskRPC = (ITaskRPC) factory.create(ITaskRPC.class, url);
List<TaskEntity> taskEntityPageInfo = taskRPC.queryAll();
System.out.println(JSON.toJSONString(taskEntityPageInfo,true));
List<String> strings = taskRPC.querySourcePools();
for (String string : strings) {
System.out.println(string);
}
}
测试结果
出处
文章首次发布于个人博客:吾勇士的博客http://wuyongshi.top/hessian-basic-use
Q.E.D.