您的位置:首页 > Web前端 > JavaScript

【Servlet】在Servlet3.0中利用ajax达到iframe局部刷新效果,同时避免在Js写过多的HTML代码

2015-03-25 09:27 597 查看
Ajax技术已经不算什么新鲜事了,Ajax局部刷新的文章在网上已经应有尽有,但是,这些文章有一个很严重的缺点,就是把查询出来的内容在JS不停地构造HTML内容,再把这些内容放在页面,好像自己的JS构造节点技术很牛B很熟练似的,或者认为查询出来的内容只能通过这种方法去局部刷新。导致后期大部分HTML在JavaScript脚本里面,IDE工具无法识别。现在不说Javascript熟练不熟练的问题。主要是脚本就应该是脚本,HTML就应该是HTML,混在一起根本就画面太丑没法看。一方面用框架不停地声称耦合度什么的,一方面自己就写出一堆耦合度极其恐怖的程序,根本不知道是什么心态。那么,如果把Ajax查询出来的内容放在HTML显示,尽量避免利用Javascript构造节点呢?你或许需要JQuery的load方法。下面用一个Servlet3.0的例子来说明这个东西,免得SSH杂糅太多包让人看不懂。

一、基本目标

修改数据库的表单在1.jsp,

2.jsp只是用来显示数据库的查询信息。也就是说2.jsp这是那张表格。

修改数据之后,我们只需要局部刷新2.jsp是不是?这样没这么卡是不是?



二、基本思想

Web工程的目录结构如下,ajax技术必须要jQuery,然后,Servlet3.0中必须的javax.servlet-api-3.1.0.jar,查询MySql必须的mysql-connector-java-5.1.32.jar就不说了。网上自己一搜就有了。web.xml除了jsp的基本框架以外,不用写任何东西,让Eclipse自动创建就行了《【Javaweb】Eclipse for JavaEE新建的Web工程自动生成web.xml》(点击打开链接),随后,所有Servlet直接用Servlet3.0标准配置。



然后,整个网络工程的大体流程是这样的。可能有点乱,但是配合下面的代码,应该大致能够理解的。



三、***过程

1、首先dbDAO.java如下,这个文件在《【Servlet】根据MVC思想设计用户登陆、用户注册、修改密码系统》(点击打开链接)已经讲解过了,这里就不讲了。完全一模一样,一个字都没有改

import java.sql.*;

public class dbDAO {
	private Connection con;

	// 构造函数,连接数据库
	public dbDAO() throws Exception {
		String dburl = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&useOldAliasMetadataBehavior=true";
		String dbusername = "root";
		String dbpassword = "root";
		Class.forName("com.mysql.jdbc.Driver");
		this.con = DriverManager.getConnection(dburl, dbusername, dbpassword);
	}

	// 执行查询
	public ResultSet query(String sql, Object... args) throws Exception {
		PreparedStatement ps = con.prepareStatement(sql);
		for (int i = 0; i < args.length; i++) {
			ps.setObject(i + 1, args[i]);
		}
		return ps.executeQuery();
	}

	// 执行插入
	public boolean insert(String sql, Object... args) throws Exception {
		PreparedStatement ps = con.prepareStatement(sql);
		for (int i = 0; i < args.length; i++) {
			ps.setObject(i + 1, args[i]);
		}
		if (ps.executeUpdate() != 1) {
			return false;
		}
		return true;
	}

	// 执行修改
	public boolean modify(String sql, Object... args) throws Exception {
		PreparedStatement ps = con.prepareStatement(sql);
		for (int i = 0; i < args.length; i++) {
			ps.setObject(i + 1, args[i]);
		}
		if (ps.executeUpdate() != 1) {
			return false;
		}
		return true;
	}

	// 析构函数,中断数据库的连接
	protected void finalize() throws Exception {
		if (!con.isClosed() || con != null) {
			con.close();
		}
	}
}


2、2.jsp里面就一个等待ajax查询结果填充的表格,这个ajax是该页面一载入就被执行,其查询结果等待url为jsonRequest的Servlet返回。注意引入jquery包。利用到文件碎片的插入方式,这样就不会太卡。文件碎片在《【JavaScript】利用文件碎片DocumentFragment改进兼容IE6可调可控的图片滑块》(点击打开链接),就已经介绍过了。2.jsp这个页面被刷新,被载入,就马上显示当前testtable表的内容。

<%@ page language="java" contentType="text/html; charset=utf-8"
	pageEncoding="utf-8"%>
