基于Struts2的jTable使用

    由于有个项目中需要用到数据显示的表格插件,经过查阅资料发现了这款插件,在使用过程中也遇到好的问题,不过都解决了,所有在闲暇时间把这款插件结合struts2 做一个demo给大家,希望对看到的人有所帮助。

    文章中有什么错误请指出,遇到问题也可以留言。

    转发时候请说明一下,尊重我的劳动成果。谢谢!

一、jTable介绍

   官方网站:http://www.jtable.org/

    jTable是基于AJAX不要编码HTML或者Javascript CRUD 表的的jQuery插件。

基于Struts2的jTable使用_第1张图片

    Java Servlet demo : http://www.programming-free.com/search/label/jTable

二、环境搭建

1.新建工程

2.配置struts2环境

      将struts2的lib包放入工程中,配置 web.xml 文件, 写struts.xml文件 。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
	<constant name="struts.enable.DynamicMethodInvocation" value="false" />
	<constant name="struts.devMode" value="true" />
	<constant name="struts.custom.i18n.resources" value="message" />
	<constant name="struts.i18n.encoding" value="utf-8" />

	<!--一定要继承 json-default-->
	<package name="student" extends="json-default" namespace="/student">

		<action name="listStudentByPageAction" class="com.action.StudentAction"
			method="listStudentByPage">
			<result type="json"></result>
		</action>
		<action name="getJSONResult" class="com.action.StudentAction"
			method="listStudentByPage">
			<result type="json" />
		</action>
	</package>
</struts>

3.将jtable的相关文件放入工程中(文件可从官方网站下载)

基于Struts2的jTable使用_第2张图片

三、编写程序

项目源码结构如下图所示

基于Struts2的jTable使用_第3张图片

1.student

package com.bean;

public class Student {
	private int studentId;
	private String name;
	private String department;
	private String emailId;

	public int getStudentId() {
		return studentId;
	}

	public String getName() {
		return name;
	}

	public String getDepartment() {
		return department;
	}

	public String getEmailId() {
		return emailId;
	}

	public void setStudentId(int studentId) {
		this.studentId = studentId;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setDepartment(String department) {
		this.department = department;
	}

	public void setEmailId(String emailId) {
		this.emailId = emailId;
	}
}

2.StudentDao

package com.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import com.bean.Student;
import com.jdbc.DataAccessObject;

public class StudentDao {
	private Connection dbConnection;
	private PreparedStatement pStmt;

	public StudentDao() {
		dbConnection = DataAccessObject.getConnection();
	}

	public void addStudent(Student student) {
		String insertQuery = "INSERT INTO STUDENT(STUDENTID, NAME, "
				+ "DEPARTMENT, EMAIL) VALUES (?,?,?,?)";
		try {
			pStmt = dbConnection.prepareStatement(insertQuery);
			pStmt.setInt(1, student.getStudentId());
			pStmt.setString(2, student.getName());
			pStmt.setString(3, student.getDepartment());
			pStmt.setString(4, student.getEmailId());
			pStmt.executeUpdate();
		} catch (SQLException e) {
			System.err.println(e.getMessage());
		}
	}

	public void deleteStudent(int userId) {
		String deleteQuery = "DELETE FROM STUDENT WHERE STUDENTID = ?";
		try {
			pStmt = dbConnection.prepareStatement(deleteQuery);
			pStmt.setInt(1, userId);
			pStmt.executeUpdate();
		} catch (SQLException e) {
			System.err.println(e.getMessage());
		}
	}

	public void updateStudent(Student student) {
		String updateQuery = "UPDATE STUDENT SET NAME = ?, "
				+ "DEPARTMENT = ?, EMAIL = ? WHERE STUDENTID = ?";
		try {
			pStmt = dbConnection.prepareStatement(updateQuery);
			pStmt.setString(1, student.getName());
			pStmt.setString(2, student.getDepartment());
			pStmt.setString(3, student.getEmailId());
			pStmt.setInt(4, student.getStudentId());
			pStmt.executeUpdate();

		} catch (SQLException e) {
			System.err.println(e.getMessage());
		}
	}

