国际化开发概述
软件的国际化:软件开发时,要使它能同时应对世界不同地区和国家的访问,并针对不同地区和国家的访问,提供相应的、符合来访者阅读习惯的页面或数据。
国际化又称为 i18n:internationalization(i与n之间有18个字符)
软件实现国际化,需要具备哪些特征:
- 对于程序中固定使用的文本元素,例如菜单栏、导航条等中使用的文本元素、或错误提示信息,状态信息等,需要根据来访者的地区和国家,选择不同的语言的文本为之服务。
- 对于程序动态产生的数据,例如(日期,货币等),软件应能根据当前所在国家或地区的文化习惯进行显示。
- 可以提供更友好的访问习惯
怎样实现国际化?
针对不同的国家与地区要显示的信息,都配置到配置文件中,根据当前访问者的国家或语言从不同的配置文件中获取信息,展示在页面上。
固定文本元素的国际化:
- 对于软件中的菜单栏、导航条、错误提示信息,状态信息等这些固定不变的文本信息,可把它们写在一个properties文件中,并根据不同的国家编写不同的properties文件。这一组properties文件称之为一个资源包。
- 在JavaAPI中提供了一个ResourceBundle类用于描述一个资源包,并且ResourceBundle类提供了相应的方法getBundle,这个方法可以根据来访者的国家地区自动获取与之对应的资源文件予以显示。
创建资源包和资源文件
- 一个资源包中的每个资源文件都必须拥有共同的basename基名。除了基名,每个资源文件的名称中还必须有标识本地信息的附加部分。例如:一个资源包的基名是“myproperties”,则与中文、英文环境相对应的资源文件名则为:
- “myproperites_zh_cn.properties”
- “myproperites_en_US.properties”
- 每个资源包都应有一个默认资源文件,这个文件不带有标识本地信息的附加部分。若ResourceBundle对象在资源包中找不到与用户匹配的资源文件,它将选择该资源包中与用户最相近的资源文件,如果再找不到,则使用默认资源文件。例如:myproperites.properties
资源文件书写格式
- 资源文件的内容通常采用“关键字=值”的形式,软件根据关键字检索值显示在页面上。一个资源包中的所有资源文件的关键字必须相同,值则为相应国家的文字。
- 并且资源文件中采用的是properties格式文件,所以文件中的所有字符都必须是ASCII字码,对于像中文这样的非ACSII字符,须先进行编码。(java提供了一个native2ascII命令用于编码)。属性文件是不能保存中文的
关于资源文件(properties)命名: 基名_语言_国家.properties
编码演示 properties文件操作以及通过ResourceBundler来获取资源包中的信息
(1)资源包文件一般都放置在classpath下(对于myeclipse就是src下)
(2)关于ResourceBundler使用
创建:
ResourceBundler bundle=ResourceBundler.getBundle("message");
ResourceBundle bundle = ResourceBundle.getBundle("message",Locale.US);
获取:
bundle.getString(String name);
扩展:关于properties文件中中文问题处理?
在jdk中有一个命令native2ascii.exe
1.如果进行一次翻译
native2ascii 回车
中文 回车 如下所示:
2.进行批量翻译
native2ascii 源文件路径 目录文件路径
例如:native2ascii d:/a.txt d:/a.properties 示例如下:
测试如下:
在src下新建message_en_US.properties、message_zh_CN.properties和message.properties
package cn.itcast.i18n;
import java.util.Locale;
import java.util.ResourceBundle;
//演示ResourceBundler使用
public class I18nTest {
public static void main(String[] args) {
ResourceBundle bundle = ResourceBundle.getBundle("message");
String value = bundle.getString("msg");
System.out.println(value);
ResourceBundle bundle2 = ResourceBundle.getBundle("message",
Locale.FRANCE);
String value2 = bundle2.getString("msg");
System.out.println(value2);
ResourceBundle bundle3 = ResourceBundle.getBundle("message",
Locale.CHINA);
String value3 = bundle3.getString("msg");
System.out.println(value3);
ResourceBundle bundle4 = ResourceBundle.getBundle("message",
Locale.US);
String value4 = bundle4.getString("msg");
System.out.println(value4);
}
}
固定文本的国际化
1、加载src下properties文件
ResourceBundle bundle = ResourceBundle.getBundle(basename);
2、读取properties文件中内容
String value = bundle.getString(key);
* 也可以在ResourceBundle.getBundle时 传入一个代表国家和地区Locale对象
* ResourceBundle bundle = ResourceBundle.getBundle("info", Locale.CHINA); 指定读取中国配置文件
优先级:指定Locale > 系统默认区域和语言 > 资源包默认的
示例演示:
示例 登录页面国际化
使用fmt 国际化标签 实现国际化登陆页面
1、将jstl的jar复制 WEB-INF/lib
2、引用fmt标签库 <%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
设置locale
<fmt:setLocale value="${param.locale}"/>
创建ResourceBundle
<fmt:setBundle basename="info" var="bundle" scope="page"/>
显示message
<fmt:message bundle="${bundle}" key="login.info" />
<fmt:message bundle="${bundle}" key="login.username" />
代码如下:
新建message_en_US.properties和message_zh_CN.properties
login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'login.jsp' starting page</title>
<script type="text/javascript">
function sendForm() {
document.getElementById("f").submit();
}
</script>
</head>
<body>
<form id="f" action="${pageContext.request.contextPath}/login.jsp"
method="POST">
<select name="country" onchange="sendForm()">
<option>--请选择国家--</option>
<option value="china">中国</option>
<option value="us">美国</option>
</select>
</form>
<%
String country = request.getParameter("country");
ResourceBundle bundle = null;
if ("us".equals(country)) {
bundle = ResourceBundle.getBundle("message", Locale.US);
} else {
bundle = ResourceBundle.getBundle("message", Locale.CHINA);
}
%>
<h1><%=bundle.getString("title")%></h1>
<form>
<%=bundle.getString("username")%>:<input type="text" name="username"><br>
<%=bundle.getString("password")%>:<input type="password"
name="password"><br> <input type="submit"
value="<%=bundle.getString("submit")%>">
</form>
</body>
</html>
login1.jsp 选择系统默认的区域和语言
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>选择系统默认的资源包</title>
</head>
<body>
<%
String country = request.getHeader("accept-language");
ResourceBundle bundle = null;
if (country.startsWith("en-US")) {
bundle = ResourceBundle.getBundle("message", Locale.US);
} else {
bundle = ResourceBundle.getBundle("message", Locale.CHINA);
}
%>
<h1><%=bundle.getString("title")%></h1>
<form>
<%=bundle.getString("username")%>:<input type="text" name="username"><br>
<%=bundle.getString("password")%>:<input type="password"
name="password"><br> <input type="submit"
value="<%=bundle.getString("submit")%>">
</form>
</body>
</html>
login2.jsp 使用JSTL标签库中的fmt进行设置
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>登录窗口</title>
<script type="text/javascript">
function change() {
document.getElementById("f").submit();
}
</script>
</head>
<body>
<form id="f" action="${pageContext.request.contextPath}/login2.jsp"
method="POST">
<select name="locale" onchange="change()">
<option>--请选择国家--</option>
<option value="en_US">US</option>
<option value="zh_CN">CHINA</option>
</select>
</form>
<br> 使用JSTL国际化标签完成
<br>
<fmt:setLocale value="${param.locale}" />
<!-- new local() -->
<fmt:setBundle basename="message" var="bundle" scope="page" />
<!-- ResourceBundle bundle=ResourceBundle("message",local) -->
<h1>
<fmt:message bundle="${bundle }" key="title" />
<!-- bundle.getString("title"); -->
</h1>
<table>
<tr>
<td><fmt:message bundle="${bundle }" key="username" /></td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td><fmt:message bundle="${bundle }" key="password" /></td>
<td><input type="password" name="paswsword"></td>
</tr>
<tr>
<td colspan="2"><input type="submit"
value="<fmt:message bundle="${bundle}" key="submit" />"></td>
</tr>
</table>
</body>
</html>
格式化类Format
DateFormat类、NumberFormat类以及MessageFormat类直接继承自抽象类Format类
演示其用法如下:
package cn.itcast.i18n;
import static org.junit.Assert.*;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.Locale;
import org.junit.Test;
public class Demo {
// 请创建一个date对象,并把date对象中表示日起部分的时间值,以及表示时间部分的时间值,分别以short、long模式进行格式化输出(国家设置为中国)
@Test
public void fun1() {
Date date = new Date();
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT,
DateFormat.LONG);
System.out.println(df.format(date));
}
// 请将时间值:09-11-28 上午10时25分39秒 CST,反解析成一个date对象
@Test
public void fun2() throws ParseException {
String s = "09-11-28 上午10时25分39秒 CST";
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.SHORT,
DateFormat.LONG, Locale.CHINA);
Date date = df.parse(s);
System.out.println(date);
}
// 请将整数198,输出为货币形式:$198,并将$198反向解析成整数198
@Test
public void fun3() throws ParseException {
NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US);
nf.setMaximumFractionDigits(0);
String s = nf.format(198);
System.out.println(s);
int n = nf.parse(s).intValue();
System.out.println(n);
}
// 请将0.78654321,输出百分比格式,保留两位小数
@Test
public void fun4() {
double d = 0.78654321;
NumberFormat nf = NumberFormat.getPercentInstance();
nf.setMinimumFractionDigits(2);
System.out.println(nf.format(d));
}
}
日期格式化
DateFormat 类可以将一个日期/时间对象格式化为表示某个国家地区的日期/时间字符串。
DateFormat 类除了可按国家地区格式化输出日期外,它还定义了一些用于描述日期/时间的显示模式的 int 型的常量,包括FULL, LONG, MEDIUM, DEFAULT, SHORT,实例化DateFormat对象时,可以使用这些常量,控制日期/时间的显示长度
实例化DateFormat类有九种方式,以下三种为带参形式,下面列出的三种方式也可以分别不带参,或只带显示样式的参数。
- getDateInstance(int style, Locale aLocale):以指定的日期显示模式和本地信息来获得DateFormat实例对象,该实例对象不处理时间值部分。
- getTimeInstance(int style, Locale aLocale):以指定的时间显示模式和本地信息来获得DateFormat实例对象,该实例对象不处理日期值部分。
- getDateTimeInstance(int dateStyle, int timeStyle, Locale aLocale):以单独指定的日期显示模式、时间显示模式和本地信息来获得DateFormat实例对象。
示例如下:
package cn.itcast.i18n;
import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.Locale;
import org.junit.Test;
//DateFormat介绍
public class DateFormatTest {
// 无参数
@Test
public void fun1() {
DateFormat df1 = DateFormat.getDateInstance();// 只有年月日
DateFormat df2 = DateFormat.getTimeInstance();// 只有小时分钟秒
DateFormat df3 = DateFormat.getDateTimeInstance();// 两者都有
Date date = new Date();
System.out.println(df1.format(date));
System.out.println(df2.format(date));
System.out.println(df3.format(date));
}
// 有参数构造,指定样式
@Test
public void fun2() {
DateFormat df1 = DateFormat.getDateInstance(DateFormat.FULL);// 只有年月日
DateFormat df2 = DateFormat.getTimeInstance(DateFormat.MEDIUM);// 只有小时分钟秒
DateFormat df3 = DateFormat.getDateTimeInstance(DateFormat.LONG,
DateFormat.SHORT);// 两者都有
Date date = new Date();
System.out.println(df1.format(date));
System.out.println(df2.format(date));
System.out.println(df3.format(date));
}
// 国际化格式
@Test
public void fun3() {
DateFormat df1 = DateFormat.getDateInstance(DateFormat.FULL, Locale.US);// 只有年月日
DateFormat df2 = DateFormat.getTimeInstance(DateFormat.MEDIUM,
Locale.US);// 只有小时分钟秒
DateFormat df3 = DateFormat.getDateTimeInstance(DateFormat.LONG,
DateFormat.SHORT, Locale.US);// 两者都有
Date date = new Date();
System.out.println(df1.format(date));
System.out.println(df2.format(date));
System.out.println(df3.format(date));
}
// 关于parse方法
@Test
public void fun4() throws ParseException {
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL,
DateFormat.FULL);// 两个都有
Date date = new Date();
System.out.println(df.format(date)); // 2017年3月1日 星期三 下午04时36分13秒 CST
String st = "2017年3月1日 星期三 下午04时36分13秒 CST";
Date d = null;
d = df.parse(st);
System.out.println(d);
}
}
数字格式化NumberFormat
实例化NumberFormat类时,可以使用locale对象作为参数,也可以不使用,下面列出的是使用参数的。
- getNumberInstance(Locale locale):以参数locale对象所标识的本地信息来获得具有多种用途的NumberFormat实例对象
- getIntegerInstance(Locale locale):以参数locale对象所标识的本地信息来获得处理整数的NumberFormat实例对象
- getCurrencyInstance(Locale locale):以参数locale对象所标识的本地信息来获得处理货币的NumberFormat实例对象
- getPercentInstance(Locale locale):以参数locale对象所标识的本地信息来获得处理百分比数值的NumberFormat实例对象
示例代码如下:
package cn.itcast.i18n;
import java.text.NumberFormat;
import java.util.Locale;
import org.junit.Test;
public class NumberFormatTest {
// 1.数值操作
@Test
public void fun1() {
NumberFormat nf = NumberFormat.getIntegerInstance();
String s = nf.format(19.98765);
System.out.println(s);
}
// 2.查百分比
@Test
public void fun2() {
NumberFormat nf = NumberFormat.getPercentInstance(Locale.FRANCE);
String s = nf.format(0.98);
System.out.println(s);
}
// 3.货币
@Test
public void fun3() {
NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.US);
System.out.println(nf.format(1090));
}
}
动态文本格式化MessageFormat
动态文件格式化.
MessageForamt可以对一个模板中的信息进行动态赋值.
MessageFormat使用
MessageForamt.format(String pattern,Object... params);
关于动态文本中的占位符?
例如:{0} is required
1.注意占位符只能使用{0}---{9}之间的数值.
2.关于占们符的格式
{argumentIndex}: 0-9 之间的数字,表示要格式化对象数据在参数数组中的索引号
{argumentIndex,formatType}: 参数的格式化类型
{argumentIndex,formatType,FormatStyle}: 格式化的样式,它的值必须是与格式化类型相匹配的合法模式、或表示合法模式的字符串。
formatType可以取的值有:number date time
formatStyle可以取的值有
number类型可以取:integer currency percent
date类型可以取的:short medium full long
time类型可以取的:short medium full long
示例代码如下:
package cn.itcast.i18n;
import java.text.MessageFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.ResourceBundle;
import org.junit.Test;
public class MessageFormatTest {
public static void main(String[] args) {
ResourceBundle bundle = ResourceBundle.getBundle("message", Locale.US);
String pattern = bundle.getString("login.error");
String value = MessageFormat.format(pattern, "username", "OK");
System.out.println(value);
}
@Test
public void fun1() {
// At 12:30 pm on jul 3,1998, a hurricance destroyed 99 houses and
// caused $1000000 of damage
String msg = " At {0,time,medium} on {0,date,long}, a hurricance destroyed {1,number,integer} houses and caused {2,number,currency} of damage";
Date date = new Date();
String value = MessageFormat.format(msg, date, 99, 1000000);
System.out.println(value);
MessageFormat mf = new MessageFormat(msg, Locale.US);
String value2 = mf.format(new Object[] { date, 99, 1000000 });
System.out.println(value2);
}
@Test
public void fun2() {
// At 12:30 pm on jul 3,1998, a hurricance destroyed 99 houses and
// caused $1000000 of damage
String msg = " At {0,time,medium} on {0,date,long}, a hurricance destroyed {1,number,integer} houses and caused {2,number,currency} of damage";
Calendar c = Calendar.getInstance();
c.set(1998, 6, 3, 12, 30, 0);
Date date = c.getTime();
String value = MessageFormat.format(msg, date, 99, 1000000);
System.out.println(value);
MessageFormat mf = new MessageFormat(msg, Locale.US);
String value2 = mf.format(new Object[] { date, 99, 1000000 });
System.out.println(value2);
}
}
AJAX概述
ajax是什么,它有什么用?
AJAX即"Asynchronous JavaScript And XML"(异步JavaScript和XML)是指一种创建交互式网页应用的网页开发技术。
AJAX= 异步JavaScript和XML(标准通用语言的子集)
即AJAX=DHTML(HTML、CSS、JavaScript)+ XMLHttpRequest对象
AJAX是一种用于创建快速动态网页的技术
使用AJAX目的是为了提高用户的感受。
AJAX交互模型
传统web交互方式—同步
AJAX支持web交互方式—异步
异步操作的核心 XMLHttpRequest对象
传统web交互模式,浏览器直接将请求发送给服务器,服务器返回相应,直接发送给浏览器。
AJAX交互模型,浏览器首先将请求发送给AJAX引擎(以XMLHttpRequest为核心),AJAX引擎再将请求发送给服务器服务器回送响应先发给AJAX引擎,再由引擎传给浏览器显示。
(1)同步交互模式:客户端提交请求,等待,在响应回到客户端之前,客户端无法进行其他操作。
(2)异步交互模式:客户端将请求提交给AJAX引擎,客户端可以继续进行操作,由AJAX引擎来完成与服务器端的通信,当响应回来后,AJAX引擎会更新客户端页面,在客户端提交请求后,用户可以继续操作,而无需等待。
AJAX应用案例:suggest建议、邮件定时保存、map地图
AJAX快速入门
1.创建XMLHttpRequest对象
2.将状态触发器绑定到一个函数
3.使用open方法建立与服务器的连接
4.向服务器端发送数据
5.在回调函数中对返回数据进行处理
AJAX开发步骤:
AJAX的核心就是XMLHttpRequest对象(JS对象)
(1)得到XMLHttpRequest对象
在w3cschool文档中的xmldom文档中就可以查到dom XMLHttpRequest 对象
var xmlhttp=null;
if (window.XMLHttpRequest)
{// code for all new browsers
xmlhttp=new XMLHttpRequest();
}
else if (window.ActiveXObject)
{// code for IE5 and IE6
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
(2)注册回调函数
xmlhttp.onreadystatechange=function(){
};
(3)open 只是用于设置请求方式以及url,它不发送请求。
(4)send 它是用于发送请求的
send(null); null代表没有参数 如果有参数可以写成:"username=tom&password=123"
(5)在回调函数中处理数据
1.XMLHttpRequest对象有一个属性 readyState:它代表的是XMLHttpRequest对象的状态
0.代表XMLHttpRequest对象创建
1.open操作
2.send操作
3.接收到了响应数据,但是只有响应头,正文还没有接收到
4.所有http响应接收完成
2.status
由服务器返回的HTTP状态代码,如200表示成功
3.在回调函数中可以通过以下方式获取服务器返回的数据
responseText
responseXML
有关对象及方法的使用:
XMLHttpRequest
方法:
- open(method,url, asynch) :建立对服务器的调用
- send(content) :向服务器发送请求
属性:
onreadystatechange :状态回调函数
responseText/responseXML :服务器的响应字符串
status:服务器返回的HTTP状态码
statusText: 服务器返回的HTTP状态信息
readyState :对象状态
0 = 未初始化 1 = 正在加载
2 = 已加载 3 = 交互中
4 = 完成
open(method,url, asynch)
其中method表示HTTP调用方法,一般使用"GET","POST"
url表示调用的服务器的地址
asynch表示是否采用异步方式,true表示异步,一般这个参数不写
范例代码
xmlHttp.open("POST", "url");
xmlHttp.open("GET", "url?name=xxx&pwd=xxx");
GET方式提交
- 数据在URL上
- xmlHttp.send(null);
POST方式提交
- xmlHttp.setRequestHeader("CONTENT-TYPE","application/x-www-form-urlencoded");
- xmlHttp.send("name=xxx&pwd=xxx");
回调函数:
function 回调函数(){
if(xmlHttp.readyState == 4) { //如果响应完成
if(xmlHttp.status == 200) {//如果返回成功
…
}
}
}
常用的服务器返回数据格式
HTML片段
JSON格式的数据
XML格式的数据
关于AJAX操作中请求参数的设置问题:
1.对于get请求方式,参数设置
直接在url后面拼接
例如:"${pageContext.request.contextPath}/ajax2?name=tom"
2.对于post请求方式,参数设置
xmlhttp.open("POST","${pageContext.request.contextPath}/ajax2");
xmlhttp.send("name=tom");
注意:如果是post请求方式,还需要设置一个http请求头。
xmlhttp.setRequestHeader("","");
例如:
xmlhttp.open("POST","${pageContext.request.contextPath}/ajax2");
xmlhttp.setRequestHeader("content-type","application/x-www-form-urlencoded");
xmlhttp.send("name=tom");
(1)代码演示AJAX的使用的步骤
新建ajax.1.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ajax开发步骤</title>
<script type="text/javascript">
//第一步:得到XMLHttpRequest对象
var xmlhttp = null;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest(); //针对现在的浏览器包括IE7以上的版本
} else if (window.ActiveXObject) {
//针对IE5,IE6版本
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
//2.设置回调函数
xmlhttp.onreadystatechange = function() {
//5.处理响应数据 当信息全部返回,并且是成功
if (xmlhttp.readyState = 4 && xmlhttp.status == 200) {
alert(xmlhttp.responseText);
}
};
//3.open
xmlhttp.open("GET", "http://localhost/myday23_3/ajax1");
//4.发送请求send
xmlhttp.send(null);
</script>
</head>
<body>
</body>
</html>
新建Ajax2Servlet 路径:/ajax1
package cn.itcast.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Ajax1Servlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.getWriter().write("hello ajax");
response.flushBuffer();
response.getWriter().close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
(2)使用POST方式进行AJAX请求
新建ajax2.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ajax开发步骤</title>
<script type="text/javascript">
//第一步:得到XMLHttpRequest对象
var xmlhttp = null;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest(); //针对现在的浏览器包括IE7以上的版本
} else if (window.ActiveXObject) {
//针对IE5,IE6版本
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
//2.设置回调函数
xmlhttp.onreadystatechange = function() {
//5.处理响应数据 当信息全部返回,并且是成功
if (xmlhttp.readyState = 4 && xmlhttp.status == 200) {
alert(xmlhttp.responseText);
}
};
//3.open
//xmlhttp.open("GET", "http://localhost/myday23_3/ajax1");
//4.发送请求send
//xmlhttp.send(null);
//post请求参数,参数设置
xmlhttp.open("POST", "${pageContext.request.contextPath}/ajax2");
xmlhttp.setRequestHeader("content-type",
"application/x-www-form-urlencoded");
xmlhttp.send("name=tom");
</script>
</head>
<body>
</body>
</html>
新建Ajax2Servlet 路径/ajax2
package cn.itcast.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Ajax2Servlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String name = request.getParameter("name");
response.getWriter().write("hello " + name);
response.getWriter().close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
(3)AJAX验证输入框信息(信息校验)
新建ajax3.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ajax开发---验证用户名是否可以使用</title>
<script type="text/javascript"
src="${pageContext.request.contextPath}/my.js"></script>
<script type="text/javascript">
window.onload = function() { //页面加载后 内部的代码才有可能执行
//得到id=t的文本框
var txt = document.getElementById("t");
//给文本框注册一个失去焦点事件
txt.onblur = function() {
//获取文本框中的信息
var value = txt.value;
//第一步:得到XMLHttpRequest对象
var xmlhttp = getXmlHttpRequest();
//2.设置回调函数
xmlhttp.onreadystatechange = function() {
//5.处理响应数据 当信息全部返回,并且是成功
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var msg = xmlhttp.responseText;
document.getElementById("s").innerHTML = msg;
}
};
//post请求方式,参数设置
xmlhttp.open("POST", "${pageContext.request.contextPath}/ajax3");
xmlhttp.setRequestHeader("content-type",
"application/x-www-form-urlencoded");
xmlhttp.send("username=" + value);
};
};
</script>
</head>
<body>
<input type="text" name="username" id="t">
<span id=s></span>
<br>
<input type="text">
</body>
</html>
新建Ajax3Servlet
package cn.itcast.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Ajax3Servlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
List<String> names = new ArrayList<String>();
names.add("tom");
names.add("fox");
names.add("james");
names.add("张三");
PrintWriter out = response.getWriter();
String username = request.getParameter("username");
if (!names.contains(username)) {
out.print("<font color='red'>用户名不可使用</font>");
} else {
out.print("<font color='green'>用户名可以使用</font>");
}
out.flush();
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
(4)获取商品信息(实现同一页面数据局部刷新)
(一)最原始的方式
第一个版本:
1.创建一个Product类
private int id;
private String name;
private double price;
2.创建ajax4.jsp
<a href="javascript:void(0)" id="p">显示商品信息</a>
<div id="d"></div>
在回调函数中得到服务器返回的信息innerHTML到div中.
3.在Ajax4Servlet中
将List<Product>中的数据,手动拼接成了html代码,写回到浏览器端.
builder.append("<table border='1'><tr><td>商品编号</td><td>商品名称</td><td>商品价格</td></tr>");
for (Product p : ps) {
builder.append("<tr><td>" + p.getId() + "</td><td>" + p.getName()
+ "</td><td>" + p.getPrice() + "</td></tr>");
}
builder.append("</table>");
my.js
/**
*
*/
function getXmlHttpRequest() {
var xmlhttp=null;
if (window.XMLHttpRequest) {
xmlhttp=new XMLHttpRequest(); // 针对于现在的浏览器包括IE7以上版本
} else if(window.ActiveXObject){
// 针对于IE5,IE6版本
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
return xmlhttp;
}
ajax4.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ajax开发---显示商品信息</title>
<script type="text/javascript"
src="${pageContext.request.contextPath}/my.js"></script>
<script type="text/javascript">
window.onload = function() { //页面加载后 内部的代码才有可能执行
//得到id=p的超链接
var p = document.getElementById("p");
//给超链接注册点击事件
p.onclick = function() {
var xmlhttp = getXmlHttpRequest();
//2.设置回调函数
xmlhttp.onreadystatechange = function() {
//5.处理响应数据 当信息全部返回,并且是成功
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var msg = xmlhttp.responseText;
document.getElementById("d").innerHTML = msg;
}
};
//get请求方式,参数设置
xmlhttp.open("GET", "${pageContext.request.contextPath}/ajax4");
xmlhttp.send(null);
};
};
</script>
</head>
<body>
<a href="javascript:void(0)" id="p">显示商品信息</a>
<div id="d"></div>
</body>
</html>
Ajax4Servlet
package cn.itcast.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcast.domain.Product;
public class Ajax4Servlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
List<Product> ps = new ArrayList<Product>();
ps.add(new Product(1, "洗衣机", 1800));
ps.add(new Product(2, "电视机", 3800));
ps.add(new Product(3, "空调", 5800));
PrintWriter out = response.getWriter();
StringBuilder builder = new StringBuilder();
builder.append("<table border='1'><tr><td>商品编号</td><td>商品名称</td><td>商品价格</td></tr>");
for (Product p : ps) {
builder.append("<tr><td>" + p.getId() + "</td><td>" + p.getName()
+ "</td><td>" + p.getPrice() + "</td></tr>");
}
builder.append("</table>");
out.print(builder.toString());
out.flush();
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
(2)第二个版本
创建一个product.jsp页面,在页面上去组装table,直接将数据返回了.
步骤
1.在Ajax4Servlet中
request.setAttribute("ps", ps);
request.getRequestDispatcher("/product.jsp").forward(request, response);
2.在product.jsp页面上
<table border='1'>
<tr>
<td>商品编号</td>
<td>商品名称</td>
<td>商品价格</td>
</tr>
<c:forEach items="${ps}" var="p">
<tr>
<td>${p.id }</td>
<td>${p.name }</td>
<td>${p.price }</td>
</tr>
</c:forEach>
</table>
Ajax4Servlet
package cn.itcast.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.itcast.domain.Product;
public class Ajax4Servlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
List<Product> ps = new ArrayList<Product>();
ps.add(new Product(1, "洗衣机", 1800));
ps.add(new Product(2, "电视机", 3800));
ps.add(new Product(3, "空调", 5800));
request.setAttribute("ps", ps);
request.getRequestDispatcher("product.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
product.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<table border="1">
<tr>
<td>商品编号</td>
<td>商品名称</td>
<td>商品价格</td>
</tr>
<c:forEach items="${ps}" var="p">
<tr>
<td>${p.id }</td>
<td>${p.name }</td>
<td>${p.price }</td>
</tr>
</c:forEach>
</table>
(3)第三个版本
在服务器端得到数据,只将要显示的内容返回,而不返回html代码
而html代码的拼接,在浏览器端完成。
问题:服务器返回什么样的数据格式?
json:它是一种轻量级的数据交换格式。
[{'id':'1','name':'洗衣机','price':'1800'},{'id':'2','name':'电视机','price':'3800'}]
在js中{name:value,name1:valu1}这就是一个js对象.
[{},{}]这代表有两个对象装入到了一个数组中。
导入jsonlib的相关jar包
ajax5.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ajax开发---显示商品信息(json)</title>
<script type="text/javascript"
src="${pageContext.request.contextPath}/my.js"></script>
<script type="text/javascript">
window.onload = function() { //页面加载后 内部的代码才有可能执行
//得到id=p的超链接
var p = document.getElementById("p");
//给超链接注册点击事件
p.onclick = function() {
var xmlhttp = getXmlHttpRequest();
//2.设置回调函数
xmlhttp.onreadystatechange = function() {
//5.处理响应数据 当信息全部返回,并且是成功
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var json = eval(xmlhttp.responseText);
var msg = "<table border='1'><tr><td>商品编号</td><td>商品名称</td><td>商品价格</td></tr>";
for(var i=0;i<json.length;i++){
msg+="<tr><td>"+json[i].id+"</td><td>"+json[i].name+"</td><td>"+json[i].price+"</td></tr>";
}
msg += "</table>";
document.getElementById("d").innerHTML = msg;
}
};
//get请求方式,参数设置
xmlhttp.open("GET", "${pageContext.request.contextPath}/ajax5");
xmlhttp.send(null);
};
};
</script>
</head>
<body>
<a href="javascript:void(0)" id="p">显示商品信息</a>
<div id="d"></div>
</body>
</html>
Ajax5Servlet /ajax5
package cn.itcast.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import cn.itcast.domain.Product;
public class Ajax5Servlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
List<Product> ps = new ArrayList<Product>();
ps.add(new Product(1, "洗衣机", 1800));
ps.add(new Product(2, "电视机", 3800));
ps.add(new Product(3, "空调", 5800));
// 返回的是json数据
PrintWriter out = response.getWriter();
String json = JSONArray.fromObject(ps).toString();
out.print(json);
out.flush();
out.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
json格式以及插件jsonlib的使用
关于jsonlib插件使用:
1.导包(6个包)
(commons-beanutils-1.8.3.jar、commons-collections-3.2.1.jar、commons-lang-2.6.jar、commons-logging-1.1.1.jar、ezmorph-1.0.6.jar、json-lib-2.4-jdk15.jar)
注意:最后一个包依赖于以上5个jar包
2.将java对象转换成json
1.对于数组,List集合,要想转换成json
JSONArray.fromObject(java对象); ["value1","value2"]
2.对于javaBean,Map
JSONObject.fromObject(javaBean对象); {name1:value1,name2:value2}
对于json数据,它只有两种格式
1.[值1,值2,...] ------>这就是javascript中的数组
2.{name:value,....} ---->就是javascript中的对象。
但是这两种格式可以嵌套.
[{},{},{}]
{name:[],name:[]}
3.如果javaBean中有一个属性,不想生成在json中,怎样处理?
JsonConfig config = new JsonConfig();
config.setExcludes(new String[] { "type" });
JSONArray.fromObject(ps, config).toString();
上述代码就是在生成json时,不将type属性包含.
Ajax处理xml以及XStream的使用
ajax操作中服务器端返回xml处理
XMHttpRequest.resposneXML;----->得到的是一个Document对象.
操作:可以自己将xml文件中的内容取出来,写回到浏览器端。也可以请求转发到一个xml文件,将这个文件信息写回到浏览器端.注意 response.setContextType("text/xml;charset=utf-8");
问题:如果没有xml文件,我们的数据是从数据库中查找到了,想要将其以xml格式返回怎样处理?
可以使用xml插件处理 xstream,它可以在java对象与xml之间做转换.
xstream使用:
1.导包
2个.(xpp3_min-1.1.4c.jar、xstream-1.3.1.jar)
2.使用
1.将java对象转换成xml
XStream xs=new XStream();
String xml=xs.toXML(java对象);
问题:生成的xml中的名称是类的全名.
两种方式:
1.编码实现
xs.alias("person", Person.class);
2.使用注解(Annotation)
@XStreamAlias(别名) 对类和变量设置别名
@XStreamAsAttribute 设置变量生成属性
@XStreamOmitField 设置变量 不生成到XML
@XStreamImplicit(itemFieldName = “hobbies”) 设置集合类型变量 别名
使注解生效
xStream.autodetectAnnotations(true);
示例1:服务器通过ajax返回xml文件内容
在WebRoot下新建person.xml文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person>
<name>tom</name>
<age>20</age>
</person>
<person>
<name>fox</name>
<age>30</age>
</person>
</persons>
新建Ajax6Servlet.
package cn.itcast.servlet;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Ajax6Servlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
InputStream fis = this.getServletContext().getResourceAsStream(
"/person.xml");
OutputStream os = response.getOutputStream();
int len = -1;
byte[] b = new byte[1024];
while ((len = fis.read(b)) != -1) {
os.write(b, 0, len);
os.flush();
}
fis.close();
os.close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
ajax6.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ajax开发---xml返回</title>
<script type="text/javascript"
src="${pageContext.request.contextPath}/my.js"></script>
<script type="text/javascript">
window.onload = function() {
//得到id=t的文本框
var btn = document.getElementById("btn");
btn.onclick = function() {
//第一步:得到XMLHttpRequest对象.
var xmlhttp = getXmlHttpRequest();
//2.设置回调函数
xmlhttp.onreadystatechange = function() {
//5.处理响应数据 当信息全部返回,并且是成功
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var xml = xmlhttp.responseXML;
alert(xml);
var names = xml.getElementsByTagName("name");
for(var i=0;i<names.length;i++){
//alert(names[i].firstChild.nodeValue);
alert(names[i].innerHTML);
}
}
};
//post请求方式,参数设置
xmlhttp.open("GET", "${pageContext.request.contextPath}/ajax6");
xmlhttp.send(null);
};
};
</script>
</head>
<body>
<input type="button" value="接收xml" id="btn">
</body>
</html>
(7)使用xstream插件将bean对象转化为指定的xml进行返回
新建Bean类person
package cn.itcast.domain;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
@XStreamAlias("person")
public class Person {
//@XStreamAsAttribute
private int id;
//@XStreamAlias("姓名")
private String name;
//@XStreamOmitField
private int age;
public Person() {
super();
}
public Person(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Ajax7Servlet
package cn.itcast.servlet;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.thoughtworks.xstream.XStream;
import cn.itcast.domain.Person;
public class Ajax7Servlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/xml;charset=utf-8");
List<Person> ps = new ArrayList<Person>();
ps.add(new Person(1, "tom", 20));
ps.add(new Person(2, "fox", 30));
XStream xs = new XStream();
xs.autodetectAnnotations(true);
String xml = xs.toXML(ps);
response.getWriter().write(xml);
response.getWriter().close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
ajax7.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ajax开发---xml返回</title>
<script type="text/javascript"
src="${pageContext.request.contextPath}/my.js"></script>
<script type="text/javascript">
window.onload = function() {
//得到id=t的文本框
var btn = document.getElementById("btn");
btn.onclick = function() {
//第一步:得到XMLHttpRequest对象.
var xmlhttp = getXmlHttpRequest();
//2.设置回调函数
xmlhttp.onreadystatechange = function() {
//5.处理响应数据 当信息全部返回,并且是成功
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var xml = xmlhttp.responseXML;
var div=document.getElementById("content");
var persons=xml.getElementsByTagName("person");
for(var i=0;i<persons.length;i++){
var id=persons[i].getElementsByTagName("id")[0].innerHTML;
var name=persons[i].getElementsByTagName("name")[0].innerHTML;
var age=persons[i].getElementsByTagName("age")[0].innerHTML;
div.innerHTML+="id:"+id+" name:"+name+" age:"+age+"<br>";
}
}
};
//post请求方式,参数设置
xmlhttp.open("GET", "${pageContext.request.contextPath}/ajax7");
xmlhttp.send(null);
};
};
</script>
</head>
<body>
<input type="button" value="接收xml" id="btn">
<div id="content">
</div>
</body>
</html>
测试XStream功能
修改person.xml
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person>
<name>tom</name>
<age>20</age>
<sex>男</sex>
</person>
<person>
<name>fox</name>
<age>30</age>
<sex>女</sex>
</person>
</persons>
修改person类
package cn.itcast.domain;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
@XStreamAlias("person")
public class Person {
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@XStreamAsAttribute
private int id;
@XStreamAlias("姓名")
// 起别名
private String name;
@XStreamOmitField
// 忽略此属性age
private int age;
private String sex;
public Person() {
super();
}
public Person(int id, String name, int age, String sex) {
super();
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", age=" + age
+ ", sex=" + sex + "]";
}
}
新建测试类
package cn.itcast.xstream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import cn.itcast.domain.Person;
public class XStreamTest {
// 将person对象转成xml
@Test
public void fun1() {
Person p = new Person(1, "tom", 20, "男");
XStream xs = new XStream();
xs.alias("person", Person.class); // 等同于注解@XStreamAlias("person")
String xml = xs.toXML(p);
System.out.println("注解前:\n" + xml);
// 设置别名
xs.alias("person", Person.class); // 等同于
// 要想要注解生效,必须开启
xs.autodetectAnnotations(true);
String xml1 = xs.toXML(p);
System.out.println("注解后:\n" + xml1);
}
// 将List<Person>转换成xml
@Test
public void fun2() {
List<Person> ps = new ArrayList<Person>();
ps.add(new Person(1, "tom", 20, "男"));
ps.add(new Person(2, "fox", 30, "女"));
XStream xs = new XStream();
xs.alias("person", Person.class);
String xml = xs.toXML(ps);
System.out.println("注解前:\n" + xml);
XStream xs2 = new XStream();
xs2.alias("persons", List.class);
xs2.autodetectAnnotations(true);
String xml2 = xs2.toXML(ps);
System.out.println("注解后:\n" + xml2);
}
// 将一个xml解析成java对象.
@Test
public void fun3() throws FileNotFoundException {
XStream xs = new XStream();
// xs.autodetectAnnotations(true);
xs.alias("person", Person.class);
xs.alias("persons", List.class);
Object obj = xs.fromXML(new FileInputStream(
"F:\\myEclipse_project\\myday23_3\\WebRoot\\person.xml"));
System.out.println(obj);
}
}
依次调试 结果如下
注意事项:innerHTML属性只适合最新版本的浏览器,是不兼容IE的
Ajax实现省市联动
实现步骤:
ajax步骤:
(1)得到XMLHttpRequest对象
(2)注册回调函数
(3)open设置请求方式与url
(4)send发送请求
(5)在回调函数中完成操作
XMLHttpRequest的readyState状态(笔试题):
- 0:XMLHttpRequest对象创建
- 1:open
- 2:send
- 3:只接受到了响应头
- 4:响应完成,响应头与响应体全部返回
注意:如果服务器返回的是JSON数据,我们在浏览器接收数据eval()转换转换成JS对象
var json=eval(xnlhttp.responseText);
有些情况下,转换会出现问题 解决方法如下:
var json=eval("(" +xmlhttp.responseText+ ")")
开发步骤:
my.js (封装XMLHttpRequest对象)
function getXmlHttpRequest() {
var xmlhttp = null;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest(); // 针对于现在的浏览器包括IE7以上版本
} else if (window.ActiveXObject) {
// 针对于IE5,IE6版本
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
return xmlhttp;
}
封装Bean对象 Province和City
Province
package cn.itcast.domain;
import java.util.List;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamImplicit;
@XStreamAlias("province")
public class Province {
private String name;
@XStreamImplicit
private List<City> citys;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<City> getCitys() {
return citys;
}
public void setCitys(List<City> citys) {
this.citys = citys;
}
}
City
package cn.itcast.domain;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@XStreamAlias("city")
public class City {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
导入XStream和jsonlib的jar包
(1)XML实现省市级联动
新建ajax1.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ajax开发---XML返回</title>
<script type="text/javascript"
src="${pageContext.request.contextPath}/my.js"></script>
<script type="text/javascript">
var xml; //声明全局,因为要在多个函数中使用
window.onload = function() {
//第一步:得到XMLHttpRequest对象
var xmlhttp = getXmlHttpRequest();
//2.设置回调函数
xmlhttp.onreadystatechange = function() {
//5.处理响应数据 当信息全部返回 并且是成功
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
xml = xmlhttp.responseXML;//得到的数据将将province数据添加
//得到xml是一个Document对象,它代表的是服务器端返回的xml
//将xml中所有province的name子元素中的文本获取到
var ps = xml.getElementsByTagName("province");
for (var i = 0; i < ps.length; i++) {
//得到每一个province元素下的第一个name子元素
var nameElement = ps[i].getElementsByTagName("name")[0];
//得到name元素中的文本信息,就是省份名称
var pname = nameElement.firstChild.nodeValue;
//创建option标签,将其添加到省份下拉框中
var option = document.createElement("option");
option.text = pname;
//将创建的option添加到省份下拉框中
document.getElementById("province").add(option);
}
}
};
//GET请求方式,参数设置
xmlhttp.open("GET", "${pageContext.request.contextPath}/ajax1");
xmlhttp.send(null);
};
//创建一个函数,用于向城市下拉框中添加值
function fillCity() {
var province = document.getElementById("province");//省份下拉框
var city = document.getElementById("city");//城市下拉框
//每一次向城市中添加信息时,将信息重置
city.innerHTML = "<option>--请选择城市--</option>";
//1.得到选中省份的名称
var pname = province.options[province.selectedIndex].text;
var ps = xml.getElementsByTagName("province");
for (var i = 0; i < ps.length; i++) {
//得到每一个province元素下的第一个name子元素
var nameElement = ps[i].getElementsByTagName("name")[0];
//得到name元素中的文本信息,就是省份名称
var pElementName = nameElement.firstChild.nodeValue;
//判断选择的省份名称与xml文件中的是否一致
if (pname == pElementName) {
//得到当前省份的所有城市
var citys = ps[i].getElementsByTagName("city");
for (var j = 0; j < citys.length; j++) {
//得到所有城市的名称
var cname = citys[j].getElementsByTagName("name")[0].firstChild.nodeValue;
//创建option添加到城市下拉框中
var option = document.createElement("option");
option.text = cname;
city.add(option);
}
}
}
}
</script>
</head>
<body>
<select id="province" onchange="fillCity()">
<option>--请选择省份--</option>
</select>
<select id="city">
<option>--请选择城市--</option>
</select>
</body>
</html>
新建Ajax1Servlet
package cn.itcast.servlet;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.thoughtworks.xstream.XStream;
import cn.itcast.domain.City;
import cn.itcast.domain.Province;
public class Ajax1Servlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/xml;charset=utf-8");
// 1.得到数据
List<Province> ps = new ArrayList<Province>();
Province p1 = new Province();
p1.setName("黑龙江");
List<City> citys1 = new ArrayList<City>();
City city1 = new City();
city1.setName("哈尔滨");
City city11 = new City();
city11.setName("齐齐哈尔");
City city111 = new City();
city111.setName("大庆");
citys1.add(city1);
citys1.add(city11);
citys1.add(city111);
p1.setCitys(citys1);
Province p2 = new Province();
p2.setName("吉林");
List<City> citys2 = new ArrayList<City>();
City city2 = new City();
city2.setName("长春");
City city22 = new City();
city22.setName("吉林");
City city222 = new City();
city222.setName("四平");
citys2.add(city2);
citys2.add(city22);
citys2.add(city222);
p2.setCitys(citys2);
ps.add(p1);
ps.add(p2);
// 将ps转换成XML
XStream xs = new XStream();
xs.autodetectAnnotations(true);
String xml = xs.toXML(ps);
response.getWriter().write(xml);
response.getWriter().close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
(2)json实现省市级联
ajax2.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>ajax开发---json返回</title>
<script type="text/javascript"
src="${pageContext.request.contextPath}/my.js"></script>
<script type="text/javascript">
var jsonObj; //声明全局,因为要在多个函数中使用
window.onload = function() {
var province = document.getElementById("province");
//第一步:得到XMLHttpRequest对象
var xmlhttp = getXmlHttpRequest();
//2.设置回调函数
xmlhttp.onreadystatechange = function() {
//5.处理响应数据 当信息全部返回 并且是成功
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
jsonObj = eval("(" + xmlhttp.responseText + ")");
//得到省份名称
for (var i = 0; i < jsonObj.length; i++) {
var pname = jsonObj[i].name;
var option = document.createElement("option");
option.text = pname;
province.add(option);
}
}
};
//GET请求方式,参数设置
xmlhttp.open("GET", "${pageContext.request.contextPath}/ajax2");
xmlhttp.send(null);
};
//创建一个函数,用于向城市下拉框中添加值
function fillCity() {
var province = document.getElementById("province");//省份下拉框
var city = document.getElementById("city");//城市下拉框
//每一次向城市中添加信息时,将信息重置
city.innerHTML = "<option>--请选择城市--</option>";
//1.得到选中省份的名称
var pname = province.options[province.selectedIndex].text;
for (var i = 0; i < jsonObj.length; i++) {
var pElementName = jsonObj[i].name;
if (pname == pElementName) {
var citys = jsonObj[i].citys;
for (var j = 0; j < citys.length; j++) {
var cname = citys[j].name;
var option = document.createElement("option");
option.text = cname;
city.add(option);
}
}
}
}
</script>
</head>
<body>
<select id="province" onchange="fillCity()">
<option>--请选择省份--</option>
</select>
<select id="city">
<option>--请选择城市--</option>
</select>
</body>
</html>
Ajax2Servlet
package cn.itcast.servlet;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import cn.itcast.domain.City;
import cn.itcast.domain.Province;
public class Ajax2Servlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/xml;charset=utf-8");
// 1.得到数据
List<Province> ps = new ArrayList<Province>();
Province p1 = new Province();
p1.setName("黑龙江");
List<City> citys1 = new ArrayList<City>();
City city1 = new City();
city1.setName("哈尔滨");
City city11 = new City();
city11.setName("齐齐哈尔");
City city111 = new City();
city111.setName("大庆");
citys1.add(city1);
citys1.add(city11);
citys1.add(city111);
p1.setCitys(citys1);
Province p2 = new Province();
p2.setName("吉林");
List<City> citys2 = new ArrayList<City>();
City city2 = new City();
city2.setName("长春");
City city22 = new City();
city22.setName("吉林");
City city222 = new City();
city222.setName("四平");
citys2.add(city2);
citys2.add(city22);
citys2.add(city222);
p2.setCitys(citys2);
ps.add(p1);
ps.add(p2);
// 转换成json
String json = JSONArray.fromObject(ps).toString();
response.getWriter().write(json);
response.getWriter().close();
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}