定时任务管理(二)velocity和groovy构成灵活的展现层

定时任务管理(二)velocity和groovy构成灵活的展现层

最近项目采用了groovy来做为我们的控制层,通过配置,能将groovy文件从项目的war包中分离出来,放置在一个特定的目录,这样,我们根据groovy解释语言的特性,可以在不修改任何war包服务的情况下,对groovy的controller进行修改。如果还是使用jsp文件,那么灵活性就大大折扣了,所以这里我们修改JSP,用velocity来替换之。
velocity在2004年的时候,我就开始在淘宝项目中使用,一直使用了2年左右的时间,一直觉得很好用。哈哈。这次终于有机会重新应用一下了,先给eclipse安装好插件
velocity首页
http://velocity.apache.org/
velocity的eclipse插件地址
http://propsorter.sourceforge.net/veloeclipse/
我在eclipse3.5下安装,最先报出提示信息如下:
There are no categorized items 安装不上
网上搜索了下,去掉了下面的勾 Group items by category就好了:)

groovy的应用
这个以前就专门写过BLOG,这里基本上也没有怎么改动
http://hi.baidu.com/luohuazju/blog/item/37db387719ceae11b151b959.html
http://hi.baidu.com/luohuazju/blog/item/0d02982367884b4493580759.html
核心配置文件core-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:groovy="http://www.sillycat.com/schema/groovy"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.sillycat.com/schema/groovy http://www.sillycat.com/schema/groovy/groovy.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:component-scan base-package="cn.sccl" />
<!-- 属性文件读入 -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:config.properties</value>
</list>
</property>
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<bean id="handlerAdapter" class="com.sillycat.easygroovyplugin.servlet.proxy.ProxyAwareAnnotationMethodHandlerAdapter" />
<lang:defaults refresh-check-delay="5" />
<!-- file://D:/work/easygroovy/groovy/*.groovy -->
<groovy:scan source-pattern="/groovy/*.groovy" />
</beans>
比较关键的是这个com.sillycat.easygroovyplugin.servlet.proxy.ProxyAwareAnnotationMethodHandlerAdapter,我做的扩展,这个是用到的easygroovyplugin项目中的东东,同时会默认装载easygroovy.properties文件如下:
###############################################
# groovy configuration
###############################################
groovy.file.path=file://D:/project/CPMIS-Core/Code/Trunk/tasksupervisor
这样就做到了groovy文件可以指向任意的路径,而不需要打在war包中
其中一个JobController.groovy文件如下:
package cn.sccl.tasksupervisor.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.bind.annotation.RequestMethod;
import cn.sccl.tasksupervisor.commons.utils.StringUtil;
import java.net.URLDecoder;
import cn.sccl.tasksupervisor.service.SchedulerService;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Controller
@RequestMapping("/job.do")
class JobController {
@Autowired
SchedulerService schedulerService;
@RequestMapping(params = "method=list")
public ModelAndView list() throws IOException {
ModelAndView view = new ModelAndView("jobList");
List<Map<String, Object>> jobs = schedulerService.getQrtzJobs();
view.addObject("items",jobs);
return view;
}
@RequestMapping(params = "method=edit")
public ModelAndView edit() throws IOException {
ModelAndView view = new ModelAndView("jobEdit");
return view;
}
@RequestMapping(params = "method=save")
public ModelAndView save(HttpServletRequest request,
HttpServletResponse response) throws IOException {
ModelAndView view = new ModelAndView("redirect:job.do?method=list");
String jobName = request.getParameter("jobName");
String jobTaskName = request.getParameter("jobTaskName");
String jobType = request.getParameter("jobType");
String relateBeanNames = request.getParameter("relateBeanNames");

if(StringUtil.isNotBlank(jobType)){
if("spring".equals(jobType)){
Map paras = null;
if(StringUtil.isNotBlank(relateBeanNames)){
paras = new HashMap<String,Object>();
paras.put("RELATE_BEANS",relateBeanNames);
}
schedulerService.addSpringJob(jobName, null, jobTaskName, paras);
}else if("java".equals(jobType)){
schedulerService.addJob(jobName, null, jobTaskName, null);
}
}
return view;
}
@RequestMapping(params = "method=cmd")
public void cmd(HttpServletRequest request,
HttpServletResponse response) throws IOException {
String action = request.getParameter("action");
String jobName = request.getParameter("jobName");
if(StringUtil.isNotBlank(action) && StringUtil.isNotBlank(jobName)){
jobName = URLDecoder.decode(jobName,"UTF-8");
if("pause".equals(action)){
//暂停任务
schedulerService.pauseJob(jobName, null);
response.getWriter().println(0);
}else if("resume".equals(action)){
//重启任务
schedulerService.resumeJob(jobName, null);
response.getWriter().println(0);
}else if("remove".equals(action)){
//删除任务
schedulerService.removeJob(jobName, null);
response.getWriter().println(0);
}
}
}
}
velocity的灵活布局
布局上参考了以前一个北京同事的BLOG,呵呵http://qieqie.iteye.com/blog/65028
核心配置文件也在这个core-context.xml里面:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:lang="http://www.springframework.org/schema/lang"
xmlns:groovy="http://www.sillycat.com/schema/groovy"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.sillycat.com/schema/groovy http://www.sillycat.com/schema/groovy/groovy.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:component-scan base-package="cn.sccl" />
<!-- 属性文件读入 -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:config.properties</value>
</list>
</property>
</bean>
<bean id="velocityConfig"
class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<property name="resourceLoaderPath" value="${velocity.file.path}/template/" />
<property name="velocityProperties">
<props>
<prop key="input.encoding">UTF-8</prop>
<prop key="output.encoding">UTF-8</prop>
<prop key="contentType">text/html;charset=UTF-8</prop>
</props>
</property>
</bean>
<bean id="velocityViewResolver"
class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">
<property name="layoutUrl" value="layout/layout.vm"/>
<property name="cache" value="false" />
<property name="suffix" value=".vm" />
<property name="exposeSpringMacroHelpers" value="true" />
<property name="contentType" value="text/html;charset=UTF-8" />
</bean>
</beans>
默认的velocity的路径指向了config.properties里面配置的:
################################################
# velocity path
################################################
velocity.file.path=file://D:/project/CPMIS-Core/Code/Trunk/tasksupervisor