<%@ page import="java.util.*"%>
<!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">
<script src="jquery-1.11.1.js"></script>
<title>2</title>
</head>
<body>
	<table border="1" id="data"></table>
</body>
</html>
<script>
	$.ajax({
		type : "post",
		url : "jsonRequest",
		dataType : "text",
		success : function(data) {
			data = eval(data);
			//构造前先清空源节点
			document.getElementById("data").innerHTML = "";
			//设置一个文件碎片
			var frag = document.createDocumentFragment();
			//这是表头
			var tr = document.createElement("tr");
			tr.innerHTML = "<td>id</td><td>username</td><td>number</td>";
			frag.appendChild(tr);
			//利用循环构造表格的每一行,把其放在文件碎片上面
			for (var i = 0; i < data.length; i++) {
				tr = document.createElement("tr");
				tr.innerHTML = "<td>" + data[i].id + "</td>" + "<td>"
						+ data[i].username + "</td>" + "<td>" + data[i].number
						+ "</td>";
				frag.appendChild(tr);
			}
			//此时文件碎片已经是一张表了,直接放网页就可以了
			document.getElementById("data").appendChild(frag);
		},
		error : function() {
			alert("出错了");
		}

	});
</script>


3、ServletJson.java也就是url为jsonRequest的Servlet。Servlet如何把查询结果构造成Json字符串返回页面的。在《【Servlet】在Servlet3.0中利用json+ajax把数据库查询出来的数据推向前台显示,无额外的json解析包》(点击打开链接)已经讲过了,这里一字没改,所用的查询表也是相同。

import java.io.*;
import java.sql.*;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;

//说明这个Servlet是没有序列号的
@SuppressWarnings("serial")
//说明这个Servlet的名称是jsonRequest,其地址是/jsonRequest这与在web.xml中设置是一样的
@WebServlet(name = "jsonRequest", urlPatterns = { "/jsonRequest" })
public class ServletJson extends HttpServlet {
	//放置用户之间通过直接在浏览器输入地址访问这个servlet
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		PrintStream out = new PrintStream(response.getOutputStream());
		response.setContentType("text/html;charSet=utf-8");
		out.print("请正常打开此页");
	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		//把从数据库的查询结果构造一个json字符串推向前台
		StringBuffer json = new StringBuffer();
		json.append("[");
		try {
			dbDAO db = new dbDAO();
			ResultSet rs = db.query("select * from testtable");
			while (rs.next()) {
				json.append('{');
				//注意每一个key-value对都要在引号之中,单引号或者双引号都可以
				json.append("'id':").append("'").append(rs.getInt("id")).append("'").append(",");
				json.append("'username':").append("'")
						.append(rs.getString("username").trim()).append("'").append(",");
				json.append("'number':").append("'")
						.append(rs.getString("number").trim()).append("'");
				json.append("},");
			}			

		} catch (Exception e) {
			e.printStackTrace();
		}
		//这是为了删除最后一次循环中出现的那个逗号
		json.deleteCharAt(json.length() - 1);
		json.append("]");
		PrintStream out = new PrintStream(response.getOutputStream());
		response.setContentType("text/html;charSet=utf-8");
		//搞完把json打印在本Servlet上,之后前台页面读这页的内容就可以了
		out.println(json.toString());
		out.close();
	}
}


4、1.jsp,这个页面是整个WEB工程的核心,

首先是HTML布局如下,当然,里面有很多无关紧要的文本,主要是用来说明这些文本到头来是不会刷新的。

loadHTML是用来载入2.jsp的。相当于以前很流行,但现在被人唾弃的iframe。还有一个等待脚本载入的下来列表。

<%@ 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">
<title>1</title>
<script src="jquery-1.11.1.js"></script>
</head>
<body>
	我是1.jsp的内容!
	<p style="color: blue">我是不被刷新的</p>
	<span style="color: red">我是不被刷新的</span>
	<br /> id=
	<select id="id"></select> username=
	<input type="text" id="username" name="username" /> number=
	<input type="text" id="number" name="number" />
	<button onclick="ajaxSubmit()">修改</button>
	<h1>==============以下为2.jsp的内容!====================</h1>
	<div id="loadHTML"></div>
	<h1>==============以上为2.jsp的内容!====================</h1>
	我是1.jsp的内容!
	<br />
	<p style="color: blue">我是不被刷新的</p>
	<span style="color: red">我是不被刷新的</span>
</body>
</html>
这个页面的脚本如下,一上来就通过load方法载入2.jsp的内容,也就是读取数据库里面的东西。然后,通过countDataBase.java这个Servlet,载入当前testtable的id列。之后,为修改按钮提供脚本,传递表达的数据什么id,username,number等给update.java这个Servlet根据此来修改数据。

<script>
	$("#loadHTML").load("2.jsp");
	$.ajax({
		type : "post",
		url : "countDataBase",
		dataType : "text",
		success : function(data) {
			data = eval(data);
			for (var i = 0; i < data.length; i++) {
				option = document.createElement("option");
				option.innerHTML = data[i].id;
				option.value = data[i].id;
				document.getElementById("id").appendChild(option);
			}
		},
		error : function() {
			alert("出错了");
		}

	});
	function ajaxSubmit() {
		var id = $("#id").val();
		var username = $("#username").val();
		var number = $("#number").val();
		$.ajax({
			type : "post",
			url : "update",
			data : {
				id : id,
				username : username,
				number : number,
			},
			success : function(data) {
				$("#loadHTML").load("2.jsp");
			},
			error : function() {
				alert("出错了");
			}

		});
	}
</script>


5、先说countDataBase.java这个Servlet,其实也没有什么好说的,就是把数据库的id列查询出来,用ajax退回给1.jsp

import java.io.*;
import java.sql.ResultSet;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;

@SuppressWarnings("serial")
@WebServlet(name = "countDataBase", urlPatterns = { "/countDataBase" })
public class countDataBase extends HttpServlet {
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		PrintStream out = new PrintStream(response.getOutputStream());
		response.setContentType("text/html;charSet=utf-8");
		out.print("请正常打开此页");
	}

	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// 把从数据库的查询结果构造一个json字符串推向前台
		StringBuffer json = new StringBuffer();
		json.append("[");
		try {
			dbDAO db = new dbDAO();
			ResultSet rs = db.query("select * from testtable");
			while (rs.next()) {
				json.append('{');
				// 注意每一个key-value对都要在引号之中,单引号或者双引号都可以
				json.append("'id':").append("'").append(rs.getInt("id"))
						.append("'").append(",");
				json.append("},");
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		// 这是为了删除最后一次循环中出现的那个逗号
		json.deleteCharAt(json.length() - 1);
		json.append("]");
		PrintStream out = new PrintStream(response.getOutputStream());
		response.setContentType("text/html;charSet=utf-8");
		// 搞完把json打印在本Servlet上,之后前台页面读这页的内容就可以了
		out.println(json.toString());
		out.close();
	}
}


6、最后是update.java这个Servlet,这个更没有东西说,设置好编码,防止中文乱码,根据1.jsp传递过来的数据,修改数据库相应的列,就是如此地简单。不懂也没关系,可以看回我之前的《【Servlet】根据MVC思想设计用户登陆、用户注册、修改密码系统》(点击打开链接

import java.io.*;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;

@SuppressWarnings("serial")
@WebServlet(name = "update", urlPatterns = { "/update" })
public class update extends HttpServlet {
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		PrintStream out = new PrintStream(response.getOutputStream());
		response.setContentType("text/html;charSet=utf-8");
		out.print("请正常打开此页");
	}
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		String id=(String)request.getParameter("id");
		String username=(String)request.getParameter("username");
		String number=(String)request.getParameter("number");

		try {
			dbDAO db = new dbDAO();
			db.modify("update testtable set username=? where id=?",username,id);
			db.modify("update testtable set number=? where id=?",number,id);	

		} catch (Exception e) {
			e.printStackTrace();
		}

		PrintStream out = new PrintStream(response.getOutputStream());
		response.setContentType("text/html;charSet=utf-8");
		//搞完把json打印在本Servlet上,之后前台页面读这页的内容就可以了
		out.println("修改成功");
		out.close();
	}
}


四、总结与展望

大家可以看到1.jsp中的脚本中根本没有过多的html代码,数据库查询出来的东西,只需要在2.jsp进行简单的构造就可以,利用一个简单的load方法,把2.jsp读进来。不要直接在1.jsp的脚本中构建一个表格。这达到了html代码与javascript的代码分离的目的,同时每一次修改只是刷新一个div的内容,到达了局部刷新的效果。以后要修改数据库查询的内容。比如2.jsp中的那个表格的样式,你就不用再脚本中修改。直接该2.jsp集合。2.jsp的作用不是正如以前iframe时代那些banner.html,footer.html……吗?而1.jsp不是正是如同以前充满iframe标签的主页面吗?
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: