一.简介

     最近项目一直在用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" οnclick="searchData()">查询</a> 
		<a href="#" class="easyui-linkbutton" iconCls="icon-reload" οnclick="resetCondition()">重置</a> 
	</div> 
	<div style="margin-top:5px;"> 
		<a href="#" class="easyui-linkbutton" iconCls="icon-add" plain="true" οnclick="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="###" οnclick="editRow('+rec.id+')">编辑</a>'; 
						e += ' | '; 
						d='<a href="###" οnclick="deleteRow('+rec.id+')">删除</a>'; 
						d += ' | '; 
					var f = '<a href="###" οnclick="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>

   页面如图所示:
       
          
    

           

          






本文参考链接:https://blog.csdn.net/congcong68/article/details/43953111
评论关闭
IT虾米网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

Java多线程中Lock锁如何使用