	public int getCount() {
		String count = "SELECT COUNT(*) FROM STUDENT";
		int i = 0;
		try {
			Statement st = dbConnection.createStatement();
			ResultSet rs = st.executeQuery(count);
			if (rs.next()) {
				i = rs.getInt(1);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return i;
	}

	public List<Student> getAllStudentsByPage(int startRow, int pageSize) {
		List<Student> students = new ArrayList<Student>();

		String query = "SELECT * FROM STUDENT LIMIT ? OFFSET ?";
		try {
			pStmt = dbConnection.prepareStatement(query);
			pStmt.setInt(1, pageSize);
			pStmt.setInt(2, startRow);
			ResultSet rs = pStmt.executeQuery();
			// Statement stmt = dbConnection.createStatement();
			// ResultSet rs = stmt.executeQuery(query);
			while (rs.next()) {
				Student student = new Student();

				student.setStudentId(rs.getInt("STUDENTID"));
				student.setName(rs.getString("NAME"));
				student.setDepartment(rs.getString("DEPARTMENT"));
				student.setEmailId(rs.getString("EMAIL"));
				students.add(student);
			}
		} catch (SQLException e) {
			System.err.println(e.getMessage());
		}
		return students;
	}
}

3.DataAccessObject

package com.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;

public class DataAccessObject {

	private static Connection connection = null;

	public static Connection getConnection() {
		if (connection != null)
			return connection;
		else {
			// Store the database URL in a string
			String serverName = "localhost";
			String portNumber = "3306";
			String sid = "test";
			String dbUrl = "jdbc:mysql://" + serverName + ":" + portNumber
					+ "/" + sid;
			try {
				Class.forName("com.mysql.jdbc.Driver");
				// set the url, username and password for the database
				connection = DriverManager.getConnection(dbUrl, "root", "root");
			} catch (Exception e) {
				e.printStackTrace();
			}
			return connection;
		}
	}
}

4.StudentAcion

    我只写了一个加载列表的action 各位可以按照我的方法依次编写其他函数

package com.action;

import java.util.ArrayList;
import java.util.List;

import com.bean.Student;
import com.dao.StudentDao;
import com.opensymphony.xwork2.Action;

public class StudentAction {

	// 属性
	private int studentId;
	private String name;
	private String department;
	private String emailId;

	private Student record;
	private List<Student> records;
	private String result;
	private String message;

	/** 分页 **/
	private int jtStartIndex;
	private int jtPageSize;
	private int totalRecordCount;

	private StudentDao dao;

	public StudentAction() {
		dao = new StudentDao();
	}

	/**
	 * 获取列表
	 * 
	 * @return
	 */
	public String listStudentByPage() {
		records = new ArrayList<Student>();
		try {
			records = dao.getAllStudentsByPage(jtStartIndex, jtPageSize);
			totalRecordCount = dao.getCount();
			System.out.println(records.size()+"--"+totalRecordCount);
			result = "OK";
		} catch (Exception e) {
			e.printStackTrace();
			message = e.getMessage();
			result = "ERROR";
		}
		return Action.SUCCESS;
	}

    //省略 set  get
}

5.index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path;
%>
<title>Insert title here</title>
<link type="text/css" rel="stylesheet" href="<%=basePath%>/res/plugins/jtable/themes/metro/blue/jtable.css" />
<link type="text/css" rel="stylesheet" href="<%=basePath%>/res/css/jquery-ui-1.10.3.custom.css" />
<script type="text/javascript" src="<%=basePath%>/res/plugins/jquery-1.9.0.min.js"></script>
<script type="text/javascript" src="<%=basePath%>/res/plugins/jquery-ui-1.10.0.min.js"></script>
<script type="text/javascript" src="<%=basePath%>/res/plugins/jtable/jquery.jtable.js"></script>
</head>
<body>
	<div style="width: 80%; margin-right: 10%; margin-left: 10%; text-align: center;">
		<h4>AJAX based CRUD operations using jTable in J2EE</h4>
		<div id="StudentTableContainer"></div>
	</div>
</body>
<script type="text/javascript">
	$(document).ready(function() {
		$('#StudentTableContainer').jtable({
			title : 'Students List',
            paging: true, //Enable paging
            pageSize: 10, //Set page size (default: 10)
			actions : {
				listAction : '<%=basePath%>/student/listStudentByPageAction',
				createAction: '<%=basePath%>/student/insertStudentAction',
				deleteAction: ''
			},
			fields : {
				studentId : {
					title : 'Student Id',
					width : '30%',
					key : true,
					list : true,
					edit : false,
					create : true
				},
				name : {
					title : 'Name',
					width : '30%',
					edit : true
				},
				department : {
					title : 'Department',
					width : '30%',
					edit : true
				},
				emailId : {
					title : 'Email',
					width : '20%',
					edit : true
				}
			}
		});
		$('#StudentTableContainer').jtable('load');
	});
</script>
</html>

四、程序调试(重要部分)

    前面都是一些准备工作,即使各位按照我的步骤也一定不会运行成功,我在写这个demo的时候已经测试过了。大家也许对其中一些变量名称有疑问,请认真看下面的部分。

    在StudentAction中有这七个变量

        private Student record;//单条记录,这个变量在添加信息时候使用,
	private List<Student> records;//数据列表,
	private String result;//结果标识
	private String message;//信息标识(在程序出行错误时候,jtable会 alert出这个信息,所有一般携带异常信息)

	/** 分页 **/
	private int jtStartIndex;//分页的开始位
	private int jtPageSize;//页面大小
	private int totalRecordCount;//数据列表中的记录数

    上面的注释中解释了一部分,这些都是jtable要使用分页功能时候必须的变量。

    下面解释为什么调试不出来的原因:

    请大家看看jtable.js源码,我这里为大家复制一段

        /* LOADING RECORDS  *****************************************************/

        /* Performs an AJAX call to reload data of the table.
        *************************************************************************/
        _reloadTable: function (completeCallback) {
            var self = this;

            //Disable table since it's busy
            self._showBusy(self.options.messages.loadingMessage, self.options.loadingAnimationDelay);

            //Generate URL (with query string parameters) to load records
            var loadUrl = self._createRecordLoadUrl();

            //Load data from server
            self._onLoadingRecords();
            self._ajax({
                url: loadUrl,
                data: self._lastPostData,
                success: function (data) {
                    self._hideBusy();

                    //Show the error message if server returns error
                    if (data.Result != 'OK') {
                        self._showError(data.Message);
                        return;
                    }

                    //Re-generate table rows
                    self._removeAllRows('reloading');
                    self._addRecordsToTable(data.Records);

                    self._onRecordsLoaded(data);

                    //Call complete callback
                    if (completeCallback) {
                        completeCallback();
                    }
                },
                error: function () {
                    self._hideBusy();
                    self._showError(self.options.messages.serverCommunicationError);
                }
            });
        },

    这段代码在jtable.js 390行开始。

    这段代码中清楚的写道jtable加载数据的ajax函数,请仔细观察其中的 Result、Message、Records这三个变量首字符全是大写,而我们的程序的变量是小写。

    也许有人会说我可以把我们的程序变量改为大写啊,但是问题出现了:

    第一、不符合java代码编写风格,

    第二、根本调试不通,在action中变量的set和get方法的下一个字母的大写,例如:

        public Student getRecord() {
		return record;
	}
	public void setRecord(Student record) {
		this.record = record;
	}

   如果你将变量的首字符设置为大写,set和get方法的下一个字母也是大写,而struts2框架通过set和get获取变量的时候默认将变量的首字符设置成小写,所以你的首字母大写的变量不会传递到前台。(这部分应该是利用Java的反射机制,struts2并不知道你action中的私有变量,它是通过你公开的set和get方法获取的到你的变量)

    解决的办法就是修改jtable.js的源码,通过我的测试只需用将相应的ajax函数中的  data.Result、data.Records 等在获取数据的地方修改即可,各位可以从我的附件中直接下载使用。

    需要修改的数据有:

    data.Result(7处修改);

    data.Message(7处修改);

    data.record(5处);

    data.Records(2处修改);

    data.Options(1处修改);

    data.TotalRecordCount(1处修改);

    data.jtStartIndex(无需修改);

    data.jtPageSize(无需修改);

五、附件

http://git.oschina.net/weisun826/jTable_Struts2_Demo

你可能感兴趣的:(Ajax,struts2,jtable)