原文转载:http://blog.csdn.net/congcong68/article/details/43953111
一.简介
最近项目一直在用SpringMVC+ Easyui +FreeMarker,最近比较有时间,重新复习一下,整个的搭建的过程,以及使用。
FreeMarker是模板引擎,是一种基于模板的、用来生成输出文本的通用工具,是基于Java的开发包和类库的。FreeMarker被设计用来生成HTML Web页面,特别是基于MVC(Model View Controller)模式的应用程序,FreeMarker与Web容器无关,即在Web运行时,它并不知道Servlet或HTTP,使用Servlet提供的数据动态地生成 HTML。
FreeMarker跟JSP相比,JSP运行时,需要在被执行的时候编译成Servlet, FreeMarker模板技术不存在编译,所以效率上FreeMarker会比较好,而且Freemarker内置了很多web编程中很常用的方法(日期转换、数字格式化等)方便开发人员操作。
Easyui是一种基于jQuery的用户界面插件集合,提供了大多数UI控件的使用,如:accordion,combobox,menu,dialog,tabs,validatebox,datagrid,window,tree等。
我们先看一下实现的列表,这样我们在整合时,就是接下来我们要分析的,这样思路会比较清晰,如图所示:
二.FreeMarker、Easyui在SpringMVC整合
1.SpringMVC配置Easyui的配置文件(spring-mvc.xml)
- <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
-
- <property name="messageConverters">
- <list>
- <bean class="org.springframework.http.converter.StringHttpMessageConverter">
- <property name="supportedMediaTypes">
- <list>
- <value>text/plain;charset=UTF-8</value>
- <value>text/html;charset=UTF-8</value>
- <value>application/json;charset=UTF-8</value>
- </list>
- </property>
- </bean>
-
- <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
- <property name="supportedMediaTypes">
- <list>
- <value>text/plain;charset=UTF-8</value>
- <value>text/html;charset=UTF-8</value>
- <value>application/json;charset=UTF-8</value>
- </list>
- </property>
- <property name="objectMapper">
-
- <bean class="com.fasterxml.jackson.databind.ObjectMapper">
- <property name="dateFormat">
- <bean class="java.text.SimpleDateFormat">
- <constructor-arg value="yyyy-MM-dd HH:mm:ss" />
- </bean>
- </property>
- </bean>
- </property>
- </bean>
- </list>
- </property>
-
- <property name="webBindingInitializer">
- <bean class="cn.social.card.util.DateBinding" />
- </property>
- lt;/bean>
说明:
HandlerAdapter接口是处理请求的映射。
AnnotationMethodHandlerAdapter类,通过注解,把一个URL映射到Controller类的方法上。这个类有很多个属性,如源代码图所示:
1. messageConverters属性配置的说明
1)messageConverters属性配置可以解决一些乱码的问题,请求和返回值是字符串类型或者对象类型,可以通过messageConverters进行系列化和反系列化,
那AnnotationMethodHandlerAdapter将使用messageConverters查找对应的并
将Controller返回值直接输出到响应体。
2)messageConverters是一个列表,列表中有StringHttpMessageConverter、MappingJackson2HttpMessageConverter等都指定了supportedMediaTypes所支持的类型,如果请求头Accept与某个messageConverter的supportedMediaTypes匹配,那么将使用此messageConverter向响应体输出内容。
(1)MappingJackson2HttpMessageConverter:使用 Jackson 的ObjectMapper 读取/编写 JSON 数据。它转换媒体类型为 application/json 的数据。该类只有org.springframework.web-3.1.2.RELEASE.jar及以上版本才有使用该配置后,才可以使用JSON相关的一些注解,并可以配置日期的格式需要引入jackson-databind-2.2.2.jar:如图所示:
2. webBindingInitializer属性配置
1)webBindingInitializer是全局的属性编辑器,我们配置了日期格式化,有可以配置电话等格式。我们自定义全局的属性编辑器时,需要实现了WebBindingInitializer接口中的initBinder方法,代码如下:
- public class DateBinding implements WebBindingInitializer {
-
-
-
- public void initBinder(WebDataBinder binder, WebRequest request) {
-
-
- SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
- binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
- }
-
- }
日期格式化全局实现好了,我们把这个类
AnnotationMethodHandlerAdapter属性配置对应的,就OK了
2)也可以定义为局部的属性编辑器,只在对应的controller类里有效的
@InitBinder
public void initBinder(WebDataBinder binder)
2.SpringMVC配置FreeMarker的配置文件(spring-mvc.xml)
-
- <bean id="freemarkerConfiguration" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
- <property name="location" value="classpath:freemarker.properties" />
- </bean>
- <bean id="xmlEscape" class="freemarker.template.utility.XmlEscape" />
-
- <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
-
- <property name="templateLoaderPath">
- <value>/WEB-INF/template/</value>
- </property>
- <property name="freemarkerVariables">
- <map>
- <entry key="xml_escape" value-ref="xmlEscape" />
- </map>
- </property>
- <property name="freemarkerSettings" ref="freemarkerConfiguration" />
- </bean>
-
-
- <bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
- <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" />
-
- <property name="viewNames" value="*.ftl" />
- <property name="contentType" value="text/html; charset=utf-8" />
- <property name="cache" value="true" />
- <property name="prefix" value="" />
- <property name="suffix" value="" />
- <property name="order" value="1"></property>
- <property name="requestContextAttribute" value="rc" />
- </bean>
freemarker.properties (
freemarker一些转换配置)
- tag_syntax=auto_detect
- template_update_delay=2
- default_encoding=UTF-8
- output_encoding=UTF-8
- locale=zh_CN
- date_format=yyyy-MM-dd
- time_format=HH:mm:ss
- datetime_format=yyyy-MM-dd HH\:mm\:ss
- number_format=#
说明:
1)通过prefix属性指定一个指定的前缀,通过suffix属性指定一个指定的后缀,然后把返回的逻辑视图名称加上指定的前缀和后缀就是指定的视图URL了。
2)<property name="order"value="1"> value="0"代表了第一个匹配的是freemarker的视图解析器,如果匹配不成功,则自动选择order="1"的其他解析器,目前的通用解析器可以解析.ftl的视图,如果需要其他视图的解析器,可以在添加新的解析器
value值对应的跟现在不一样。
三.SpringMVC的Controller代码的实现
刚才我们介绍了Spring的配置文件,现在我们介绍代码的实现,@Controller @RequestMapping @ResponseBody这些注解就不在介绍一下,网上资料很多,代码如下:
- @Controller
- @RequestMapping(value="/admin/user")
- public class UserController {
-
- @Autowired
- private UserService userService;
-
-
-
-
-
-
-
-
- @RequestMapping(value="/index")
- public String showRootLayer(HttpSession session, HttpServletRequest request, ModelMap map) {
- String contextPath = request.getContextPath();
- User user=(User) session.getAttribute("user");
- map.put("contextPath", contextPath);
- map.put("user", user);
- return "/user/index.ftl";
- }
-
-
-
-
-
-
-
-
- @ResponseBody
- @RequestMapping(value="/listData", method=RequestMethod.POST)
- public EUDGPagination detailDataList(HttpSession session, @RequestParam(value="page") int page, @RequestParam(value="rows") int rows, @RequestParam(value="yhm",required=false) String yhm, @RequestParam(value="rymc",required=false) String rymc, @RequestParam(value="rybh",required=false) String rybh) {
- if(page<=0) page=1;
- if(yhm!=null){yhm=yhm.trim();}
- if(rymc!=null){rymc=rymc.trim();}
- if(rybh!=null){rybh=rybh.trim();}
- Map<String, Object> params = new HashMap<String, Object>();
- params.put("yhm", yhm);
- params.put("rymc", rymc);
- params.put("rybh", rybh);
- User user=(User) session.getAttribute("user");
- params.put("user",user);
- EUDGPagination pagination = userService.findUserPagination(page, rows, params);
- return pagination;
- }
-
-
-
-
-
-
-
-
-
- @RequestMapping(value="/detail")
- public String detail(HttpSession session,@RequestParam(value="id") Long id, HttpServletRequest request, ModelMap map) {
- String contextPath = request.getContextPath();
- User user=userService.findUserById(id);
- map.put("contextPath", contextPath);
- User userSession=(User) session.getAttribute("user");
- map.put("user", user);
- map.put("userSession", userSession);
- return "/user/detail.ftl";
- }
-
- }
四.Easyui列表的实现
- <!DOCTYPE html PUBLIC "-/W3C/DTD XHTML 1.0 Transitional/EN" "http:/www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http:/www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>请假管理</title>
- <link rel="stylesheet" type="text/css" href="${contextPath}/css/main_new.css" />
- <link rel="stylesheet" type="text/css" href="${contextPath}/css/easyui.css">
- <link rel="stylesheet" type="text/css" href="${contextPath}/css/icon.css">
- <link rel="stylesheet" type="text/css" href="${contextPath}/css/demo.css">
- <script type="text/javascript" src="${contextPath}/js/formatDate.js"></script>
- <script type="text/javascript" src="${contextPath}/js/jquery-1.8.0.min.js"></script>
- <script type="text/javascript" src="${contextPath}/js/jquery.easyui.min.js"></script>
- <script type="text/javascript" src="${contextPath}/js/locale/easyui-lang-zh_CN.js"></script>
- </head>
- <body class="easyui-layout">
- <div id="careRoadContentDiv" region="center" title=" 请假管理" border="false" style="overflow:hidden;">
- <table id="list"></table>
- </div>
-
- <div id="jqueryToolbar" style="padding:5px;height:auto">
- <div style="margin-top:5px; padding-bottom:8px; border-bottom:1px solid #ccc;">
- 人员名称:<input type="text" id="rymc" style="width:120px" />
- 人员编号:<input type="text" id="rybh" style="width:120px" />
- <a href="#" class="easyui-linkbutton" iconCls="icon-search" onclick="searchData()">查询</a>
- <a href="#" class="easyui-linkbutton" iconCls="icon-reload" onclick="resetCondition()">重置</a>
- </div>
- <div style="margin-top:5px;">
- <a href="#" class="easyui-linkbutton" iconCls="icon-add" plain="true" onclick="create()">新增</a>
- </div>
- </div>
-
- <script type="text/javascript">
- $(function(){
- $('#list').datagrid({
- width:600,
- height:600,
- nowrap: false,
- striped: true,
- fit: true,
- idField:'id',
- url:'${contextPath}/admin/user/listData.json',
- columns:[[
- {field:'id',title:'',hidden:true},
- {field:'rybh',title:'人员编号', align:'center',width:150},
- {field:'rymc',title:'人员名称', align:'center',width:100},
- {field:'rylx',title:'人员类型', align:'center',width:100},
- {field:'sszhmc',title:'所属部门名称', align:'center',width:200},
- {field:'sqrybh',title:'授权人员编号', align:'center',width:150},
- {field:'czry',title:'操作人员', align:'center',width:120},
- {field:'czsj',title:'操作时间', align:'center',width:130},
- {field:'opt', title:'操作', width:160, align:'center', formatter:function(value, rec, index){
- var e ='';
- var d ='';
- e='<a href="###" onclick="editRow('+rec.id+')">编辑</a>';
- e += ' | ';
- d='<a href="###" onclick="deleteRow('+rec.id+')">删除</a>';
- d += ' | ';
- var f = '<a href="###" onclick="showRow('+ rec.id +')">详情</a>';
- return e+d+f;
- }},
- ]],
- toolbar:'#jqueryToolbar',
- pagination:true,
- queryParams:{},
- onLoadSuccess:function(data){
- $('#list').datagrid('clearSelections');
- if(data.total==0){
- $('.datagrid-body-inner').eq(0).addClass("l_elist");
- $('.datagrid-body').eq(1).append('<div class="r_elist">无数据</div>');
- }else{
- $('.datagrid-body-inner').eq(0).removeClass("l_elist");
- }
- }
- });
-
-
- var p = $('#list').datagrid('getPager');
- $(p).pagination({
- pageSize: 10,
- pageList: [10,20,30,40,50],
- beforePageText: '第',
- afterPageText: '页 共 {pages} 页',
- displayMsg: '当前显示第 {from} 到 {to} 条记录 共 {total} 条记录'
-
-
-
-
-
- });
-
-
- })
-
- function searchData() {
- var a = new Array();
- var yhm = $("#yhm").val();
- if(yhm!=null && yhm!="") a["yhm"]=yhm;
- var rymc = $("#rymc").val();
- if(rymc!=null && rymc!="") a["rymc"]=rymc;
- var rybh = $("#rybh").val();
- if(rybh!=null && rybh!="") a["rybh"]=rybh;
- doSearch(a);
- }
-
- function doSearch(queryParams){
- $('#list').datagrid('clearSelections');
- $("#list").datagrid('options').queryParams=queryParams;
- $("#list").datagrid('load');
- }
-
- function resetCondition(){
- $("#yhm").val("");
- $("#rymc").val("");
- $("#rybh").val("");
- }
-
- function create() {
- var url = '${contextPath}/admin/user/create.jhtml';
- showMaxJqueryWindow("新增用户信息", url);
- }
-
- function editRow(id) {
- var url = '${contextPath}/admin/user/edit.jhtml?id='+id;
- showMaxJqueryWindow("编辑用户信息", url);
- }
-
- function showRow(id) {
- var url = '${contextPath}/admin/user/detail.jhtml?id='+id;
- showMaxJqueryWindow("用户详情", url);
- }
-
- </script>
- </body>
- </html>
说明:
1)field中的值要跟实体的属性名称一样,不然就获取不到
2)SpringMVC的Controller中方法要注解为
@ResponseBody,返回的是JSON格式如下所示:
- {"total":4,"rows":[{"id":6,"sszhmc":"5301d","mm":"1","rybh":"test3","sqrybh":"1","rymc":"1 ","rylx":"1","czry":"admin","czsj":"2014-12-27 14:02:31","role":null},{"id":5,"sszhmc":"52k ","mm":"1","rybh":"test2","sqrybh":"1","rymc":"1","rylx":"1 ","czry":"admin","czsj":"2014-12-27 14:02:14","role":null},{"id":4,"sszhmc":"51h","mm":"1","rybh":"test","sqrybh":"1","rymc":"1 ","rylx":"1","czry":"admin ","czsj":"2014-12-27 13:39:25 ","role":null},{"id":3,"sszhmc":"50郑 ","mm":"123456","rybh":"admin","sqrybh":"","rymc":"","rylx":"","czry":"","czsj":"","role":null}],"footer":null}
五.FreeMarker的实现
而且Freemarker内置了很多web编程中很常用的方法(日期转换、数字格式化等)方便开发人员操作
插值:即${...}或#{...}格式的部分,将使用数据模型中的部分替代输出
- <body>
- <div id="infoTabs" class="easyui-tabs" fit="true" border="false" style="margin: 0; height:530px;">
- <div title="用户信息" id="editInfo" style="margin:0">
- <form id="tableForm" name="tableForm" action="${contextPath}/admin/base/report.jhtml" method="post">
- <table width="100%" border="0" cellspacing="0" cellpadding="0" class="border-t">
- <tr class="item">
- <td class="itemtit"> 人员编号</td>
- <td class="border_b" colspan="3">
- ${user.rybh!''}
- </td>
- </tr>
-
- <tr class="item">
-
- <td class="itemtit"> 密码</td>
- <td class="border_b" colspan="3">
- ${user.mm!''}
- </td>
-
- </tr>
-
-
-
- <tr class="item">
- <td class="itemtit"> 授权人员编号</td>
- <td class="border_b" colspan="3">
- ${user.sqrybh!''}
- </td>
- </tr>
-
- <tr class="item">
- <td class="itemtit"> 人员名称</td>
- <td class="border_b" colspan="3">
- ${user.rymc!''}
- </td>
- </tr>
- <tr class="item">
- <td class="itemtit"> 人员类型</td>
- <td class="border_b" colspan="3">
- ${user.rylx!''}
- </td>
- </tr>
- <tr class="item">
- <td class="itemtit"> 所属部门名称</td>
- <td class="border_b" colspan="3">
- ${user.sszhmc!''}
- </td>
- </tr>
- <tr class="item">
- <td class="itemtit"> 操作人员</td>
- <td class="border_b" colspan="3">
- ${user.czry!''}
- </td>
- </tr>
- <tr class="item">
- <td class="itemtit"> 操作人员</td>
- <td class="border_b" colspan="3">
- ${user.czsj!''}
- </td>
- </tr>
- </table>
- </form>
- </div>
-
- </div>
页面如图所示: