整合DataTables到JavaWeb(SSH)实例总结分析

本教程详细介绍了如何在SSH(Struts2、Hibernate、Spring)框架的JavaWeb项目中整合Datatables,实现数据的增删查改及分页。通过服务器处理模式(Server-side processing)和Ajax,数据以Json格式在后台与前端之间交换。项目涉及的主要技术包括Ajax、Json、Bootstrap、jQuery等,提供完整步骤和关键代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

整合DataTables到JavaWeb(SSH)实例总结分析

一、项目介绍
    本项目在基础的SSH框架上,利用Datatables控件实现对数据库中数据的基本增删查改及分页。主要采用Datatables的服务器处理模式(Server-side processing),并通过Ajax将数据封装成Json后实现前后台数据的交换。
    图片展示:下面展示登陆界面和学生信息管理界面,注册以及找回密码界面在此不展示。

图1.1 登陆界面


图1.2 学生信息界面

二、开发环境及准备
1、开发环境:JDK7、MyEclipse10、Tomcat7、MySQL5.0
2、开发要求:SSH、Ajax、Json、Datatables、Bootstrap、JavaScript、jQuery···
Tips:学习本文之前可先学习“SSH框架搭建”(链接:http://note.youdao.com/share/?id=28ea97b9884156a5e040caf98338bc21&type=note),以及“Ajax+Json+Struts2+jQuery实例总结分析”,理解Json数据是如何通过Ajax以及Struts实现前后台的传递。(链接:http://note.youdao.com/share/?id=e5e3a1e2efa73254c3243fb69f83f027&type=note

三、项目思路分析
    本项目是在基础的SSH框架整合实例基础上,整合Datatables控件到JavaWeb项目中,实现对数据库中数据的基本增删查改及分页。
思路及设计流程:
1、将数据库中的数据封装成Json格式,并通过struts正确传送到前台;
关键点:(1)如何正确有效的将后台数据封装成Json格式:将后台数据封装成Json格式有多种方法, 如写函数将数据拼接成json格式、或利用gson或者org.json的方法。本项目中采用gson的 toJson()方法。
     (2)在于如何配置struts.xml,实现JSP页面与控制层Json数据的正确传递。
2、将传送到前台的Json格式数据利用Datatables显示出来;
关键点:服务器处理Ajax源数据时,程序设计中必须按照API要求的发送参数及返回参数进行设置处理。
3、实现增、删、改基本功能;
关键点:掌握jQuery中$.ajax()方法的使用
4、实现查询及分页;
关键点:(1)实现查询以及分页各需要服务器返回什么参数(主要看官网文档);
        (2)Hibernate如何实现原生sql查询。本项目中,在DAO层先获取session对象,然后执行session的createSQLQuery(sql)方法。
5、项目优化。

四、实例讲解
    这部分将分层给出详细的讲解并给出部分核心代码。
1、model层:编写实体模型及配置映射文件。以Students实体为例。
(1)编写实体Students.java。
package com.ssh.model;

/**
 *
 * @author 杜航
 * @function:Students entity.
 *
 */

public class Students implements java.io.Serializable {

 /** Fields */

 /**
  *
  */
 private static final long serialVersionUID = 1L;
 private Integer id;
 private String username;
 private String gender;
 private String age;
 private String degree;
 private String remark;

 /** Constructors */
 /** default constructor */
 public Students() {
 }

 /** full constructor */
 public Students(Integer id, String username, String gender, String age,
   String degree, String remark) {
  this.id = id;
  this.username = username;
  this.gender = gender;
  this.age = age;
  this.degree = degree;
  this.remark = remark;
 }

 /** Property accessors */
 public Integer getId() {
  return id;
 }

 public void setId(Integer id) {
  this.id = id;
 }

 public String getUsername() {
  return username;
 }

 public void setUsername(String username) {
  this.username = username;
 }

 public String getGender() {
  return gender;
 }

 public void setGender(String gender) {
  this.gender = gender;
 }

 public String getAge() {
  return age;
 }

 public void setAge(String age) {
  this.age = age;
 }

 public String getDegree() {
  return degree;
 }

 public void setDegree(String degree) {
  this.degree = degree;
 }

 public String getRemark() {
  return remark;
 }

 public void setRemark(String remark) {
  this.remark = remark;
 }

}

(2)配置映射文件Students.hbm.xml。(如果采用Hibernate反向工程,则不需要配置映射文档)
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- 
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="com.ssh.model.Students" table="students" catalog="sshexample">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="increment"></generator>
        </id>
        <property name="username" type="java.lang.String">
            <column name="username" length="20" not-null="true" unique="true" />
        </property>
        <property name="gender" type="java.lang.String">
            <column name="gender" length="20" not-null="true" />
        </property>
        <property name="age" type="java.lang.String">
            <column name="age" length="3" not-null="true" />
        </property>
        <property name="degree" type="java.lang.String">
            <column name="degree" length="20" not-null="true" />
        </property>
        <property name="remark" type="java.lang.String">
            <column name="remark" length="20" not-null="true" />
        </property>
    </class>
</hibernate-mapping>

2、DAO层:编写Hibernate操作数据库接口并实现其对应类。
(1)编写接口IStudentsDAO.java。
    由于实现查询和分页时,默认生成的DAO层的方法已无法达到要求,故而在原始的SSH框架实例的基础上,在DAO层新增excuteSQL()方法,以在Hibernate中执行原生的sql语句,sql语句的封装以及执行在Web层。
package com.ssh.dao;
import java.util.List;
import com.ssh.model.Students;
public interface IStudentsDAO {
 // property constants
 public static final String USERNAME = "username";
 public static final String GENDER = "gender";
 public static final String AGE = "age";
 public static final String DEGREE = "degree";
 public static final String REMARK = "remark";
 public abstract void save(Students transientInstance);
 public abstract void delete(Students persistentInstance);
 public abstract Students findById(java.lang.Integer id);
 public abstract List findByExample(Students instance);
 public abstract List findByProperty(String propertyName, Object value);
 public abstract List findByUsername(Object username);
 public abstract List findByGender(Object gender);
 public abstract List findByAge(Object age);
 public abstract List findByDegree(Object degree);
 public abstract List findByRemark(Object remark);
 public abstract List findAll();
 public abstract Students merge(Students detachedInstance);
 public abstract void attachDirty(Students instance);
 public abstract void attachClean(Students instance);
 /**
  * Hibernate执行sql语句
  */
 public List excuteSQL(String sql);
}

(2)实现接口StudentsDAO.java。
    实现接口中的excuteSQL()方法,首先要理解如何获得session,然后要区分createSQLQuery()与createQuery()方法的区别,以及对其返回结果的正确处理。
package com.ssh.dao;

import java.util.ArrayList;
import java.util.List;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.ssh.model.Students;

/**
 * 
 * @author 杜航
 * @function:学生接口实现类
 * 
 */

public class StudentsDAO extends HibernateDaoSupport implements IStudentsDAO {
 private static final Logger log = LoggerFactory.getLogger(StudentsDAO.class);

 protected void initDao() {
 }

 /*
  * 杜航 
  * 功能:保存Students对象
  */
 @Override
 public void save(Students transientInstance) {
  log.debug("saving Students instance");
  try {
   getHibernateTemplate().save(transientInstance);
   log.debug("save successful");
  } catch (RuntimeException re) {
   log.error("save failed", re);
   throw re;
  }
 }

 /*
  * 杜航 
  * 功能:删除Students对象
  */
 @Override
 public void delete(Students persistentInstance) {
  log.debug("deleting Students instance");
  try {
   getHibernateTemplate().delete(persistentInstance);
   log.debug("delete successful");
  } catch (RuntimeException re) {
   log.error("delete failed", re);
   throw re;
  }
 }

 /*
  * 杜航 
  * 功能:根据Id属性,查找Students对象
  */
 @Override
 public Students findById(java.lang.Integer id) {
  log.debug("getting Students instance with id: " + id);
  try {
   Students instance = (Students) getHibernateTemplate().get(
     "com.ssh.model.Students", id);
   return instance;
  } catch (RuntimeException re) {
   log.error("get failed", re);
   throw re;
  }
 }

 /*
  * 杜航 
  * 功能:根据属性,查找Students对象
  */
 @Override
 public List findByExample(Students instance) {
  log.debug("finding Students instance by example");
  try {
   List results = getHibernateTemplate().findByExample(instance);
   log.debug("find by example successful, result size: "
     + results.size());
   return results;
  } catch (RuntimeException re) {
   log.error("find by example failed", re);
   throw re;
  }
 }

 /*
  * 杜航 
  * 功能:根据Example,查找Students对象
  */
 @Override
 public List findByProperty(String propertyName, Object value) {
  log.debug("finding Students instance with property: " + propertyName
    + ", value: " + value);
  try {
   String queryString = "from Students as model where model."
     + propertyName + "= ?";
   return getHibernateTemplate().find(queryString, value);
  } catch (RuntimeException re) {
   log.error("find by property name failed", re);
   throw re;
  }
 }

 /*
  * 杜航 
  * 功能:根据username属性,查找Students对象
  */
 @Override
 public List findByUsername(Object username) {
  return findByProperty(USERNAME, username);
 }

 /*
  * 杜航 
  * 功能:根据gender属性,查找Students对象
  */
 @Override
 public List findByGender(Object gender) {
  return findByProperty(GENDER, gender);
 }

 /*
  * 杜航 
  * 功能:根据age属性,查找Students对象
  */
 @Override
 public List findByAge(Object age) {
  return findByProperty(AGE, age);
 }

 /*
  * 杜航 
  * 功能:根据degree属性,查找Students对象
  */
 @Override
 public List findByDegree(Object degree) {
  return findByProperty(DEGREE, degree);
 }

 /*
  * 杜航 
  * 功能:根据remark属性,查找Students对象
  */
 @Override
 public List findByRemark(Object remark) {
  return findByProperty(REMARK, remark);
 }

 /*
  * 杜航 
  * 功能:查找所有的Students对象
  */
 @Override
 public List findAll() {
  log.debug("finding all Students instances");
  try {
   String queryString = "from Students";
   return getHibernateTemplate().find(queryString);
  } catch (RuntimeException re) {
   log.error("find all failed", re);
   throw re;
  }
 }

 /*
  * 杜航 
  * 功能:将传入的detached(分离的)状态的Students对象的属性复制到持久化对象中,并返回该持久化对象
  * 如果该session中没有关联的持久化对象,加载一个,如果传入对象未保存,保存一个副本并作为持久对象返回,传入对象依然保持detached状态。
  */
 @Override
 public Students merge(Students detachedInstance) {
  log.debug("merging Students instance");
  try {
   Students result = (Students) getHibernateTemplate().merge(
     detachedInstance);
   log.debug("merge successful");
   return result;
  } catch (RuntimeException re) {
   log.error("merge failed", re);
   throw re;
  }
 }

 /*
  * 杜航 
  * 功能:将Students对象持久化并保存
  * 如果对象未保存(Transient状态),调用save方法保存。如果对象已保存(Detached状态
  * ),调用update方法将对象与Session重新关联
  */
 @Override
 public void attachDirty(Students instance) {
  log.debug("attaching dirty Students instance");
  try {
   getHibernateTemplate().saveOrUpdate(instance);
   log.debug("attach successful");
  } catch (RuntimeException re) {
   log.error("attach failed", re);
   throw re;
  }
 }

 /*
  * 杜航 
  * 功能:将传入的Students对象设置为transient(暂时的)状态
  */
 @Override
 public void attachClean(Students instance) {
  log.debug("attaching clean Students instance");
  try {
   getHibernateTemplate().lock(instance, LockMode.NONE);
   log.debug("attach successful");
  } catch (RuntimeException re) {
   log.error("attach failed", re);
   throw re;
  }
 }

 /*
  * 杜航 
  * 功能:得到StudentsDAO上下文对象
  */
 public static IStudentsDAO getFromApplicationContext(ApplicationContext ctx) {
  return (IStudentsDAO) ctx.getBean("StudentsDAO");
 }

 /*
  * 杜航 
  * 功能:Hibernate执行sql语句
  */
 @Override
 public List excuteSQL(String sql) {

  List list = new ArrayList();
  Query query = getSession().createSQLQuery(sql);
  list = (List) query.list();
  
  return list;
 }

}

3、Service层:编写业务逻辑接口并实现其对应类。
(1)编写接口IStudentsService.java。
   新增excuteSQL()方法,供Web层调用。
package com.ssh.service;
import java.util.List;
import com.ssh.model.Students;
public interface IStudentsService {
 public List<Students> findAll();
 public Students findByName(String uname);
 public void addStudents(Students u);
 public void delStudents(Students u);
 public void updateStudents(Students u);
 public List excuteSQL(String sql);
}

(2)实现接口StudentsService.java。
    通过调用DAO层的excuteSQL()方法来实现Service层的excuteSQL()方法。
package com.ssh.service;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ssh.dao.IStudentsDAO;
import com.ssh.model.Students;
public class StudentsService implements IStudentsService {
 private static final Logger log = LoggerFactory.getLogger(StudentsService.class);
 private IStudentsDAO studentsDAO = null;
 /*
  * 杜航
  * 功能:保存Students对象
  */
 @Override
 public void addStudents(Students u) {
  studentsDAO.save(u);
 }
 /*
  * 杜航
  * 功能:删除Students对象
  */
 @Override
 public void delStudents(Students u) {
  studentsDAO.delete(u);
 }
 /*
  * 杜航
  * 功能:查找所有的Students对象
  */
 @Override
 public List<Students> findAll() {
  return studentsDAO.findAll();
 }
 /*
  * 杜航
  * 功能:根据uname属性,查找Students对象
  */
 @Override
 public Students findByName(String uname) {
  List<Students> list = studentsDAO.findByUsername(uname);
  if (list == null) {
   return null;
  }
  return list.get(0);
 }
 /*
  * 杜航
  * 功能:更新Students对象
  */
 @Override
 public void updateStudents(Students u) {
  studentsDAO.attachDirty(u);
 }
 /*
  * 杜航
  * 功能:Hibernate执行sql语句
  */
 @Override
 public List excuteSQL(String sql) {
  return studentsDAO.excuteSQL(sql);
 }
 public void setStudentsDAO(IStudentsDAO studentsDAO) {
  this.studentsDAO = studentsDAO;
 }
 public IStudentsDAO getStudentsDAO() {
  return studentsDAO;
 }
}

4、Web层:编写用户控制类StudentsAction.java。
    编写用户控制主要难点在于:(1)如何封装sql语句;(2)如何将后台数据正确封装成Json格式;(3)如何对createSQLQuery().list()返回的数据库数据进行恰当的处理。
package com.ssh.web;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.ssh.model.Students;
import org.apache.struts2.ServletActionContext;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.ssh.service.IStudentsService;
import com.google.gson.Gson;
import com.opensymphony.xwork2.ActionSupport;
public class StudentsAction extends ActionSupport { 
 /**
  *
  */
 private static final long serialVersionUID = 1L;
 private static final Logger log = LoggerFactory
   .getLogger(StudentsAction.class);
 private Students u = new Students();
 private List<Students> studentList = new ArrayList<Students>();
 private List list = null;
 private static IStudentsService studentsService = null;
 private String name;
 private Integer id;
 private String username;
 private String gender;
 private String age;
 private String degree;
 private String remark;
 /**
  * 服务器模式中不返回的4个参数:draw recordsTotal recordsFiltered data
  */
 private String draw = "0"; // 总共记录数
 private String recordsTotal; // 过滤后记录数
 private String recordsFiltered; // 表中中需要显示的数据
 private List<Students> data; // 请求次数
 private String start; // 数据起始位置
 private String length; // 数据长度
 private String orderDir = "asc"; // 获取排序方式 默认为asc
 private String[] cols = { "id", "username", "gender", "age", "degree",
   "remark" };// 定义列名
 private String orderColumn = "0"; // 获取客户端需要那一列排序
 private String searchValue; // 获取用户过滤框里的字符
 private String table = "sshexample.students";// 所要查询的表名 注意加上数据库的名字
 
 /*
  * 杜航
  * 功能:根据上下文获得studentsService对象
  */
 public IStudentsService getStudentsService() {
  if (studentsService == null) {
   ServletContext sc = ServletActionContext.getServletContext();
   ApplicationContext ac = WebApplicationContextUtils
     .getRequiredWebApplicationContext(sc);
   studentsService = (IStudentsService) ac.getBean("StudentsService");
   if (studentsService == null)
    System.out.println("error");
  }
  return studentsService;
 }
 /*
  * 杜航
  * 功能:添加学生信息
  */
 public String addStudent() throws Exception {
  try {
   getStudentsService().addStudents(u);
  } catch (Exception e) {
   e.printStackTrace();
   log.error("增添学生错误", e);
   return ERROR;
  }
  return SUCCESS;
 }
 /*
  * 杜航
  * 功能:删除学生信息
  */
 public String delStudent() throws Exception {
  try {
   u.setUsername("");
   getStudentsService().delStudents(u);
  } catch (Exception e) {
   log.error("删除学生错误", e);
   return ERROR;
  }
  return SUCCESS;
 }
 /*
  * 杜航
  * 功能:编辑学生信息
  */
 public String editStudent() throws Exception {
  if (u == null) {
   System.out.println("null");
  }
  try {
   getStudentsService().updateStudents(u);
  } catch (Exception e) {
   log.error("编辑学生信息错误", e);
   return ERROR;
  }
  return SUCCESS;
 }
 /*
  * 杜航
  * 功能:列表显示学生信息
  */
 public String listStudent() throws Exception {
  studentList = getStudentsService().findAll();
  //将用户信息打印在控制台上
  for (Students student : studentList) {
   System.out.print(student.getId() + "\t");
   System.out.print(student.getUsername() + "\t");
   System.out.print(student.getGender() + "\t");
   System.out.print(student.getAge() + "\t");
   System.out.print(student.getDegree() + "\t");
   System.out.println(student.getRemark());
  }
  return SUCCESS;
 }
 /** 前后台实现Json数据传递 */
 /*
  * 杜航
  * 功能:获得所有学生的信息
  */
 public void getAllStudent() throws NumberFormatException, SQLException {
  HttpServletRequest request = ServletActionContext.getRequest();
  draw = request.getParameter("draw");
  start = request.getParameter("start");
  length = request.getParameter("length");
  orderColumn = request.getParameter("order[0][column]");
  orderColumn = cols[Integer.parseInt(orderColumn)];
  orderDir = request.getParameter("order[0][dir]");
  searchValue = request.getParameter("search[value]");
  // 解决request请求返回时中文乱码
  try {
   searchValue = new String(searchValue.getBytes("ISO-8859-1"),
     "utf-8");
  } catch (UnsupportedEncodingException e1) {
   // TODO Auto-generated catch block
   e1.printStackTrace();
  }
  System.out.println("Datatables服务器处理请求的数据:");
  // 打印请求回来的数据
  System.out.print("\t" + "draw:" + draw + "\t" + "start:" + start + "\t"
    + "length:" + length + "\t" + "orderColumn:" + orderColumn
    + "\t" + "orderDir:" + orderDir + "\t");
  // 打印查询框的内容
  System.out.println("searchValue:" + searchValue);
  List<String> sArray = new ArrayList<String>();
  if (!searchValue.equals("")) {
   sArray.add(" id like '%" + searchValue + "%'");
   sArray.add(" username like '%" + searchValue + "%'");
   sArray.add(" gender like '%" + searchValue + "%'");
   sArray.add(" age like '%" + searchValue + "%'");
   sArray.add(" degree like '%" + searchValue + "%'");
   sArray.add(" remark like '%" + searchValue + "%'");
  }
  String individualSearch = ""; // 个别查询
  if (sArray.size() == 1) {
   individualSearch = sArray.get(0);
  } else if (sArray.size() > 1) {
   for (int i = 0; i < sArray.size() - 1; i++) {
    individualSearch += sArray.get(i) + " or ";
   }
   individualSearch += sArray.get(sArray.size() - 1);
  }
  List<Students> students = new ArrayList<Students>();
  String recordsFilteredSql = "select count(1) as recordsFiltered from "
    + table;
  // 获取数据库总记录数
  String recordsTotalSql = "select count(1) as recordsTotal from "
    + table;
  list = studentsService.excuteSQL(recordsTotalSql);
  recordsTotal = String.valueOf(list.size());
//	System.out.println("总记录数:" + recordsTotal);
  String searchSQL = "";
  String sql = "SELECT * FROM " + table;
  if (individualSearch != "") {
   searchSQL = " where " + individualSearch;
  }
  sql += searchSQL;
  recordsFilteredSql += searchSQL;
  sql += " order by " + orderColumn + " " + orderDir;
  recordsFilteredSql += " order by " + orderColumn + " " + orderDir;
  sql += " limit " + start + ", " + length; // 用来分页
 
  list = studentsService.excuteSQL(sql);
  // 取出list的每条记录的每个数据项,存放在数组objects中
  for (int i = 0; i < list.size(); i++) {
   Object[] objects = (Object[]) list.get(i);
   // 打印记录
//	for (int j = 0; j < objects.length; j++) {
//	System.out.print(objects[j] + "\t");
//	}
//	System.out.println("");
   students.add(new Students(Integer.parseInt(objects[0].toString()),
     objects[1].toString(), objects[2].toString(), objects[3]
       .toString(), objects[4].toString(), objects[5]
       .toString()));
  }
  if (searchValue != "") {
   list = studentsService.excuteSQL(recordsFilteredSql);
   recordsFilteredSql = String.valueOf(list.size());
  } else {
   recordsFiltered = recordsTotal;
  }
//	System.out.println("过滤后记录数:" + recordsFiltered);
 
  HttpServletResponse response = ServletActionContext.getResponse();
  response.setContentType("text/json");
  response.setCharacterEncoding("UTF-8");
  PrintWriter out = null;
  try {
   out = response.getWriter();
  } catch (IOException e) {
   e.printStackTrace();
  }
  Map<Object, Object> info = new HashMap<Object, Object>();
  info.put("data", students);
  info.put("recordsTotal", recordsTotal);
  info.put("recordsFiltered", recordsFiltered);
  info.put("draw", draw);
  String json = new Gson().toJson(info);
  out.println(json);
  out.flush();
  out.close();
 }
 /*
  * 杜航
  * 功能:增添学生信息
  */
 public void addStudentJson() throws Exception {
  Students student = new Students();
  // 解决中文乱码问题
  username = new String(username.getBytes("ISO-8859-1"), "UTF-8");
  gender = new String(gender.getBytes("ISO-8859-1"), "UTF-8");
  age = new String(age.getBytes("ISO-8859-1"), "UTF-8");
  degree = new String(degree.getBytes("ISO-8859-1"), "UTF-8");
  remark = new String(remark.getBytes("ISO-8859-1"), "UTF-8");
  student.setUsername(username);
  student.setGender(gender);
  student.setAge(age);
  student.setDegree(degree);
  student.setRemark(remark);
  System.out.println("新用户:" + username + "\t" + "性别:" + gender);
  studentsService.addStudents(student);
  JSONObject json = new JSONObject();
  json.put("status", "success");
  HttpServletResponse response = ServletActionContext.getResponse();
  response.setContentType("text/json");
  response.setCharacterEncoding("UTF-8");
  PrintWriter out = null;
  try {
   out = response.getWriter();
  } catch (IOException e) {
   e.printStackTrace();
  }
  out.println(json);
  System.out.println("json数据:" + json);
  out.flush();
  out.close();
 }
 /*
  * 杜航
  * 功能:删除学生信息
  */
 public void delStudentJson() throws Exception {
  Students student = new Students();
  student.setId(id);
  System.out.println("选中的ID:" + id);
  student.setUsername("");
  student.setGender("");
  student.setAge("");
  student.setDegree("");
  student.setRemark("");
  studentsService.delStudents(student);
  JSONObject json = new JSONObject();
  json.put("status", "success");
  HttpServletResponse response = ServletActionContext.getResponse();
  response.setContentType("text/json");
  response.setCharacterEncoding("UTF-8");
  PrintWriter out = null;
  try {
   out = response.getWriter();
  } catch (IOException e) {
   e.printStackTrace();
  }
  out.println(json);
  System.out.println("json数据:" + json);
  out.flush();
  out.close();
 }
 /*
  * 杜航
  * 功能:编辑学生信息
  */
 public void editStudentJson() throws Exception {
  Students student = new Students();
  // 解决中文乱码问题
  username = new String(username.getBytes("ISO-8859-1"), "UTF-8");
  gender = new String(gender.getBytes("ISO-8859-1"), "UTF-8");
  age = new String(age.getBytes("ISO-8859-1"), "UTF-8");
  degree = new String(degree.getBytes("ISO-8859-1"), "UTF-8");
  remark = new String(remark.getBytes("ISO-8859-1"), "UTF-8");
  student.setId(id);
  student.setUsername(username);
  student.setGender(gender);
  student.setAge(age);
  student.setDegree(degree);
  student.setRemark(remark);
  studentsService.updateStudents(student);
  JSONObject json = new JSONObject();
  json.put("status", "success");
  HttpServletResponse response = ServletActionContext.getResponse();
  response.setContentType("text/json");
  response.setCharacterEncoding("UTF-8");
  PrintWriter out = null;
  try {
   out = response.getWriter();
  } catch (IOException e) {
   e.printStackTrace();
  }
  out.println(json);
  System.out.println("json数据:" + json);
  out.flush();
  out.close();
 }
 /*
  * 杜航
  * 功能:获得studentsService对象
  */
 public void setStudentsService(IStudentsService studentsService) {
  this.studentsService = studentsService;
 }
 public Students getU() {
  return u;
 }
 public void setU(Students u) {
  this.u = u;
 }
 public List<Students> getStudentList() {
  return studentList;
 }
 public void setStudentList(List<Students> studentList) {
  this.studentList = studentList;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getName() {
  return this.name;
 }
 public Integer getId() {
  return id;
 }
 public void setId(Integer id) {
  this.id = id;
 }
 public String getUsername() {
  return username;
 }
 public void setUsername(String username) {
  this.username = username;
 }
 public String getGender() {
  return gender;
 }
 public void setGender(String gender) {
  this.gender = gender;
 }
 public String getAge() {
  return age;
 }
 public void setAge(String age) {
  this.age = age;
 }
 public String getDegree() {
  return degree;
 }
 public void setDegree(String degree) {
  this.degree = degree;
 }
 public String getRemark() {
  return remark;
 }
 public void setRemark(String remark) {
  this.remark = remark;
 }
 public String getDraw() {
  return draw;
 }
 public void setDraw(String draw) {
  this.draw = draw;
 }
 public String getRecordsTotal() {
  return recordsTotal;
 }
 public void setRecordsTotal(String recordsTotal) {
  this.recordsTotal = recordsTotal;
 }
 public String getRecordsFiltered() {
  return recordsFiltered;
 }
 public void setRecordsFiltered(String recordsFiltered) {
  this.recordsFiltered = recordsFiltered;
 }
 public List<Students> getData() {
  return data;
 }
 public void setData(List<Students> data) {
  this.data = data;
 }
 public String getStart() {
  return start;
 }
 public void setStart(String start) {
  this.start = start;
 }
 public String getLength() {
  return length;
 }
 public void setLength(String length) {
  this.length = length;
 }
 public String getOrderDir() {
  return orderDir;
 }
 public void setOrderDir(String orderDir) {
  this.orderDir = orderDir;
 }
 public String[] getCols() {
  return cols;
 }
 public void setCols(String[] cols) {
  this.cols = cols;
 }
 public String getOrderColumn() {
  return orderColumn;
 }
 public void setOrderColumn(String orderColumn) {
  this.orderColumn = orderColumn;
 }
 public String getSearchValue() {
  return searchValue;
 }
 public void setSearchValue(String searchValue) {
  this.searchValue = searchValue;
 }
}

5、编写JSP页面。这里以studentIndex.jsp为例。
    本部分的重点在于:(1)Datatables如何进行服务器处理;(2)如何封装前台数据成Json格式。
<%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8"%>

<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<link rel=stylesheet type=text/css href="css/studentIndex.css">
<title>管理学生信息(增、删、查、改、分页)</title>

<!-- CDN -->
<!-- DataTables CSS -->
<!-- 
<link rel="stylesheet" type="text/css"
href="http://cdn.datatables.net/1.10.7/css/jquery.dataTables.css">
 -->
<!-- jQuery -->
<!-- 
<script type="text/javascript" charset="utf8"
src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
 -->
<!-- DataTables -->
<!-- 
<script type="text/javascript" charset="utf8"
src="http://cdn.datatables.net/1.10.7/js/jquery.dataTables.js"></script>
 -->

<!-- 本地 -->
<!-- DataTables CSS -->
<link rel="stylesheet" type="text/css" href="css/jquery.dataTables.css">

<!-- jQuery -->
<script type="text/javascript" charset="utf8" src="js/jquery.js"></script>

<!-- DataTables JS -->
<script type="text/javascript" charset="utf8"
src="js/jquery.dataTables.js"></script>


<!-- Bootstrap CSS -->

<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">

<!-- jQuery -->
<!--添加该js会出问题:Uncaught TypeError: Object [object Object] has no method 'DataTable'
<script type="text/javascript"charset="utf8"src="js/jquery-1.11.3.min.js"></script>
 -->
<!-- Bootstrap JS -->

<script type="text/javascript" charset="utf8" src="js/bootstrap.min.js"></script>



<style type="text/css">
#myModal {
margin: auto auto;
}
</style>

</head>
<body>
<div class="myTitle" align="center">
<h1>Duang学堂教育信息管理系统</h1>
</div>
<div class="container table-responsive">
<!-- class="table-responsive":设置响应式设计 -->
<table id="example" class="table table-striped table-bordered">
<thead>
<tr>
<th>ID</th>
<th>姓名</th>
<th>性别</th>
<th>年龄</th>
<th>学历</th>
<th>备注</th>
</tr>
</thead>
<tbody>

</tbody>
<!-- tbody是必须的 -->
</table>
</div>
<div id="myModal" class="modal fade" tabindex="-1" role="dialog"
aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title" id="myModalLabel">新增</h4>
</div>
<div id="modal-body" align="center">
<div class="form-group">
<input type="text" class="form-control" id="username"
name="u.username" placeholder="姓名">
</div>
<div class="form-group">
<input type="text" class="form-control" id="gender"
name="u.gender" placeholder="性别">
</div>
<div class="form-group">
<input type="text" class="form-control" id="age" name="u.age"
placeholder="年龄">
</div>
<div class="form-group">
<input type="text" class="form-control" id="degree"
name="u.degree" placeholder="学历">
</div>
<div class="form-group">
<input type="text" class="form-control" id="remark"
name="u.remark" placeholder="备注">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-info" id="addInitData"
οnclick="addInitData()">添加模拟数据</button>
<button type="button" class="btn btn-default" id="clearData"
οnclick="clearData()">清空</button>
<button type="button" class="btn btn-primary" id="save"
οnclick="save()">保存</button>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

<script type="text/javascript">
var table;
var url;
var selectedId,selectedUsername,selectedGender,selectedAge,selectedDegree,selectedRemark;
$(document).ready(function() {
table = $('#example').DataTable({
"processing": true,
        "serverSide": true,
        "ajax": {
              "url": "getAllStudent.action",
              "type": "get"
         },
        "columns": [
            { "data": "id" },
            { "data": "username" },
            { "data": "gender" },
            { "data": "age" },
            { "data": "degree" },
            { "data": "remark" }
        ],
        "language": {	//语言国际化
                "lengthMenu": "_MENU_ 条记录每页",	//'每页显示记录'的下拉框的提示信息
                "zeroRecords": "没有找到记录",	//当搜索结果为空时,显示的信息
                "info": "第 _PAGE_ 页 ( 总共 _PAGES_ 页 )",	//表格的page分页所需显示的所有字符串
                "infoEmpty": "无记录",	//当表格没有数据时,汇总地方显示的字符串
                "infoFiltered": "(从 _MAX_ 条记录过滤)",	//当表格搜索后,在汇总字符串上需要增加的内容
                "paginate": {	//分页信息显示所需的字符串的所有信息
                    "previous": "上一页",	//分页信息的 'previous' 按钮显示的信息
                    "next": "下一页"	//分页信息的 'next' 按钮显示的信息
                }
            },
            "dom": "<'row'<'col-xs-2'l><'#mytool.col-xs-4'><'col-xs-6'f>r>" +	//通过一个自定义的字符串来定义DataTables里面所有组件的显示,位置和显隐.
                    "t" +
                    "<'row'<'col-xs-6'i><'col-xs-6'p>>",
            initComplete: function () {//初始化结束后的回调函数
                $("#mytool").append('<button type="button" class="btn btn-primary btn-sm" data-toggle="modal" οnclick="addData()" >添加</button> ');
                $("#mytool").append('<button type="button" class="btn btn-success btn-sm" data-toggle="modal" οnclick="delData()" >删除</button> ');
                $("#mytool").append('<button type="button" class="btn btn-info btn-sm" data-toggle="modal" οnclick="editData()">修改</button> ');
            }
});

//选中行,然后返回其id
$('#example tbody').on( 'click', 'tr', function () {
        if ( $(this).hasClass('selected') ) {
            $(this).removeClass('selected');
        }
        else {
            table.$('tr.selected').removeClass('selected');
            $(this).addClass('selected');
        }
selectedId = table.row('.selected').data().id;
selectedUsername = table.row('.selected').data().username;
selectedGender = table.row('.selected').data().gender;
selectedAge = table.row('.selected').data().age;
selectedDegree = table.row('.selected').data().degree;
selectedRemark = table.row('.selected').data().remark;
console.log("选中行的id:"+ selectedId);
$("#username").val(selectedUsername);
//setRadioBoxByValue("u.gender",selectedGender);
$("#gender").val(selectedGender);
$("#age").val(selectedAge);
$("#degree").val(selectedDegree);
$("#remark").val(selectedRemark);
     } );

});

/**
     * 添加模拟数据
     */
    function addInitData() {
        $("#username").val("Inputting");
$("#gender").val("男");
$("#age").val("18");
$("#degree").val("高中");
$("#remark").val("( ^_^ )/~~拜拜");
$("#myModal").modal("show");
    }

/**
     * 清除
     */
    function clearData() {
        $("#username").val("");
$("#gender").val("");
$("#age").val("");
$("#degree").val("");
$("#remark").val("");
$("#myModal").modal("show");
    }
    
    /**
     * 保存
     */
    function save() {
     if(checkData()){
      $.ajax({
url : url,
data : {
"id"       : selectedId,//修改数据时需要返回其id
"username" : $("#username").val(),
//"gender" : getRadioBoxValue("u.gender"),
"gender"   : $("#gender").val(),
"age" 	   : $("#age").val(),
"degree"   : $("#degree").val(),
"remark"   : $("#remark").val()
},
success : function(data) {
console.log("结果" + data);
clearData();
$("#myModal").modal("hide");
$("#myModalLabel").text("新增");
table.ajax.reload(); 
}
});
     }
    }

/**
 * 添加数据
 **/
function addData() {
$("#myModal").modal("show");
$("#myModalLabel").text("新增");
url = "addStudentJson.action";
}

/**
 * 删除数据
 **/
function delData() {
var flag = confirm("确定删除么?");
if(flag){
$.ajax({
url : "delStudentJson.action",
data : {
"id" : selectedId
},
success : function(data) {
//console.log("结果" + data);
table.ajax.reload(); 
}
});
}

}


/**
 * 编辑数据
 **/
function editData() {
$("#myModal").modal("show");
$("#myModalLabel").text("修改");
url = "editStudentJson.action";
}

/**
     * 检查数据格式是否符合要求
     * 此处只检验是否为空,为空则提示数据为空,请输入数据。
     */
    function checkData() {
     var checkFlag = true;
     if($("#username").val()==""){
      alert("亲~姓名不能为空哦( ^_^ )");
checkFlag = false;
     }
     if($("#gender").val()==""){
      alert("亲~性别不能为空哦( ^_^ )");
      checkFlag = false;
     }
     if($("#age").val()==""){
      alert("亲~年龄不能为空哦( ^_^ )");
      checkFlag = false;
     }
     if($("#degree").val()==""){
      alert("亲~学历不能为空哦( ^_^ )");
      checkFlag = false;
     }
$("#myModal").modal("show");
return checkFlag;
    }

/**
 * 取得Radio被选中的值
 **/
function getRadioBoxValue(radioName) {
var value;
console.log("1");
var obj = document.getElementsByName(radioName);  //这个是以标签的name来取控件
console.log("2");
for(i=0; i<obj.length;i++)    {
if(obj[i].checked)    { 
value = obj[i].value;
//console.log("函数内部radioValue"+value);
break;
} 
} 
return   value;           
}

/**
 * 通过值修改所选中的单选按钮Radio的状态
 **/
function setRadioBoxByValue(radioName,radioValue){        //传入radio的name和选中项的值
var obj = document.getElementsByName(radioName);
for(var i=0;i<obj.length;i++){
         if(obj[i].value==radioValue){
           obj[i].checked=true; //修改选中状态
           break; //停止循环
         }
}
}

</script>

6、配置struts.xml(hibernate.cfg.xml及applicationContext.xml配置见基础SSH实例,在此不做赘述)
    本处重点在于如何正确配置以实现前后台Json数据的正确传递。
<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>

<package name="usermanage" extends="struts-default">

<!-- 增加用户 -->
<action name="addUser" class="com.ssh.web.UsersAction" method="addUser">
<result name="success" type="redirect">/addUser_success.jsp</result>
<result name="error">/error.jsp</result>
</action>
<!-- 删除用户 -->
<action name="delUser" class="com.ssh.web.UsersAction" method="delUser">
<result name="success" type="redirect">/delUser_success.jsp</result>
<result name="error">/error.jsp</result>
</action>
<!-- 编辑用户 -->
<action name="editUser" class="com.ssh.web.UsersAction" method="editUser">
<result name="success">/user_edit.jsp</result>
<result name="error">/error.jsp</result>
</action>
<!-- 用户列表 -->
<action name="listUser" class="com.ssh.web.UsersAction" method="listUser">
<result name="success">/user_list.jsp</result>
</action>
<!-- 登陆 -->
<action name="login" class="com.ssh.web.UsersAction" method="login">
<result name="success">/welcome.jsp</result>
<result name="input">/login.jsp</result>
<result name="error">/error.jsp</result>
</action>
<!-- 管理员登陆 -->
<action name="adminLogin" class="com.ssh.web.UsersAction" method="adminLogin">
<result name="success">/studentIndex.jsp</result>
<result name="input">/index.jsp</result>
<result name="error">/error.jsp</result>
</action>

<!-- 增加学生 -->
<action name="addStudent" class="com.ssh.web.StudentsAction" method="addStudent">
<result name="success" type="redirect">/addUser_success.jsp</result>
<result name="error">/error.jsp</result>
</action>
<!-- 学生资料编辑 -->
<action name="editStudent" class="com.ssh.web.StudentsAction" method="editStudent">
<result name="success" type="redirect">/addUser_success.jsp</result>
<result name="error">/error.jsp</result>
</action>
<!-- 学生列表显示 -->
<action name="listStudent" class="com.ssh.web.StudentsAction" method="listStudent">
<result name="success">/student_list.jsp</result>
<result name="error">/error.jsp</result>
</action>

</package>


<!--返回json的action -->
<package name="json" namespace="" extends="json-default">
<!-- 获得所有用户 -->
<action name="getAllUser" class="com.ssh.web.UsersAction" method="getAllUser">
<result type="json"></result>
</action>
<!-- 添加用户 -->
<action name="addUserJson" class="com.ssh.web.UsersAction" method="addUserJson">
<result type="json"></result>
</action>
<!-- 删除用户 -->
<action name="delUserJson" class="com.ssh.web.UsersAction" method="delUserJson">
<result type="json"></result>
</action>
<!-- 编辑用户 -->
<action name="editUserJson" class="com.ssh.web.UsersAction" method="editUserJson">
<result type="json"></result>
</action>

<!-- 新增 用户注册 -->
<action name="register" class="com.ssh.web.UsersAction" method="register">
<result type="json"></result>
</action>
<!-- 用户修改秘密 -->
<action name="modifyPassword" class="com.ssh.web.UsersAction" method="modPassword">
<result type="json"></result>
</action>


<!-- 获得所有学生用户 -->
<action name="getAllStudent" class="com.ssh.web.StudentsAction" method="getAllStudent">
<result type="json"></result>
</action>
<!-- 添加学生 -->
<action name="addStudentJson" class="com.ssh.web.StudentsAction" method="addStudentJson">
<result type="json"></result>
</action>
<!-- 删除学生 -->
<action name="delStudentJson" class="com.ssh.web.StudentsAction" method="delStudentJson">
<result type="json"></result>
</action>
<!-- 编辑学生 -->
<action name="editStudentJson" class="com.ssh.web.StudentsAction" method="editStudentJson">
<result type="json"></result>
</action>

</package>

</struts>
    以上6步大致展现了此项目实例的大致框架,其余部分配置文件以及jsp文件可详见附件。

五、总结
    整合Datatables控件到Java Web实例,首先,我们需要明确项目的要求(本项目要求是在基础的SSH框架的JavaWeb项目中实现Datatables的基本增删查改及分页),然后分析达到要求所需要的掌握的技术知识点(本项目需要我们掌握Datatables、Ajax、Json、JavaScript、jQuery,上文提到的其他技术可暂时不要求掌握),通过对每部分知识点的基础掌握使用,在此基础上,实现整合Datatables控件,从局部到整体,直至整个项目的完善。


百度云附件:链接:http://pan.baidu.com/s/1sjtIWyh 密码:b8ma
    
使用方法: 支持JAVA和PHP两种后台。 PHP:直接将WebRoot下的文件放到php服务器上直接运行即可,记得启用sqlite3。 JAVA:修改user-manage.js,将访问后台的url由"datasource.php"改为"datasource.jsp",然后将WebRoot下的文件放到tomcat下直接运行。也可使用Eclipse直接导入此项目文件。 简要说明: 使用DataTable默认的ajax交互功能,对传给后台和从后台获取的数据都有命名格式要求,这样一来耦合度较高,不利于后期扩展,不能直接适用于需要跟多种不同前端或其他业务交互的项目。本例子主要展示了自行封装请求参数和返回数据的用法,对后台的交互没有任何格式和命名限制。 基于Bootstrap 2.3.2,相关的其他插件包括图标控件FontAwesome、等待提示控件Spinjs(修改版)、弹窗控件lhgdialog(修改版) 主要展现: 封装请求参数(查询、排序、分页,不再需要data、dataFilter和dataSrc) 封装返回数据 自定义查询参数 服务器分页 自行控制和自定义遮罩效果 生成自定义效果的单元格(在线离线) 生成复选框单元格 响应复选框选择事件 生成操作按钮单元格 响应操作栏按钮点击事件 响应行点击事件 渲染回调事件(默认选中第一行) 分页栏增加跳页功能(直接修改了dataTables.bootstrap.js和dataTables.bootstrap.css) CSS实现单元格超长文字省略号显示 CSS实现单元格连续纯字母数字强制换行显示
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值