• Spring+Mybatis+SpringMVC后台与前台分页展示实例(附工程)


     林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka

           摘要:本文实现了一个后台由Spring+Mybatis+SpringMVC组成,分页采用PageHelper,前台展示使用bootstrap-paginator来显示效果的分页实例。整个项目由maven构成。这里主要讲了分页的实例,框架怎么搭建就不再说明,主要是在这里的基础上来增加分页功能的。注意,此文是在这个基础 Spring+Mybatis+SpringMVC+Maven+MySql搭建实例 之上来做分页的,建议文中看不懂的配置可以看看这里。

    整个工程下载(旧版本,日志打印使用log4j,数据库配置放在properties文件)

    新版本下载:https://github.com/appleappleapple/ssm_project (日志打印使用logback,数据库配置放在POM.XML)博主推荐使用新版本,而且这里详细说明了整个工程应用的框架,数据源配置,SQL语句等等!

    重要的事情说三遍:请下新版本~请下新版本~请下新版本~

    最后的结果如下:

    环境:jdk1.6

             Tomcat 7.0

             Eclipse luna/windows 7    

    一、后台PageHelper使用

    PageHelper:https://github.com/pagehelper/Mybatis-PageHelper

    1、引入jar包

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <!-- 添加分布插件的包pagehelper -->  
    2. <dependency>  
    3.     <groupId>com.github.pagehelper</groupId>  
    4.     <artifactId>pagehelper</artifactId>  
    5.     <version>4.0.0</version>  
    6. </dependency>  


    2.mybatis-config.xml中添加插件

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <plugins>  
    2.     <!-- com.github.pagehelper为PageHelper类所在包名 -->  
    3.     <plugin interceptor="com.github.pagehelper.PageHelper">  
    4.         <property name="dialect" value="mysql"/>  
    5.         <!-- 该参数默认为false -->  
    6.         <!-- 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 -->  
    7.         <!-- 和startPage中的pageNum效果一样-->  
    8.         <property name="offsetAsPageNum" value="true"/>  
    9.         <!-- 该参数默认为false -->  
    10.         <!-- 设置为true时,使用RowBounds分页会进行count查询 -->  
    11.         <property name="rowBoundsWithCount" value="true"/>  
    12.         <!-- 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 -->  
    13.         <!-- (相当于没有执行分页查询,但是返回结果仍然是Page类型)-->  
    14.         <property name="pageSizeZero" value="true"/>  
    15.         <!-- 3.3.0版本可用 - 分页参数合理化,默认false禁用 -->  
    16.         <!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 -->  
    17.         <!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->  
    18.         <property name="reasonable" value="false"/>  
    19.         <!-- 3.5.0版本可用 - 为了支持startPage(Object params)方法 -->  
    20.         <!-- 增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 -->  
    21.         <!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值 -->  
    22.         <!-- 不理解该含义的前提下,不要随便复制该配置 -->  
    23.         <property name="params" value="pageNum=start;pageSize=limit;"/>  
    24.     </plugin>  
    25. </plugins>  

    这样子就引入进来了,接下来就是来开始分页功能的实现

    3、mapper文件中添加如下一个方法:

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <select id="selectUserByUserName" parameterType="java.lang.String" resultMap="BaseResultMap">  
    2.     SELECT *  
    3.     FROM t_user  
    4.     WHERE 1 = 1  
    5.     <if test="userName != null and userName !=''">  
    6.         AND USER_NAME = #{userName,jdbcType=VARCHAR}  
    7.     </if>  
    8.     ORDER BY USER_ID  
    9. </select>  


    注意,这里的返回其实是一个list

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <!--设置domain类和数据库中表的字段一一对应,注意数据库字段和domain类中的字段名称不致,此处一定要! -->  
    2. <resultMap id="BaseResultMap" type="com.lin.domain.User">  
    3.     <id column="USER_ID" property="userId" jdbcType="INTEGER" />  
    4.     <result column="USER_NAME" property="userName" jdbcType="CHAR" />  
    5.     <result column="USER_PASSWORD" property="userPassword" jdbcType="CHAR" />  
    6.     <result column="USER_EMAIL" property="userEmail" jdbcType="CHAR" />  
    7. </resultMap>  


    4、然后就是dao类

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. /**  
    2.  *   
    3.  * @author linbingwen  
    4.  * @since  2015年10月22日   
    5.  * @param userName  
    6.  * @return  
    7.  */  
    8. List<User> selectUserByUserName(@Param("userName") String userName);  


    这里一定的记得加@Param("userName")

    接下来就可以在service层中添加分页查询的的接口了

    5、接口类

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. /**  
    2.  *   
    3.  * @author linbingwen  
    4.  * @since  2015年10月23日   
    5.  * @param userName 查询条件,可为空  
    6.  * @param pageNo 查询条件,可为空,默认取1  
    7.  * @param pageSize 查询条件,可为空,默认取10  
    8.  * @return  
    9.  */  
    10. PagedResult<User> queryByPage(String userName,Integer pageNo,Integer pageSize);  

    6、实现类

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. public PagedResult<User> queryByPage(String userName,Integer pageNo,Integer pageSize ) {  
    2.     pageNo = pageNo == null?1:pageNo;  
    3.     pageSize = pageSize == null?10:pageSize;  
    4.     PageHelper.startPage(pageNo,pageSize);  //startPage是告诉拦截器说我要开始分页了。分页参数是这两个。  
    5.     return BeanUtil.toPagedResult(userDao.selectUserByUserName(userName));  
    6. }  

    这里就可以直接在返回里头使用了PageHelper,这里userDao.selectUserByUserName(userName)的返回是一个list

    其中,PagedResult是我自己封装的一个分页结果类

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.lin.util;  
    2.   
    3. import java.util.List;  
    4.   
    5. import com.lin.dto.BaseEntity;  
    6.   
    7. /** 
    8.  * 功能概要: 
    9.  *  
    10.  * @author linbingwen 
    11.  * @since  2015年10月23日  
    12.  */  
    13. public class PagedResult<T> extends BaseEntity {  
    14.       
    15.     /*serialVersionUID*/  
    16.     private static final long serialVersionUID = 1L;  
    17.   
    18.     private List<T> dataList;//数据  
    19.       
    20.     private long pageNo;//当前页  
    21.       
    22.     private long pageSize;//条数  
    23.       
    24.     private long total;//总条数  
    25.       
    26.     private long pages;//总页面数目  
    27.   
    28.     public List<T> getDataList() {  
    29.         return dataList;  
    30.     }  
    31.   
    32.     public void setDataList(List<T> dataList) {  
    33.         this.dataList = dataList;  
    34.     }  
    35.   
    36.     public long getPageNo() {  
    37.         return pageNo;  
    38.     }  
    39.   
    40.     public void setPageNo(long pageNo) {  
    41.         this.pageNo = pageNo;  
    42.     }  
    43.   
    44.     public long getPageSize() {  
    45.         return pageSize;  
    46.     }  
    47.   
    48.     public void setPageSize(long pageSize) {  
    49.         this.pageSize = pageSize;  
    50.     }  
    51.   
    52.     public long getTotal() {  
    53.         return total;  
    54.     }  
    55.   
    56.     public void setTotal(long total) {  
    57.         this.total = total;  
    58.     }  
    59.   
    60.     public long getPages() {  
    61.         return pages;  
    62.     }  
    63.   
    64.     public void setPages(long pages) {  
    65.         this.pages = pages;  
    66.     }  
    67.       
    68. }  

    这是它的基类

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.lin.dto;  
    2.   
    3. import java.io.Serializable;  
    4. import java.lang.reflect.Method;  
    5. import java.lang.reflect.Modifier;  
    6. import java.util.ArrayList;  
    7. import java.util.HashMap;  
    8. import java.util.List;  
    9. import java.util.Map;  
    10.   
    11. /**  
    12.  *   
    13.  * <b>类说明:</b>bean基类  
    14.  *   
    15.  * <p>  
    16.  * <b>详细描述:</b>  
    17.  *   
    18.  * @author costin_law   
    19.  * @since 2014-5-5  
    20.  */  
    21. public abstract class BaseEntity implements Serializable{  
    22.     private static final long serialVersionUID = 1L;  
    23.       
    24.     private static Map<Class<?>,PropertyInfo[]class2Props = new HashMap<Class<?>,PropertyInfo[]>(128);  
    25.       
    26.     @Override  
    27.     public String toString() {  
    28.         PropertyInfo[] props = class2Props.get(this.getClass());  
    29.         if( props == null ){  
    30.             props = getProps(this.getClass());  
    31.         }  
    32.           
    33.         StringBuilder   builder = new StringBuilder(1024);  
    34.         boolean isFirst = true;  
    35.         for (int i = 0, n = props.length; i n; i++) {  
    36.             try {  
    37.                 PropertyInfo propInfo = props[i];                 
    38.                   
    39.                 Object value = propInfo.getMethod.invoke(this, new Object[0]);  
    40.                 if (isFirst)  
    41.                     isFirst = false;  
    42.                 else  
    43.                     builder.append(",");  
    44.                 builder.append(propInfo.propName);  
    45.                 builder.append(":");  
    46.                 if (value instanceof String)  
    47.                     builder.append(""");  
    48.                 builder.append(value);  
    49.                 if (value instanceof String)  
    50.                     builder.append(""");                 
    51.             } catch (Exception e) {  
    52.                 // ignore  
    53.             }  
    54.         }  
    55.         return "{" + builder.toString() + "}";  
    56.     }  
    57.   
    58.     private static PropertyInfo[] getProps(Class<? extends BaseEntity> clazz) {  
    59.         PropertyInfo[] props;  
    60.         Method[] allMethods = clazz.getMethods();   
    61.         List<PropertyInfopropList = new ArrayList<PropertyInfo>();  
    62.           
    63.         for (int i = 0, n = allMethods.length; i n; i++) {  
    64.             try {  
    65.                 Method method = allMethods[i];  
    66.                 if ((method.getModifiers() & Modifier.PUBLIC) == 1  
    67.                         && method.getDeclaringClass() != Object.class  
    68.                         && (method.getParameterTypes() == null || method  
    69.                                 .getParameterTypes().length == 0)) {  
    70.                     String methodName = method.getName();  
    71.                     if (methodName.startsWith("get") || methodName.startsWith("is") ) {  
    72.                         PropertyInfo propInfo = new PropertyInfo();                                       
    73.                         propInfo.getMethod = method;  
    74.                         if (methodName.startsWith("get")) {  
    75.                             propInfo.propName = methodName.substring(3, 4).toLowerCase()  
    76.                                     + methodName.substring(4);  
    77.                         } else if (methodName.startsWith("is")) {  
    78.                             propInfo.propName = methodName.substring(2, 3).toLowerCase()  
    79.                                     + methodName.substring(3);  
    80.                         }                 
    81.                         propList.add(propInfo);  
    82.                     }  
    83.                 }                     
    84.             }catch(Exception e){                      
    85.             }  
    86.         }  
    87.           
    88.         props =  new PropertyInfo[propList.size()];  
    89.         propList.toArray(props);  
    90.         class2Props.put(clazz, props);  
    91.         return props;  
    92.     }  
    93.       
    94.     static class PropertyInfo{  
    95.         Method getMethod;  
    96.         String propName;          
    97.     }  
    98.   
    99. }  

    BeanUtil是一个将PageHelper返回的list转成pageResult的工具

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.lin.util;  
    2.   
    3. import java.util.List;  
    4.   
    5. import com.github.pagehelper.Page;  
    6. import com.lin.util.PagedResult;  
    7.   
    8. /**  
    9.  * 功能概要:  
    10.  *   
    11.  * @author linbingwen  
    12.  * @since  2015年10月22日   
    13.  */  
    14.   
    15.   
    16. public class BeanUtil {  
    17.   
    18.     public static <T> PagedResult<T> toPagedResult(List<T> datas) {  
    19.         PagedResult<Tresult = new PagedResult<T>();  
    20.         if (datas instanceof Page) {  
    21.             Page page = (Page) datas;  
    22.             result.setPageNo(page.getPageNum());  
    23.             result.setPageSize(page.getPageSize());  
    24.             result.setDataList(page.getResult());  
    25.             result.setTotal(page.getTotal());  
    26.             result.setPages(page.getPages());  
    27.         }  
    28.         else {  
    29.             result.setPageNo(1);  
    30.             result.setPageSize(datas.size());  
    31.             result.setDataList(datas);  
    32.             result.setTotal(datas.size());  
    33.         }  
    34.   
    35.         return result;  
    36.     }  
    37.   
    38. }  


    7、这样就好了,可以跑单元测试了

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. /** 
    2.  * 分页测试 
    3.  * @author linbingwen 
    4.  * @since  2015年10月22日 
    5.  */  
    6. @Test  
    7. public void queryByPage(){  
    8.      PagedResult<User>  pagedResult = userService.queryByPage(null,1,10);//null表示查全部    
    9.      logger.debug("查找结果" + pagedResult);  
    10. }  


    输出结果:


    看不清的话看下面


    查找结果{total:46,dataList:Page{pageNum=1, pageSize=10, startRow=0, endRow=10, total=46, pages=5, reasonable=false,

     pageSizeZero=true},pageNo:1,pageSize:10,pages:5}

    其中的dataList中存放的就是数据

    打个断点看下就知道了:

    二、前台展示分页结果

             前台展示主要使用了bootstrap-paginator,这里的原理其实就是将上面查出来的结果,转换成json数据传给前台,然后前台再根据条数和分页数目、总目生成表格,同时每次点击对应的按钮都发送一个ajax请求到后台查询应对的数据,前台每次发送到后台都会包含分页数目、查询条件

    1、Controller层的基类

    这个基类主要实现了将数据转成json

    引用到的jar包如下:

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <!-- 添加json的依赖包 -->  
    2.         <dependency>  
    3.             <groupId>net.sf.json-lib</groupId>  
    4.             <artifactId>json-lib</artifactId>  
    5.             <version>2.3</version>  
    6.             <classifier>jdk15</classifier>  
    7.         </dependency>  
    8.   
    9.         <dependency>  
    10.             <groupId>org.springframework.data</groupId>  
    11.             <artifactId>spring-data-commons</artifactId>  
    12.             <version>1.6.1.RELEASE</version>  
    13.         </dependency>  
    14.   
    15.         <dependency>  
    16.             <groupId>org.springframework.data</groupId>  
    17.             <artifactId>spring-data-jpa</artifactId>  
    18.             <version>1.4.1.RELEASE</version>  
    19.         </dependency>  
    20.   
    21.         <dependency>  
    22.             <groupId>com.alibaba</groupId>  
    23.             <artifactId>fastjson</artifactId>  
    24.             <version>1.1.34</version>  
    25.         </dependency>  

    基类如下:

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.lin.controller;  
    2.   
    3. import com.lin.common.HttpConstants;  
    4. import com.lin.json.JsonDateValueProcessor;  
    5.   
    6. import net.sf.json.JSONArray;  
    7. import net.sf.json.JSONObject;  
    8. import net.sf.json.JsonConfig;  
    9.   
    10. import org.slf4j.Logger;  
    11. import org.slf4j.LoggerFactory;  
    12.   
    13. import java.util.Date;  
    14.   
    15. /** 
    16.  * Controller基类 
    17.  */  
    18. public class BaseController {  
    19.   
    20.     protected Logger logger = LoggerFactory.getLogger(this.getClass());  
    21.       
    22.     protected final static String DATE_FORMATE = "yyyy-MM-dd";  
    23.       
    24.     /** 
    25.      * 返回服务端处理结果 
    26.      * @param obj 服务端输出对象 
    27.      * @return 输出处理结果给前段JSON格式数据 
    28.      * @author YANGHONGXIA 
    29.      * @since 2015-01-06 
    30.      */  
    31.     public String responseResult(Object obj){  
    32.         JSONObject jsonObj = null;  
    33.         if(obj != null){  
    34.             logger.info("后端返回对象:{}", obj);  
    35.             JsonConfig jsonConfig = new JsonConfig();   
    36.             jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor());  
    37.             jsonObj = JSONObject.fromObject(obj, jsonConfig);  
    38.             logger.info("后端返回数据:" + jsonObj);  
    39.             if(HttpConstants.SERVICE_RESPONSE_SUCCESS_CODE.equals(jsonObj.getString(HttpConstants.SERVICE_RESPONSE_RESULT_FLAG))){  
    40.                 jsonObj.element(HttpConstants.RESPONSE_RESULT_FLAG_ISERROR, false);  
    41.                 jsonObj.element(HttpConstants.SERVICE_RESPONSE_RESULT_MSG, "");  
    42.             }else{  
    43.                 jsonObj.element(HttpConstants.RESPONSE_RESULT_FLAG_ISERROR, true);  
    44.                 String errMsg = jsonObj.getString(HttpConstants.SERVICE_RESPONSE_RESULT_MSG);  
    45.                 jsonObj.element(HttpConstants.SERVICE_RESPONSE_RESULT_MSG, errMsg==null?HttpConstants.SERVICE_RESPONSE_NULL:errMsg);  
    46.             }  
    47.         }  
    48.         logger.info("输出结果:{}", jsonObj.toString());  
    49.         return jsonObj.toString();  
    50.     }  
    51.       
    52.     /** 
    53.      * 返回成功 
    54.      * @param obj 输出对象 
    55.      * @return 输出成功的JSON格式数据 
    56.      */  
    57.     public String responseSuccess(Object obj){  
    58.         JSONObject jsonObj = null;  
    59.         if(obj != null){  
    60.             logger.info("后端返回对象:{}", obj);  
    61.             JsonConfig jsonConfig = new JsonConfig();   
    62.             jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor());  
    63.             jsonObj = JSONObject.fromObject(obj, jsonConfig);  
    64.             logger.info("后端返回数据:" + jsonObj);  
    65.             jsonObj.element(HttpConstants.RESPONSE_RESULT_FLAG_ISERROR, false);  
    66.             jsonObj.element(HttpConstants.SERVICE_RESPONSE_RESULT_MSG, "");  
    67.         }  
    68.         logger.info("输出结果:{}", jsonObj.toString());  
    69.         return jsonObj.toString();  
    70.     }  
    71.   
    72.     /** 
    73.      * 返回成功 
    74.      * @param obj 输出对象 
    75.      * @return 输出成功的JSON格式数据 
    76.      */  
    77.     public String responseArraySuccess(Object obj){  
    78.         JSONArray jsonObj = null;  
    79.         if(obj != null){  
    80.             logger.info("后端返回对象:{}", obj);  
    81.             JsonConfig jsonConfig = new JsonConfig();  
    82.             jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor());  
    83.             jsonObj = JSONArray.fromObject(obj, jsonConfig);  
    84.             logger.info("后端返回数据:" + jsonObj);  
    85.         }  
    86.         logger.info("输出结果:{}", jsonObj.toString());  
    87.         return jsonObj.toString();  
    88.     }  
    89.       
    90.     /** 
    91.      * 返回成功 
    92.      * @param obj 输出对象 
    93.      * @return 输出成功的JSON格式数据 
    94.      */  
    95.     public String responseSuccess(Object obj, String msg){  
    96.         JSONObject jsonObj = null;  
    97.         if(obj != null){  
    98.             logger.info("后端返回对象:{}", obj);  
    99.             JsonConfig jsonConfig = new JsonConfig();   
    100.             jsonConfig.registerJsonValueProcessor(Date.class, new JsonDateValueProcessor());  
    101.             jsonObj = JSONObject.fromObject(obj, jsonConfig);  
    102.             logger.info("后端返回数据:" + jsonObj);  
    103.             jsonObj.element(HttpConstants.RESPONSE_RESULT_FLAG_ISERROR, false);  
    104.             jsonObj.element(HttpConstants.SERVICE_RESPONSE_RESULT_MSG, msg);  
    105.         }  
    106.         logger.info("输出结果:{}", jsonObj.toString());  
    107.         return jsonObj.toString();  
    108.     }  
    109.       
    110.     /** 
    111.      * 返回失败 
    112.      * @param errorMsg 错误信息 
    113.      * @return 输出失败的JSON格式数据 
    114.      */  
    115.     public String responseFail(String errorMsg){  
    116.         JSONObject jsonObj = new JSONObject();  
    117.         jsonObj.put(HttpConstants.RESPONSE_RESULT_FLAG_ISERROR, true);  
    118.         jsonObj.put(HttpConstants.SERVICE_RESPONSE_RESULT_MSG, errorMsg);  
    119.         logger.info("输出结果:{}", jsonObj.toString());  
    120.         return jsonObj.toString();  
    121.     }  
    122.   
    123. }  

    上面用到的一些变量如下:

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.lin.common;  
    2.   
    3. public class HttpConstants {  
    4.   
    5.     public static final String SYSTEM_ERROR_MSG = "系统错误";  
    6.       
    7.     public static final String REQUEST_PARAMS_NULL = "请求参数为空";  
    8.   
    9.     public static final String SERVICE_RESPONSE_NULL = "服务端返回结果为空";  
    10.       
    11.     // 服务端返回成功的标志  
    12.     public static final String SERVICE_RESPONSE_SUCCESS_CODE = "AMS00000";  
    13.       
    14.     // 服务端返回结果的标志  
    15.     public static final String SERVICE_RESPONSE_RESULT_FLAG = "returnCode";  
    16.       
    17.     // 服务端返回结果失败的标志  
    18.     public static final String SERVICE_RESPONSE_RESULT_MSG = "errorMsg";  
    19.       
    20.     // 返回给前段页面成功或失败的标志  
    21.     public static final String RESPONSE_RESULT_FLAG_ISERROR = "isError";  
    22.       
    23.     // 执行删除操作  
    24.     public static final String OPERATION_TYPE_DELETE = "D";  
    25.   
    26.     public static final String ENUM_PATH = "com.mucfc.msm.enumeration.";  
    27.       
    28. }  


    引用一个包的内容如下:

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.lin.json;  
    2.   
    3. import net.sf.json.JsonConfig;  
    4. import net.sf.json.processors.JsonValueProcessor;  
    5.   
    6. import java.text.SimpleDateFormat;  
    7. import java.util.Date;  
    8. import java.util.Locale;  
    9.   
    10. public class JsonDateValueProcessor implements JsonValueProcessor {  
    11.   
    12.     /** 
    13.      * datePattern 
    14.      */  
    15.     private String datePattern = "yyyy-MM-dd HH:mm:ss";  
    16.   
    17.     /** 
    18.      * JsonDateValueProcessor 
    19.      */  
    20.     public JsonDateValueProcessor() {  
    21.         super();  
    22.     }  
    23.   
    24.     /** 
    25.      * @param format 
    26.      */  
    27.     public JsonDateValueProcessor(String format) {  
    28.         super();  
    29.         this.datePattern = format;  
    30.     }  
    31.   
    32.     /** 
    33.      * @param value 
    34.      * @param jsonConfig 
    35.      * @return Object 
    36.      */  
    37.     public Object processArrayValue(Object value, JsonConfig jsonConfig) {  
    38.         return process(value);  
    39.     }  
    40.   
    41.     /** 
    42.      * @param key 
    43.      * @param value 
    44.      * @param jsonConfig 
    45.      * @return Object 
    46.      */  
    47.     public Object processObjectValue(String key, Object value, JsonConfig jsonConfig) {  
    48.         return process(value);  
    49.     }  
    50.   
    51.     /** 
    52.      * process 
    53.      * 
    54.      * @param value 
    55.      * @return 
    56.      */  
    57.     private Object process(Object value) {  
    58.         try {  
    59.             if (value instanceof Date) {  
    60.                 SimpleDateFormat sdf = new SimpleDateFormat(datePattern, Locale.UK);  
    61.                 return sdf.format((Date) value);  
    62.             }  
    63.             return value == null ? "" : value.toString();  
    64.         } catch (Exception e) {  
    65.             return "";  
    66.         }  
    67.   
    68.     }  
    69.   
    70.     /** 
    71.      * @return the datePattern 
    72.      */  
    73.     public String getDatePattern() {  
    74.         return datePattern;  
    75.     }  
    76.   
    77.     /** 
    78.      * @param pDatePattern the datePattern to set 
    79.      */  
    80.     public void setDatePattern(String pDatePattern) {  
    81.         datePattern = pDatePattern;  
    82.     }  
    83.   
    84. }  

    这里主要实现了能将list/map/set/数组等转换成josn,并传到前台‘

    2、光这里写不行,还得配置springMVC中以json来传递数据,并配置自己的字符过滤器,要不然中文传到前台可能乱码,这里的配置比较复杂,大部分时间都花在这里,

    这里我直接放spingMVC的配置:spring-mvc.xml

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <beans xmlns="http://www.springframework.org/schema/beans"  
    3.   xmlns:p="http://www.springframework.org/schema/p"  
    4.   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    5.   xmlns:context="http://www.springframework.org/schema/context"  
    6.   xmlns:mvc="http://www.springframework.org/schema/mvc"  
    7.   xsi:schemaLocation="  
    8.     http://www.springframework.org/schema/beans  
    9.     http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
    10.     http://www.springframework.org/schema/context  
    11.     http://www.springframework.org/schema/context/spring-context-3.2.xsd  
    12.     http://www.springframework.org/schema/mvc  
    13.     http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">  
    14.        
    15.     <!-- 扫描controller(controller层注入) -->  
    16.    <context:component-scan base-package="com.lin.controller" use-default-filters="false">  
    17.         <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>  
    18.         <context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>  
    19.     </context:component-scan>  
    20.      
    21.      
    22.        <!-- 会自动注册了validator  ConversionService  -->  
    23.     <mvc:annotation-driven validator="validator" conversion-service="conversionService" content-negotiation-manager="contentNegotiationManager">  
    24.         <mvc:message-converters register-defaults="true">  
    25.             <!-- StringHttpMessageConverter编码为UTF-8,防止乱码 -->  
    26.             <bean class="org.springframework.http.converter.StringHttpMessageConverter">  
    27.                 <constructor-arg value="UTF-8"/>  
    28.                 <property name = "supportedMediaTypes">  
    29.                     <list>  
    30.                         <bean class="org.springframework.http.MediaType">  
    31.                             <constructor-arg index="0" value="text"/>  
    32.                             <constructor-arg index="1" value="plain"/>  
    33.                             <constructor-arg index="2" value="UTF-8"/>  
    34.                         </bean>  
    35.                         <bean class="org.springframework.http.MediaType">  
    36.                             <constructor-arg index="0" value="*"/>  
    37.                             <constructor-arg index="1" value="*"/>  
    38.                             <constructor-arg index="2" value="UTF-8"/>  
    39.                         </bean>  
    40.                     </list>  
    41.                 </property>  
    42.             </bean>  
    43.             <!-- 避免IE执行AJAX时,返回JSON出现下载文件 -->  
    44.             <bean id="fastJsonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">  
    45.                 <property name="supportedMediaTypes">  
    46.                     <list>  
    47.                         <value>application/json;charset=UTF-8</value>  
    48.                     </list>  
    49.                 </property>  
    50.                 <!--<property name="serializerFeature">-->  
    51.                 <!--这个地方加上这个功能吧,能自己配置一些东西,比如时间的格式化,null输出""等等-->  
    52.                 <!--</property>-->  
    53.             </bean>  
    54.         </mvc:message-converters>  
    55.   
    56.         <mvc:argument-resolvers>  
    57.           <bean class="org.springframework.data.web.PageableHandlerMethodArgumentResolver" />  
    58.         </mvc:argument-resolvers>  
    59.     </mvc:annotation-driven>  
    60.   
    61.   
    62.            <!-- 内容协商管理器  -->  
    63.     <!--1、首先检查路径扩展名(如my.pdf);2、其次检查Parameter(如my?format=pdf);3、检查Accept Header-->  
    64.     <bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">  
    65.         <!-- 扩展名至mimeType的映射,即 /user.json => application/json -->  
    66.         <property name="favorPathExtension" value="true"/>  
    67.         <!-- 用于开启 /userinfo/123?format=json 的支持 -->  
    68.         <property name="favorParameter" value="true"/>  
    69.         <property name="parameterName" value="format"/>  
    70.         <!-- 是否忽略Accept Header -->  
    71.         <property name="ignoreAcceptHeader" value="false"/>  
    72.   
    73.         <property name="mediaTypes"<!--扩展名到MIME的映射;favorPathExtension, favorParameter是true时起作用  -->  
    74.             <value>  
    75.                 json=application/json  
    76.                 xml=application/xml  
    77.                 html=text/html  
    78.             </value>  
    79.         </property>  
    80.         <!-- 默认的content type -->  
    81.         <property name="defaultContentType" value="text/html"/>  
    82.     </bean>  
    83.   
    84.   
    85.   
    86.     <!-- 当在web.xml 中   DispatcherServlet使用 <url-pattern>/</url-pattern> 映射时,能映射静态资源 -->  
    87.     <mvc:default-servlet-handler />    
    88.     <!-- 静态资源映射 -->  
    89.     <mvc:resources mapping="/static/**" location="/WEB-INF/static/"/>  
    90.      
    91.   
    92.    <!-- 对模型视图添加前后缀 -->  
    93.      <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"  
    94.       p:prefix="/WEB-INF/view/" p:suffix=".jsp"/>  
    95.         
    96.     <!-- 这里设置静态的资源 -->  
    97. <!--     <mvc:resources location="/static/" mapping="/static/**" /> -->  
    98.   
    99.   
    100. </beans>  


    3、Spirng中也和配置:

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <beans xmlns="http://www.springframework.org/schema/beans"  
    3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
    4.     xmlns:aop="http://www.springframework.org/schema/aop"  
    5.     xsi:schemaLocation="    
    6.            http://www.springframework.org/schema/beans    
    7.            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd    
    8.            http://www.springframework.org/schema/aop    
    9.            http://www.springframework.org/schema/aop/spring-aop-3.0.xsd  
    10.            http://www.springframework.org/schema/context    
    11.            http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
    12.              
    13.              <!-- 以下 validator  ConversionService 在使用 mvc:annotation-driven 会 自动注册-->  
    14.     <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">  
    15.     </bean>  
    16.        
    17.      <!-- 引入jdbc配置文件 -->    
    18.      <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
    19.         <property name="locations">  
    20.             <list>  
    21.                <value>classpath:properties/*.properties</value>  
    22.                 <!--要是有多个配置文件,只需在这里继续添加即可 -->  
    23.             </list>  
    24.         </property>  
    25.     </bean>  
    26.       
    27.       
    28.          <!-- 扫描注解Bean -->  
    29.     <context:component-scan base-package="com.lin.service">  
    30.         <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>  
    31.     </context:component-scan>  
    32.       
    33.     <!-- 激活annotation功能 -->  
    34.     <context:annotation-config />  
    35.     <!-- 激活annotation功能 -->  
    36.     <context:spring-configured />  
    37.     <!-- 注解事务配置 -->  
    38.       
    39.     <!-- 类型转换及数据格式化 -->  
    40.     <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"/>    
    41.   
    42.     <!-- 配置数据源 -->  
    43.     <bean id="dataSource"  
    44.         class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
    45.         <!-- 不使用properties来配置 -->  
    46.         <!-- <property name="driverClassName" value="com.mysql.jdbc.Driver" />   
    47.             <property name="url" value="jdbc:mysql://localhost:3306/learning" />   
    48.             <property name="username" value="root" />   
    49.             <property name="password" value="christmas258@" /> -->  
    50.        <!-- 使用properties来配置 -->  
    51.         <property name="driverClassName">  
    52.             <value>${jdbc_driverClassName}</value>  
    53.         </property>  
    54.         <property name="url">  
    55.             <value>${jdbc_url}</value>  
    56.         </property>  
    57.         <property name="username">  
    58.             <value>${jdbc_username}</value>  
    59.         </property>  
    60.         <property name="password">  
    61.             <value>${jdbc_password}</value>  
    62.         </property>  
    63.     </bean>  
    64.   
    65.     <!-- 自动扫描了所有的XxxxMapper.xml对应的mapper接口文件,这样就不用一个一个手动配置Mpper的映射了,只要Mapper接口类和Mapper映射文件对应起来就可以了。 -->  
    66.     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
    67.         <property name="basePackage"  
    68.             value="com.lin.dao" />  
    69.     </bean>  
    70.   
    71.     <!-- 配置Mybatis的文件 ,mapperLocations配置**Mapper.xml文件位置,configLocation配置mybatis-config文件位置-->  
    72.     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
    73.         <property name="dataSource" ref="dataSource" />  
    74.         <property name="mapperLocations" value="classpath*:com/lin/mapper/**/*.xml"/>    
    75.         <property name="configLocation" value="classpath:mybatis/mybatis-config.xml" />  
    76.         <!-- <property name="typeAliasesPackage" value="com.tiantian.ckeditor.model"   
    77.             /> -->  
    78.     </bean>  
    79.   
    80. </beans>  


    其中validator这个bean需要引用如下:

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <dependency>  
    2.             <groupId>javax.validation</groupId>  
    3.             <artifactId>validation-api</artifactId>  
    4.             <version>1.1.0.Final</version>  
    5.         </dependency>  
    6.   
    7.         <dependency>  
    8.             <groupId>org.hibernate</groupId>  
    9.             <artifactId>hibernate-validator</artifactId>  
    10.             <version>5.0.1.Final</version>  
    11.         </dependency>  


    4、conroller层编写

    [java] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. package com.lin.controller;  
    2.   
    3.   
    4. import java.util.HashMap;  
    5. import java.util.Map;  
    6.   
    7. import javax.annotation.Resource;  
    8.   
    9. import org.slf4j.Logger;  
    10. import org.slf4j.LoggerFactory;  
    11. import org.springframework.data.domain.Pageable;  
    12. import org.springframework.stereotype.Controller;  
    13. import org.springframework.web.bind.annotation.RequestMapping;  
    14. import org.springframework.web.bind.annotation.RequestMethod;  
    15. import org.springframework.web.bind.annotation.ResponseBody;  
    16. import org.springframework.web.servlet.ModelAndView;  
    17.   
    18. import com.github.pagehelper.Page;  
    19. import com.lin.domain.User;  
    20. import com.lin.service.UserService;  
    21. import com.lin.util.PagedResult;  
    22.   
    23. /** 
    24.  * 功能概要:UserController 
    25.  *  
    26.  * @author linbingwen 
    27.  * @since  2015年9月28日  
    28.  */  
    29. @Controller  
    30. public class UserController extends BaseController {  
    31.       
    32.     private Logger logger = LoggerFactory.getLogger(getClass());  
    33.       
    34.     @Resource  
    35.     private UserService userService;  
    36.       
    37.     @RequestMapping("/")    
    38.     public ModelAndView getIndex(){      
    39.         ModelAndView mav = new ModelAndView("index");   
    40.         User user = userService.selectUserById(1);  
    41.         mav.addObject("user", user);   
    42.         return mav;    
    43.     }    
    44.       
    45.     /** 
    46.      * 显示首页 
    47.      * @author linbingwen 
    48.      * @since  2015年10月23日  
    49.      * @return 
    50.      */  
    51.     @RequestMapping("/bootstrapTest1")    
    52.     public String bootStrapTest1(){  
    53.         return "bootstrap/bootstrapTest1";  
    54.     }  
    55.       
    56.     /** 
    57.      * 分页查询用户信息 
    58.      * @author linbingwen 
    59.      * @since  2015年10月23日  
    60.      * @param page 
    61.      * @return 
    62.      */  
    63.     @RequestMapping(value="/list.do", method= RequestMethod.POST)  
    64.     @ResponseBody  
    65.     public String list(Integer pageNumber,Integer pageSize ,String userName) {  
    66.         logger.info("分页查询用户信息列表请求入参:pageNumber{},pageSize{}", pageNumber,pageSize);  
    67.         try {  
    68.             PagedResult<User> pageResult = userService.queryByPage(userName, pageNumber,pageSize);  
    69.             return responseSuccess(pageResult);  
    70.         } catch (Exception e) {  
    71.             return responseFail(e.getMessage());  
    72.         }  
    73.     }  
    74. }  


    5、最后一步就是前台的页面了,这里可以先写页面再来写controller也可以的

    [html] view plain copy
     
     在CODE上查看代码片派生到我的代码片
    1. <%@ page language="java" contentType="text/html; charset=UTF-8"  
    2.     pageEncoding="UTF-8"%>  
    3. <!DOCTYPE html>  
    4. <html lang="en">  
    5. <head>  
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">  
    7. <title>Bootstrap分页实例</title>  
    8. <link href="<%=request.getContextPath()%>/static/js/bootstrap//css/bootstrap.min.css" rel="stylesheet">  
    9. <script src="<%=request.getContextPath()%>/static/js/jQuery/jquery-2.1.4.min.js"></script>  
    10. <script src="<%=request.getContextPath()%>/static/js/bootstrap/js/bootstrap.min.js"></script>  
    11. <script src="<%=request.getContextPath()%>/static/js/bootstrap/js/bootstrap-paginator.min.js"></script>  
    12. <style type="text/css">  
    13. #queryDiv {  
    14.  margin-right: auto;  
    15.  margin-left: auto;  
    16.  600px;  
    17. }  
    18. #textInput {  
    19.  margin-top: 10px;  
    20. }  
    21. #tableResult {  
    22.  margin-right: auto;  
    23.  margin-left: auto;  
    24.  600px;  
    25. }  
    26. td {  
    27.  150px  
    28. }  
    29. </style>  
    30. </head>  
    31. <body>  
    32.     <div id = "queryDiv">  
    33.         <input id = "textInput" type="text" placeholder="请输入用户名" >  
    34.         <button id = "queryButton" class="btn btn-primary" type="button">查询</button>  
    35.     </div>  
    36.     <form id="form1">  
    37.         <table class="table table-bordered" id = 'tableResult'>  
    38.             <caption>查询用户结果</caption>  
    39.             <thead>  
    40.                 <tr>  
    41.                     <th>序号</th>  
    42.                     <th>用户名</th>  
    43.                     <th>密码</th>  
    44.                     <th>用户邮箱</th>  
    45.                 </tr>  
    46.             </thead>  
    47.             <tbody id="tableBody">  
    48.             </tbody>  
    49.         </table>  
    50.         <!-- 底部分页按钮 -->  
    51.         <div id="bottomTab"></div>  
    52.     </form>  
    53.     <script type='text/javascript'>      
    54.         var PAGESIZE = 10;  
    55.         var options = {    
    56.             currentPage: 1,  //当前页数  
    57.             totalPages: 10,  //总页数,这里只是暂时的,后头会根据查出来的条件进行更改  
    58.             size:"normal",    
    59.             alignment:"center",    
    60.             itemTexts: function (type, page, current) {    
    61.                 switch (type) {    
    62.                     case "first":    
    63.                         return "第一页";    
    64.                     case "prev":    
    65.                         return "前一页";    
    66.                     case "next":    
    67.                         return "后一页";    
    68.                     case "last":    
    69.                         return "最后页";    
    70.                     case "page":    
    71.                         return  page;    
    72.                 }                   
    73.             },    
    74.             onPageClicked: function (e, originalEvent, type, page) {    
    75.                 var userName = $("#textInput").val(); //取内容  
    76.                 buildTable(userName,page,PAGESIZE);//默认每页最多10条  
    77.             }    
    78.         }    
    79.   
    80.         //获取当前项目的路径  
    81.         var urlRootContext = (function () {  
    82.             var strPath = window.document.location.pathname;  
    83.             var postPath = strPath.substring(0, strPath.substr(1).indexOf('/') + 1);  
    84.             return postPath;  
    85.         })();  
    86.           
    87.          
    88.         //生成表格  
    89.         function buildTable(userName,pageNumber,pageSize) {  
    90.              var url =  urlRootContext + "/list.do"; //请求的网址  
    91.              var reqParams = {'userName':userName, 'pageNumber':pageNumber,'pageSize':pageSize};//请求数据  
    92.              $(function () {     
    93.                   $.ajax({  
    94.                         type:"POST",  
    95.                         url:url,  
    96.                         data:reqParams,  
    97.                         async:false,  
    98.                         dataType:"json",  
    99.                         success: function(data){  
    100.                             if(data.isError == false) {  
    101.                            // options.totalPages = data.pages;  
    102.                         var newoptions = {    
    103.                         currentPage: 1,  //当前页数  
    104.                         totalPages: data.pages==0?1:data.pages,  //总页数  
    105.                         size:"normal",    
    106.                         alignment:"center",    
    107.                         itemTexts: function (type, page, current) {    
    108.                         switch (type) {    
    109.                             case "first":    
    110.                             return "第一页";    
    111.                             case "prev":    
    112.                             return "前一页";    
    113.                             case "next":    
    114.                             return "后一页";    
    115.                             case "last":    
    116.                             return "最后页";    
    117.                         case "page":    
    118.                         return  page;    
    119.                 }                   
    120.             },    
    121.             onPageClicked: function (e, originalEvent, type, page) {    
    122.                 var userName = $("#textInput").val(); //取内容  
    123.                 buildTable(userName,page,PAGESIZE);//默认每页最多10条  
    124.             }    
    125.          }                           
    126.          $('#bottomTab').bootstrapPaginator("setOptions",newoptions); //重新设置总页面数目  
    127.          var dataList = data.dataList;  
    128.          $("#tableBody").empty();//清空表格内容  
    129.          if (dataList.length > 0 ) {  
    130.              $(dataList).each(function(){//重新生成  
    131.                     $("#tableBody").append('<tr>');  
    132.                     $("#tableBody").append('<td>' + this.userId + '</td>');  
    133.                     $("#tableBody").append('<td>' + this.userName + '</td>');  
    134.                     $("#tableBody").append('<td>' + this.userPassword + '</td>');  
    135.                     $("#tableBody").append('<td>' + this.userEmail + '</td>');  
    136.                     $("#tableBody").append('</tr>');  
    137.                     });    
    138.                     } else {                                  
    139.                           $("#tableBody").append('<tr><th colspan ="4"><center>查询无数据</center></th></tr>');  
    140.                     }  
    141.                     }else{  
    142.                           alert(data.errorMsg);  
    143.                             }  
    144.                       },  
    145.                         error: function(e){  
    146.                            alert("查询失败:" + e);  
    147.                         }  
    148.                     });  
    149.                });  
    150.         }  
    151.           
    152.         //渲染完就执行  
    153.         $(function() {  
    154.               
    155.             //生成底部分页栏  
    156.             $('#bottomTab').bootstrapPaginator(options);       
    157.               
    158.             buildTable("",1,10);//默认空白查全部  
    159.               
    160.             //创建结算规则  
    161.             $("#queryButton").bind("click",function(){  
    162.                 var userName = $("#textInput").val();     
    163.                 buildTable(userName,1,PAGESIZE);  
    164.             });  
    165.         });  
    166.     </script>  
    167. </body>  
    168. </html>  

    注意引入的js文件,bootstrap-paginator需要引用bootstrap和jquery

    6、最终运行结果

    最后以web工程运行就可以了:

    结果如下:

    打印出来的一些日志:

    后台返回给前台的就是json

    整个工程下载(旧版本)

    新版本下载:https://github.com/appleappleapple/ssm_project (日志打印使用logback,数据库配置放在POM.XML)博主推荐使用新版本,而且这里详细说明了整个工程应用的框架,数据源配置,SQL语句等等!

    重要的事情说三遍:请下新版本~请下新版本~请下新版本~

    from: http://blog.csdn.net/evankaka/article/details/49452201

  • 相关阅读:
    剑指Offer——矩形覆盖
    剑指Offer——变态跳台阶
    ASCII table and description .
    字符编解码的故事(ASCII,ANSI,Unicode,Utf-8区别) .
    tchar 输入输出类 和 string 类 函数简单说明 总结各种前缀后缀
    各种 C++编译器的性能对比
    怎样写参数个数可变的宏 Debug宏 Log宏等
    C语言中的可变参数函数 三个点“…”printf( const char* format, ...)
    常用C语言字符串操作函数
    Multi-Byte Character Set &amp; Use Unicode Character Set .
  • 原文地址:https://www.cnblogs.com/GarfieldEr007/p/5746245.html
Copyright © 2020-2023  润新知