摘录自:http://www.cnblogs.com/gaopeng527/p/4459622.html

1. 级联下拉列表

例1.1 级联下拉列表。

(1)编写AjaxRequest.js文件,并将其保存到JS文件夹中。AjaxRequest.js的具体代码如下:

var net = new Object();  //定义一个全局变量net
//编写构造函数
net.AjaxRequest=function(url,onload,onerror,method,params){
this.req = null;
this.onload = onload;
this.onerror=(onerror)?onerror:this.defaultError;
this.loadDate(url,method,params);
}
//编写用于初始化XMLHttpRequest对象并指定处理函数,最后发送HTTP请求的方法
net.AjaxRequest.prototype.loadDate=function(url,method,params){
if(!method){
method="GET";
}
if(window.XMLHttpRequest){
this.req=new XMLHttpRequest();
}else if(window.ActiveXObject){
this.req = new ActiveXObject("Microsoft.XMLHTTP");
}
if(this.req){
try{
var loader = this;
this.req.onreadystatechange=function(){
net.AjaxRequest.onReadyState.call(loader);
}
this.req.open(method,url,true); //建立对服务器的调用
if(method=="POST"){
this.req.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); //设置请求头
}
this.req.send(params);
}catch(err){
this.onerror.call(this);
}
}
} //重构回调函数
net.AjaxRequest.onReadyState = function(){
var req=this.req;
var ready=req.readyState;
if(ready==4){
if(req.status==200){
this.onload.call(this);
}else{
this.onerror.call(this);
}
}
}
//重构默认的错误处理函数
net.AjaxRequest.prototype.defaultError = function(){
alert("错误数据\n\n回调状态:"+this.req.readyState+"\n状态:"+this.req.status);
}

(2)编写index.jsp文件,并在该文件中包含AjaxRequest.js文件,具体代码如下:

<script language="javascript" src="JS/AjaxRequest.js"></script>

(3)在index.jsp页面中编写错误处理的函数、实例化Ajax对象的方法和回调函数。在本例中,涉及两次异步操作,所以需要编写两个实例化Ajax对象的方法和回调函数。

编写实例化用于异步获取省份和直辖市的Ajax对象的方法和回调函数。具体代码如下:

function getProvince(){
var loader=new net.AjaxRequest("ZoneServlet?action=getProvince&nocache="+new Date().getTime(), deal_getProvince, onerror, "GET");
}
function deal_getProvince(){ //通过循环将数组中的省份名称添加到下拉列表中
provinceArr=this.req.responseText.split(","); //将获取的省份名称字符串分割为数组
for(i=0;i<provinceArr.length;i++){
document.getElementById("province").options[i]=new Option(provinceArr[i],provinceArr[i]);
}
if(provinceArr[0]!=""){
getCity(provinceArr[0]); //获取市县
}
}
window.onload=function(){
getProvince();
}

编写实例化用于异步获取市县的Ajax对象的方法和回调函数,以及错误处理函数。具体代码如下:

function getCity(selProvince){
var loader=new net.AjaxRequest("ZoneServlet?action=getCity&parProvince="+selProvince+"&nocache="+new Date().getTime(), deal_getCity, onerror, "GET");
}
function deal_getCity(){
cityArr=this.req.responseText.split(","); //将获取的市县名称字符串分割为数组
document.getElementById("city").length=0; //清空下拉列表
for(i=0;i<cityArr.length;i++){
document.getElementById("city").options[i]=new Option(cityArr[i],cityArr[i]);
}
}
function onerror(){} //错误处理函数

(4) 在页面中添加设置省份和直辖市的下拉列表,名称为province和设置市县的下拉列表,名称为city,并在省份和直辖市下拉列表的onchange事件中,调用getCity()方法获取省份对应的市县。具体代码如下:

<select name="province" id="province" onchange="getCity(this.value)"></select>
<select name="city" id="city"></select>

(5)编写获取居住地的Servlet实现类ZoneServlet,在该Servlet中的doGet()方法中,编写以下代码用于根据传递的action参数,执行不同的处理方法。

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { String action = request.getParameter("action"); //获取action参数的值
if("getProvince".equals(action)){ //获取省份和直辖市信息
this.getProvince(request,response);
}else if("getCity".equals(action)){ //获取市县信息
this.getCity(request,response);
}
}

(6)在ZoneServlet中,编写getProvince()方法。在该方法中,将省份信息连接为一个以逗号分隔的字符串输出到页面上(本例比较简单实际当中应采用Map存放省份与市县信息)。具体代码如下:

    /**
* 获取省份和直辖市
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
public void getProvince(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("GBK");
String result="吉林";
response.setContentType("text/html");
PrintWriter out=response.getWriter();
out.print(result); //输出获取的省份字符串
out.flush();
out.close();
}

(7)在ZoneServlet中,编写个getCity()方法。在该方法中,中获取指定省份对应的市县信息,并将获取的是市县信息连接成一个以逗号分隔的字符串输出到页面上。具体代码如下:

    /**
* 获取市县
* @param request
* @param response
* @throws ServletException
* @throws IOException
*/
public void getCity(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("GBK");
String result="长春,延边,白山,白城,四平,辽源";
response.setContentType("text/html");
PrintWriter out=response.getWriter();
out.print(result); //输出获取的市县字符串
out.flush();
out.close();
}

(8) 为了在页面载入后显示默认的省份,还需要在页面的onload事件中调用获取省份的方法getProvince()。具体代码如下:

window.onload=function(){
getProvince(); //获取省份和直辖市
}

运行本实例index.jsp,结果如下所示:

2. 显示进度条

文件上传是一个很费时的任务,经常需要用户进行长时间等待,为了让用户在等待的过程中,即使了解上传的进度,可以在进行文件上传时,显示上传进度条。下面将介绍如何实现带进度条的文件上传。

例2.1 显示进度条。

(1) 编写index.jsp页面,在该页面中添加用于获取上传文件所需信息的表单及表单元素。由于要实现文件上传,所以需要将表单的enctype属性设置为multipart/form-data。关键代码如下:

<form name="form1" enctype="multipart/form-data" method="post" action="UpLoad?action=uploadFile">
<div align="center">
请选择要上传的文件:<input type="file" name="file" size="42"><br>
<input type="button" name="shangchuan" value="上传" width="61" height="23" onClick="deal(form1)">
<input type="button" name="chongzhi" value="重置" width="61" height="23" onClick="form1.reset();">
</div>
</form>

(2)在index.jsp页面的合适位置添加用于显示进度条的<div>标记和显示百分比的<span>标记。具体代码如下:

    <div id="progressBar" class="prog_border" align="left"><img src="data:images/progressBar.png" width="0" height="13"
id="imgProgress">
</div>
?<span id="progressPercent" style="width:40px;display:none">0%</span>

(3)在CSS样式表文件style.css中,添加用于控制进度条样式的CSS样式。具体代码如下:

.prog_border{
height:15px; //高度
widht:255px; //宽度
background:#9ce0fd; //背景颜色
border:1px solid #FFFFFF; //边框样式
margin:0;
padding:0;
display:none;
position:relative
left:25px;
float:left; //居左对齐
}

(4)在index.jsp页面的<head>标记中,编写自定义的JavaScript函数deal(),用于提交表单并设置每隔500毫秒获取一次上传进度。deal()函数的具体代码如下:

<script type="text/javascript">
function deal(form){
form.submit(); //提交表单
timer=window.setInterval("getProgress()", 500); //每隔500毫秒获取一次上传进度
}
</script>

(5)编写上传文件的Servlet实现类UpLoad。在该Servlet中编写实现文件上传的方法uploadFile()。在uploadFile()方法中,将调用Common-FileUpload组件分段上传文件,并计算上传百分比,将其实时保存到Session中。

Apache commons-fileupload 的使用: 
 1) 去 http://commons.apache.org/fileupload/ 下载fileupload jar包 
 同时下载 commons-fileupload 和  commons-io 两个包  -------- 因为fileupload依赖io包 
 2) 将jar包导入 web 工程WEB-INF/lib下

uploadFile()方法的具体代码如下:

package com.cn.Ajax;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List; import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload; public class UpLoad extends HttpServlet { public void uploadFile(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { response.setContentType("text/html;charset=GBK");
request.setCharacterEncoding("GBK");
HttpSession session=request.getSession();
session.setAttribute("progressBar", 0); //定义上传进度的Session变量
String error = "";
int maxSize = 50*1024*1024; //单个文件上传大小的上限
DiskFileItemFactory factory = new DiskFileItemFactory(); //基于磁盘文件项目创建一个工厂对象
ServletFileUpload upload = new ServletFileUpload(factory); //创建一个新的文件上传对象
try {
List items = upload.parseRequest(request); //解析上传请求
Iterator itr = items.iterator(); //枚举方法
while(itr.hasNext()){
FileItem item =(FileItem) itr.next(); //获取FileItem对象
if(!item.isFormField()){ //判断是否为文件域
if(item.getName()!=null&&!item.getName().equals("")){ //判断是否选择了文件
long upFileSize = item.getSize(); //上传文件的大小
String fileName = item.getName(); //获取文件名
if(upFileSize>maxSize){
error="您上传的文件太大,请选择不超过50MB的文件";
break;
}
//此时文件暂存在服务器的内存中
File tempFile = new File(fileName); //构造临时对象
//获取根目录对应的真实物理路径
File file = new File(request.getRealPath("/upload"),tempFile.getName());
InputStream is = item.getInputStream();
int buffer=1024;
int length =0;
byte[] b=new byte[buffer];
double percent=0;
FileOutputStream fos = new FileOutputStream(file);
while((length=is.read(b))!=-1){
percent += length/(double)upFileSize*100D; //计算上传文件的百分比
fos.write(b,0,length); //向文件输出流写读取的数据
session.setAttribute("progressBar", Math.round(percent)); //将上传百分比保存到Session中
}
fos.close();
Thread.sleep(1000); //线程休眠1秒
}else {
error="没有选择上传文件!";
}
}
}
} catch (Exception e) {
e.printStackTrace();
error = "上传文件出现错误:"+e.getMessage();
}
if(!"".equals(error)){
request.setAttribute("error", error);
request.getRequestDispatcher("error.jsp").forward(request, response);
}else {
request.setAttribute("result", "文件上传成功!");
request.getRequestDispatcher("upFile_deal.jsp").forward(request, response);
} } }

(6)由于要使用Ajax,所以需要创建一个封装Ajax必须实现功能的对象AjaxRequest,并将其代码保存为AjaxRequest.js,

AjaxRequest.js

var net = new Object();  //定义一个全局变量net
//编写构造函数
net.AjaxRequest=function(url,onload,onerror,method,params){
this.req = null;
this.onload = onload;
this.onerror=(onerror)?onerror:this.defaultError;
this.loadDate(url,method,params);
}
//编写用于初始化XMLHttpRequest对象并指定处理函数,最后发送HTTP请求的方法
net.AjaxRequest.prototype.loadDate=function(url,method,params){
if(!method){
method="GET";
}
if(window.XMLHttpRequest){
this.req=new XMLHttpRequest();
}else if(window.ActiveXObject){
this.req = new ActiveXObject("Microsoft.XMLHTTP");
}
if(this.req){
try{
var loader = this;
this.req.onreadystatechange=function(){
net.AjaxRequest.onReadyState.call(loader);
}
this.req.open(method,url,true); //建立对服务器的调用
if(method=="POST"){
this.req.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); //设置请求头
}
this.req.send(params);
}catch(err){
this.onerror.call(this);
}
}
} //重构回调函数
net.AjaxRequest.onReadyState = function(){
var req=this.req;
var ready=req.readyState;
if(ready==4){
if(req.status==200){
this.onload.call(this);
}else{
this.onerror.call(this);
}
}
}
//重构默认的错误处理函数
net.AjaxRequest.prototype.defaultError = function(){
alert("错误数据\n\n回调状态:"+this.req.readyState+"\n状态:"+this.req.status);
}

然后在index.jsp页面中通过以下代码包含该文件:

    <script language="javascript" src="JS/AjaxRequest.js"></script>

说明:通常情况下,在处理POST请求时,需要将请求头设置为application/x-www-form-urlencoded。但是,如果将表单的enctype属性设置为multipart/form-data,在处理请求时,就需要将请求头设置为multipart/form-data。

(7)在index.jsp页面中,编写自定义的JavaScript函数getProgress(),用于实例化Ajax对象。getProgress()函数的具体代码如下:

function getProgress(){
var loader=new net.AjaxRequest("showProgress.jsp?nocache="+new Date().getTime(), deal_p, onerror, "GET");
}

在上面的代码中一定要加代码“?nocache="+new Date().getTime()”,否则将出现进度不更新的情况。

(8)编写showProgress.jsp页面,在该页面中只需要应用EL表达式输出保存上传进度的Session变量。具体代码如下:

<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
${progressBar}

(9)编写Ajax的回调函数deal_p(),用于显示上传进度条及完成的百分比。deal_p()函数的具体代码如下:

        function deal_p(){
var h=this.req.responseText;
h=h.replace(/\s/g,""); //去除字符串中的Unicode空白符
document.getElementById("progressPercent").style.display="";//现实百分比
progressPercent.innerHTML=h+"%"; //显示完成的百分比
document.getElementById("progressBar").style.display="block"; //显示进度条
document.getElementById("imgProgress").width=h*(255/100); //显示完成的进度
}

(10)编写Ajax的错误处理函数onerror(),在该函数中,添加弹出“出错了”提示对话框的代码。onerror()函数的具体代码如下:

function onerror(){
alert("上传文件出错!");
}

(11)编写error.jsp和upFile_deal.jsp代码如下:

<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<!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=GB18030">
<title>Insert title here</title>
</head>
<body>
${error}<br>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<!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=GB18030">
<title>Insert title here</title>
</head>
<body>
${result}<br>
</body>
</html>

完整的index.jsp页面代码如下:

<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<!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=GB18030">
<title>Insert title here</title>
<script type="text/javascript">
function deal(form){
form.submit(); //提交表单
timer=window.setInterval("getProgress()", 500); //每隔500毫秒获取一次上传进度
} function getProgress(){
var loader=new net.AjaxRequest("showProgress.jsp?nocache="+new Date().getTime(), deal_p, onerror, "GET");
} function deal_p(){
var h=this.req.responseText;
h=h.replace(/\s/g,""); //去除字符串中的Unicode空白符
document.getElementById("progressPercent").style.display="";//现实百分比
progressPercent.innerHTML=h+"%"; //显示完成的百分比
document.getElementById("progressBar").style.display="block"; //显示进度条
document.getElementById("imgProgress").width=h*(255/100); //显示完成的进度
} function onerror(){
alert("上传文件出错!");
}
</script>
</head>
<body> <form name="form1" enctype="multipart/form-data" method="post" action="UpLoad">
<div align="center">
请选择要上传的文件:<br>
<input type="file" name="file" size="42"><br>
注:文件大小请控制在50M以内。
</div>
<table align="center">
<tr>
<td align="left">
<div id="progressBar" class="prog_border" align="left"><img src="data:images/progressBar.png" width="0" height="13"
id="imgProgress"></div>
</td>
<td>
<span id="progressPercent" style="width:40px;display:none">0%</span>
</td>
</tr>
</table>
<div align="center">
<input type="button" name="shangchuan" value="上传" width="61" height="23" onClick="deal(form1)">
<input type="button" name="chongzhi" value="重置" width="61" height="23" onClick="form1.reset();">
</div>
</form> <script language="javascript" src="JS/AjaxRequest.js"></script>
</body>
</html>

运行结果如下图所示:

Ajax常用实例的更多相关文章

  1. ajax常用实例代码总结新手向参考(一)

    http的交互方法有四种:get.post.put(增加数据).delete(删除数据) put和delete实现用的是get和post   get方式 页面不能被修改,只是获取查询信息.但是提交的数 ...

  2. Ajax-04 jQuery Ajax 常用操作

    jQuery jQuery 其实就是一个JavaScript的类库,其将复杂的功能做了上层封装,使得开发者可以在其基础上写更少的代码实现更多的功能. jQuery Ajax a.概述 jQuery 不 ...

  3. find一些常用参数的一些常用实例和一些具体用法和注意事项。

    find一些常用参数的一些常用实例和一些具体用法和注意事项. 1.使用name选项: 文件名选项是find命令最常用的选项,要么单独使用该选项,要么和其他选项一起使用.  可以使用某种文件名模式来匹配 ...

  4. AJAX 数据库实例

    AJAX 用于创建动态性更强的应用程序. AJAX ASP 实例 下面的例子将演示当用户在输入框中键入字符时,网页如何与服务器进行通信: 实例 请在下面的输入框中键入字母(A - Z): 姓名: 建议 ...

  5. 【转】 Android常用实例—Alert Dialog的使用

    Android常用实例—Alert Dialog的使用 AlertDialog的使用很普遍,在应用中当你想要用户做出“是”或“否”或者其它各式各样的选择时,为了保持在同样的Activity和不改变用户 ...

  6. AJAX XML 实例

    AJAX XML 实例 下面的例子将演示网页如何使用 AJAX 来读取来自 XML 文件的信息 <!DOCTYPE html> <html> <head> < ...

  7. php中ajax使用实例

    php中ajax使用实例 一.总结 1.多复习:这两段代码都挺简单的,就是需要复习,要多看 2.ajax原理:ajax就是部分更新页面,其实还在的html页面监听到事件后,然后传给服务器进行操作,这里 ...

  8. thinkphp中ajax使用实例(thinkphp内置支持ajax)

    thinkphp中ajax使用实例(thinkphp内置支持ajax) 一.总结 1.thinkphp应该是内置支持ajax的,所以请求类型里面才会有是否是ajax // 是否为 Ajax 请求 if ...

  9. spark2.4.5计算框架中各模块的常用实例

    本项目是使用scala语言给出了spark2.4.5计算框架中各模块的常用实例. 温馨提醒:spark的版本与scala的版本号有严格的对应关系,安装请注意. Spark Core RDD以及Pair ...

随机推荐

  1. 进程管理工具Supervisor(一)简介与使用

    Supervisor是用Python开发的一套client/server架构的进程管理程序,能做到开机启动,以daemon进程的方式运行程序,并可以监控进程状态等等. linux进程管理方式有传统的r ...

  2. iOS性能优化技术

    小小总结,后续继续跟进. 1. 提高应用性能的几个开发细节 * 尽量避免使用constraint实现动画 * 尽量避免使用数组的删除操作 * 尽量避免使用 NSString::stringWithFo ...

  3. Java学习笔记8---类的静态成员变量与静态成员方法的访问与调用方式

    (注:静态变量修改为静态成员变量,静态方法改为静态成员方法) 静态成员变量又称类变量,静态成员方法又称类方法,它们统称为静态成员或类成员.静态成员由static修饰,是属于整个类的,所有的对象共享这些 ...

  4. 入门干货之Grpc的.Net实现-MagicOnion

    此文章简单残暴,学习成本较低,你可以跟着我一起撸代码,一起吐槽,一起砸键盘.以下操作均为 core2.0 环境. 0x01.Grpc 1.介绍  Google主导开发的RPC框架,使用HTTP/2协议 ...

  5. 搬个小板凳,我们扯扯Docker的前生

    一.新瓶装旧酒 首先我们需要知道,Docker是一个"箩筐": 1.存储:Device Mapper.BtrFS.AUFS 2.名字空间:UTS.IPC.Mount.PID.Net ...

  6. Spring Boot快速入门(三):依赖注入

    原文地址:https://lierabbit.cn/articles/6 spring boot使用依赖注入的方式很简单,只需要给添加相应的注解即可 @Service用于标注业务层组件 @Contro ...

  7. Android4.0 声卡配置-高通msm8916移植

    一个正常的UAC设备插入Android 7.0是默认打开UAC配置的,打印的log如下: [ - using xhci_hcd [ - [ -, Product=, SerialNumber= [ - ...

  8. inline函数不能在for循环中使用的原因

    inline函数的作用继承了宏定义的优点,没有了参数压栈,代码生成等一部分操作,并且摒弃了没有检查编译规则的缺点: 另外要注意,内联函数一般只会用在函数内容非常简单的时候,这是因为,内联函数的代码会在 ...

  9. 51 NOD 1238 最小公倍数之和 V3

    原题链接 最近被51NOD的数论题各种刷……(NOI快到了我在干什么啊! 然后发现这题在网上找不到题解……那么既然A了就来骗一波访问量吧…… (然而并不怎么会用什么公式编辑器,写得丑也凑合着看吧…… ...

  10. 【Java学习笔记之四】java进制转化

    十进制转成十六进制: Integer.toHexString(int i) 十进制转成八进制 Integer.toOctalString(int i) 十进制转成二进制 Integer.toBinar ...