这样,就做到了velocity页面文件也和war分开了。也就是说,我平时改页面,改controller层代码,其实我都不需要重新发布war包,只要改了文件上传就行了。

另外我的velocity layout布局是怎么回事呢,看看以下几个文件就明白了:
/template/layout/layout.vm
<html>
<head>
<title>任务调度系统</title>
</head>
<body>
<div id="header">#parse('common/header.vm')</div>
<div id="content">
<div id="sub">#parse($sub)</div>
<div id="main">$screen_content</div>
</div>
<div id="footer">#parse('common/footer.vm')</div>
</body>
</html>
/template/common/header.vm
header is here!
/template/common/footer.vm
footer is here!
/template/common/menu.vm
<a href="job.do?method=edit">新增任务</a>   |   
<a href="trigger.do?method=edit">新增调度</a>   |   
<a href="job.do?method=list">任务管理</a>   |   
<a href="trigger.do?method=list">调度管理</a>   |   <br />
当访问我的真实页面/template/jobEdit.vm的时候,会在jobEdit.vm里面设置,我要调用哪个layout,哪个sub元素,其实以前在淘宝用的webx框架就和这个很类似,访问一个页面就去找对应文件夹的layout,可能就是从这里得到灵感出来的。
#set($layout = "layout/layout_edit.vm")
#set($sub= "common/menu.vm")
<h1>新增任务</h1>
....省略

完成以上功能后,发现,整个项目的velocity展现层+groovy控制层都比较灵活了,同时又有很灵活的layout布局,把很多页面单元可以抽取成各个小模块,放置到commons里面以供调用,修改velocity文件和groovy文件也不用重启服务,很方便。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值