SpringMVC与Easyui(实现了JSON的展示)、FreeMarker的整合


一.简介

最近项目一直在用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">
		<!-- 解决JSON中文乱码问题 -->
		<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>
				<!-- 该类只有org.springframework.web-3.1.2.RELEASE.jar及以上版本才有  使用该配置后,才可以使用JSON相关的一些注解-->
                <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">
                    <!-- jackson-databind-2.2.2.jar -->
                 		<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>
	    <!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射   请求映射-->
	    <property name="webBindingInitializer">
            <bean class="cn.social.card.util.DateBinding" />
        </property>
	</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 {
    /**
     * 表单数据(全部是字符串)通过WebDataBinder进行绑定到命令对象,内部通过PropertyEditor实现
     */
	public void initBinder(WebDataBinder binder, WebRequest request) {
		//使用spring自带的CustomDateEditor
		//注册自定义的属性编辑器(日期)
		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)

	<!-- 设置freeMarker的配置文件路径 -->
	<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" />
	<!-- freeMarker的模板配置 -->
	<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
		<!--视图解析器会在/WEB-INF/template/路径下查找-->
		<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>

	<!-- 配置freeMarker视图解析器 -->
	<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
		<property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView" />
		<!--查找对应下所有以ftl结尾的文件-->
		<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;

	/**
	 * 用户信息首页
	 * @param session
	 * @param request
	 * @param map
	 * @return
	 */
	@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";
	}

	/**
	 * 获取用户信息列表
	 * @param session
	 * @param page
	 * @param rows
	 * @return
	 */
	@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;
	}

	/**
<span style="white-space:pre">	</span> * 详情页面
<span style="white-space:pre">	</span> * @param session
<span style="white-space:pre">	</span> * @param id
<span style="white-space:pre">	</span> * @param request
<span style="white-space:pre">	</span> * @param map
<span style="white-space:pre">	</span> * @return
<span style="white-space:pre">	</span> */
	@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} 条记录'/*,
			onBeforeRefresh:function(){
				$(this).pagination('loading');
				alert('before refresh');
				$(this).pagination('loaded');
			}*/
		});

	})

	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>

页面如图所示:

时间: 2024-07-29 13:59:14

SpringMVC与Easyui(实现了JSON的展示)、FreeMarker的整合的相关文章

springmvc + jquery easyui实现分页显示

如有不明白的地方,戏迎加入QQ群交流:66728073 一,下载并导入jquery easyui的导 <link rel="stylesheet" type="text/css" href="<%=basePath%>js/jquery-easyui-1.4/themes/default/easyui.css"> <link rel="stylesheet" type="text/css

springmvc+mybatis+easyui分页

道德三黄五帝,功名夏侯商周.五霸七雄闹春秋,顷刻兴亡过手.清时几行名姓,北芒无数荒丘.前人播种后人收,说什么原创与否. 今天和大家分享一下springmvc+mybatis+easyui的分页实现.springmvc,mybatis的优缺点不做太多敖述大家都比较了解了,ssm框架整合的例子网上也有很多了,为什么还要写这篇文章那,主要是觉得大多过于零散配置方式又是千差万别,总结一下本文希望对遇到此问题的人有所帮助,前人播种后人收.当然程序开发没有觉得正确,谁也说不出一个正确的实现第N行代码是什么,

学习SpringMVC(二十)之返回JSON

首先要加入三个JAR包: 其次在Controller中: <span style="font-family:SimSun;font-size:18px;">package com.cgf.springmvc.handlers; import java.util.Collection; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereo

SpringMVC Ajax请求时返回json中文字符串的乱码问题的解决方案

1.org.springframework.http.converter.StringHttpMessageConverter类是处理请求或相应字符串的类,并且默认字符集为ISO-8859-1,所以在当返回json中有中文时会出现乱码. 2.StringHttpMessageConverter的父类里有个List<MediaType> supportedMediaTypes属性,用来存放StringHttpMessageConverter支持需特殊处理的MediaType类型,如果需处理的Me

SpringMVC 中使用 @ResponseBody 返回Json时,需要手动添加jackson依赖

No converter found for return value of type: class java.util.HashMapSpringMVC 中使用 @ResponseBody 返回Json时,需要手动添加jackson依赖!Maven添加: <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId>

springMVC+freemarker+slf4j整合(基于注解方式)

springmvc在项目中使用较多,本文将基于spring注解springMVC+freemarker+slf4j整合在一起,便于开发,后续还会将ibatis整合进来. 第一步:使用编程工具建立web工程,本文使用eclipse + tomcat 7.0 + jdk 1.7. 第二步:引入工程使用到的jar文件: commons-logging-1.1.3.jar.freemarker-2.3.20.jar.logback-classic-1.0.9.jar.logback-core-1.0.9

SpringMVC+FreeMarker+Mybatis 整合

这个项目自己有时写写测试代码什么的, 代码比较简单,代码已放在 github : https://github.com/zhouyongtao/homeinns-web 目录结构: 贴一下Maven的POM <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=&quo

spring+websocket整合(springMVC+spring+MyBatis即SSM框架和websocket技术的整合)

java-websocket的搭建非常之容易,没用框架的童鞋可以在这里下载撸主亲自调教好的java-websocket程序: Apach Tomcat 8.0.3+MyEclipse+maven+JDK1.7 spring4.0以后加入了对websocket技术的支持,撸主目前的项目用的是SSM(springMVC+spring+MyBatis)框架,所 以肯定要首选spring自带的websocket了,好,现在问题来了,撸主在网上各种狂搜猛找,拼凑了几个自称是spring websocket

Spring+SpringMVC+MyBatis+easyUI整合基础篇(二)牛刀小试

承接上文,该篇即为项目整合的介绍了. 废话不多说,先把源码和项目地址放上来,重点要写在前面. github地址为ssm-demo 你也可以先体验一下实际效果,点击这里就行啦 账号:admin 密码:123456 从构思这个博客,一直到最终确定以这个项目为切入点,中间也是各种问题出现,毕竟是新人,所以也是十分的小心,修改代码以及搬上github其实花了不少时间,但也特别的认真,不知道是怎么回事,感觉这几天的过程比逼死产品经理还要精彩和享受.或许是博客路上的第一站吧,有压力也有新奇,希望自己能坚持下