Ajax虽然是一种新瓶装旧酒的技术,但这个名词从诞生到现在,短短的时间却对Web开发产生了深远的影响。
2005.2.18,Jesse James Garrett 的一篇A New Approach to Web Applications引出了AJAX这个web界的新名词。
Ajax的含义就是异步JavaScript+HTML。它最大的作用就是可以使Web页面实现无刷新异步获取数据。为了领略一下Ajax的应用,我也做了一个非常简单的项目:模拟Google的提示输入。
创建一个名为AjaxTest的Web项目,其根路径为”/AjaxTest“。之后,创建一个JSP文件,内容如下:
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My Ajaxt Test!</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="Ajax,test,ajax test">
<meta http-equiv="description" content="This is my Ajax Test page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<script type='text/javascript' src='ajaxTest.js'></script>
</head>
<body οnlοad=" initXHR() ;">
<form name="myForm">
Name: < input type="text" id="userName" οnkeyup="callServer()">
<br>
<div id="txtHint" ><b>Delars info will be listed here.</b></div>
</form>
</body>
</html>
然后,创建一个进行数据库访问的JavaBean, 需要说明的是,这个小例子使用的数据库是postgreeSQL,如果使用不同的数据库,请修改成相应的连接字符串。另外请将你的数据库的连接驱动包放到WEB-INF下的lib目录下。
接下来, 将servlet2.3的jar也放到lib目录下。 创建一个Servlet,实现服务端的处理。这个Sevlet源码如下:
配置WEB-INF目录下的web.xml,其内容参照如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app id="Ajax_Test">
<display-name>Ajax_Test</display-name>
<servlet>
<servlet-name>TestServlet</servlet-name>
<display-name>TestServlet</display-name>
<description>Test servlet</description>
<servlet-class>com.ajax.servlet.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<url-pattern>/test.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
好了,让我们再看一下关键的ajaxTest.js文件,看看怎样用Ajax实现远程访问(对服务器端的访问,并取得数据)。Ajax的核心技术是使用一个叫做XMLHttpRequest对象。这并不是一个新对象,很多浏览器都在Ajax这个名词诞生之前都拥有了她,但实现的方式各有不同。请通过源例子代码查看其区别,IE一般是通过ActiveXObject实现,且不同版本名称可能不同,而FireFox等浏览器则直接有了这个对象(据说IE7也实现了)。 ajaxTest.js的内容如下:
var xmlHttp;
function initXHR(){
xmlHttp = getXmlHttpRequest();
}
function getXmlHttpRequest(){
var xhr;
// Internet Explorer
try{
xhr = new ActiveXObject("Microsoft.XMLHTTP"); //IE5+
}catch(e){
try{
xhr = new ActiveXObject("Msxml2.XMLHTTP");//IE5-
}catch(er){
xhr = false;
}
}
if(!xhr && typeof XMLHttpRequest != 'undefined'){
try{
// Firefox, Opera 8.0+, Safari
xhr = new XMLHttpRequest();
}catch(e){
alert("Your browser dose not support Ajax!");
}
}
return xhr;
}
function callServer(){
var userName = document.getElementById("userName").value();
var url = "test.do?d_name=" + escape(userName);
try{
xmlHttp.open("GET",url, true);
}catch(e){
alert('Request error:'+e);
}
xmlHttp.onreadystatechange=updatePage;
xmlHttp.send(null);
}
function updatePage(){
if(xmlHttp.readyState==4){
var resText = xmlHttp.responseText;
document.getElementById("txtHint").innerHTML= resText ;
}
}
//JS实现trim()
String.prototype.trim = function(){
return this.replace(/(^/s*)|(/s*$)/g, "");
}
好了,即将大功告成了,请将项目部署在tomcat-5.0.28(其他绝大多数版本也是可以的)的webapps下面,启动Tomcat,打开浏览器,在地址栏输入:“http://localhost:8080/AjaxTest/”,如果你配置正确,则会出现一个输入框,请输入任意一个字母,Ajax就会在后台访问数据库,下方显示提示字符串(前提是你数据库里有匹配的),和google的提示输入非常像,是不是很炫呀?
这个例子只是最初步的Ajax应用,只是为了领略一下Ajax的工作方式。在企业级开发中,一般是用到相对成熟的一些Ajax框架的,这样可以大大提高开发效率,并增强安全性与可维护性。目前Ajax的开发框架方兴未艾,比较流行的有Dojo, Prototype, Sajax, DWR(直接Web远程调用,spring的推荐Ajax框架,可在JS中调用Java对象)...以及最近才热起来的JQuery等等。
创建一个名为AjaxTest的Web项目,其根路径为”/AjaxTest“。之后,创建一个JSP文件,内容如下:
<%@ page language="java" import="java.util.*" pageEncoding="GBK"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My Ajaxt Test!</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="Ajax,test,ajax test">
<meta http-equiv="description" content="This is my Ajax Test page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<script type='text/javascript' src='ajaxTest.js'></script>
</head>
<body οnlοad=" initXHR() ;">
<form name="myForm">
Name: < input type="text" id="userName" οnkeyup="callServer()">
<br>
<div id="txtHint" ><b>Delars info will be listed here.</b></div>
</form>
</body>
</html>
然后,创建一个进行数据库访问的JavaBean, 需要说明的是,这个小例子使用的数据库是postgreeSQL,如果使用不同的数据库,请修改成相应的连接字符串。另外请将你的数据库的连接驱动包放到WEB-INF下的lib目录下。
package com.ajax.db;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class DbConn {
private Connection connect = null;
private Statement statement = null;
private String connect_url = "jdbc:postgresql://localhost:5432/testDB";
private String user_name = "chrome";
private String password = "ch";
public DbConn(){
}
public void setUserName(String user_name) {
this.user_name = user_name;
}
public Connection getConnect() {
return connect;
}
public void setConnect(Connection connect) {
this.connect = connect;
}
public String getConnectUrl() {
return connect_url;
}
public void setConnectUrl(String url) {
this.connect_url = url;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Statement getStatement() {
return statement;
}
public void setStatement(Statement statement) {
this.statement = statement;
}
public String getUserName() {
return user_name;
}
public void initConn() {
try{
Class.forName("org.postgresql.Driver");
}catch(ClassNotFoundException e){
e.printStackTrace();
}
if(connect==null||statement==null){
try{
connect = DriverManager.getConnection(connect_url,user_name,password);
statement = connect.createStatement();
}catch(SQLException se){
se.printStackTrace();
}
}
}
public ResultSet execQuery(String sql) {
if(statement==null){
this.initConn();
}
ResultSet rs =null;
try{
rs = statement.executeQuery(sql);
}catch(SQLException e){
e.printStackTrace();
}
return rs;
}
public List query(String sql){
if(statement==null){
this.initConn();
}
List<String> list = new ArrayList<String>();
try{
ResultSet rs = statement.executeQuery(sql);
while(rs.next()){
list.add(rs.getString(1));
}
}catch(SQLException e){
e.printStackTrace();
}
return list;
}
public List queryMatch(String sql,String match){
if(connect==null){
this.initConn();
}
List<String> list = new ArrayList<String>();
try{
if(match!=null&&!"".equals(match.trim())){
PreparedStatement ps = connect.prepareStatement(sql);
ps.setString(1, match.trim()+"%");
ResultSet rs = ps.executeQuery();
int i = 0;
while(rs.next()&&i<50){
list.add(rs.getString(1));
i++;
}
}
}catch(SQLException e){
e.printStackTrace();
return null;
}
return list;
}
public void destroy(){
try{
statement.close();
connect.close();
}catch(SQLException se){
try{
if(statement!=null){
statement.close();
}
if(connect!=null){
connect.close();
}
}catch(SQLException e){
e.printStackTrace();
}
}
finally{
statement=null;
connect=null;
}
}
public static void main(String[] args){
DbConn dc = new DbConn();
String sql = "";
sql = "select distinct/ "name/" from /"user_info/" where /"name/" like ? order by /"name/" ";
List list = dc.queryMatch(sql, "B");
dc.destroy();
//System.out.println(list.size()+" dealers : "+list);
for(int i=0;i<10&&i<list.size();i++){
System.out.println(list.get(i));
}
}
}
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class DbConn {
private Connection connect = null;
private Statement statement = null;
private String connect_url = "jdbc:postgresql://localhost:5432/testDB";
private String user_name = "chrome";
private String password = "ch";
public DbConn(){
}
public void setUserName(String user_name) {
this.user_name = user_name;
}
public Connection getConnect() {
return connect;
}
public void setConnect(Connection connect) {
this.connect = connect;
}
public String getConnectUrl() {
return connect_url;
}
public void setConnectUrl(String url) {
this.connect_url = url;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Statement getStatement() {
return statement;
}
public void setStatement(Statement statement) {
this.statement = statement;
}
public String getUserName() {
return user_name;
}
public void initConn() {
try{
Class.forName("org.postgresql.Driver");
}catch(ClassNotFoundException e){
e.printStackTrace();
}
if(connect==null||statement==null){
try{
connect = DriverManager.getConnection(connect_url,user_name,password);
statement = connect.createStatement();
}catch(SQLException se){
se.printStackTrace();
}
}
}
public ResultSet execQuery(String sql) {
if(statement==null){
this.initConn();
}
ResultSet rs =null;
try{
rs = statement.executeQuery(sql);
}catch(SQLException e){
e.printStackTrace();
}
return rs;
}
public List query(String sql){
if(statement==null){
this.initConn();
}
List<String> list = new ArrayList<String>();
try{
ResultSet rs = statement.executeQuery(sql);
while(rs.next()){
list.add(rs.getString(1));
}
}catch(SQLException e){
e.printStackTrace();
}
return list;
}
public List queryMatch(String sql,String match){
if(connect==null){
this.initConn();
}
List<String> list = new ArrayList<String>();
try{
if(match!=null&&!"".equals(match.trim())){
PreparedStatement ps = connect.prepareStatement(sql);
ps.setString(1, match.trim()+"%");
ResultSet rs = ps.executeQuery();
int i = 0;
while(rs.next()&&i<50){
list.add(rs.getString(1));
i++;
}
}
}catch(SQLException e){
e.printStackTrace();
return null;
}
return list;
}
public void destroy(){
try{
statement.close();
connect.close();
}catch(SQLException se){
try{
if(statement!=null){
statement.close();
}
if(connect!=null){
connect.close();
}
}catch(SQLException e){
e.printStackTrace();
}
}
finally{
statement=null;
connect=null;
}
}
public static void main(String[] args){
DbConn dc = new DbConn();
String sql = "";
sql = "select distinct/ "name/" from /"user_info/" where /"name/" like ? order by /"name/" ";
List list = dc.queryMatch(sql, "B");
dc.destroy();
//System.out.println(list.size()+" dealers : "+list);
for(int i=0;i<10&&i<list.size();i++){
System.out.println(list.get(i));
}
}
}
接下来, 将servlet2.3的jar也放到lib目录下。 创建一个Servlet,实现服务端的处理。这个Sevlet源码如下:
package com.ajax.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.ajax.db.DbConn;
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String d_name = request.getParameter("d_name");
List list = null;
if(d_name!=null&&!"".equals(d_name.trim())){
DbConn conn = new DbConn();
conn.setConnectUrl("jdbc:postgresql://localhost:5432/testDB");
list = new ArrayList();
String sql = "select distinct/ "name/" from /"user_info/" where upper( /"name/" ) like ? order by /"name/" ";
list = conn.queryMatch(sql,d_name.toUpperCase());
conn.destroy();
}
if(list!=null&&list.size()>0){
response.setHeader("Cache-Control", "no-cache");
response.getWriter().write("<table>");
//reurn first 15 record
for(int i=0;i<list.size()&&i<15;i++){
response.getWriter().write("<tr><td><font color="green">"+list.get(i)+"</font></td></tr>");
}
response.getWriter().write("</table>");
response.getWriter().flush();
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}
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.ajax.db.DbConn;
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String d_name = request.getParameter("d_name");
List list = null;
if(d_name!=null&&!"".equals(d_name.trim())){
DbConn conn = new DbConn();
conn.setConnectUrl("jdbc:postgresql://localhost:5432/testDB");
list = new ArrayList();
String sql = "select distinct/ "name/" from /"user_info/" where upper( /"name/" ) like ? order by /"name/" ";
list = conn.queryMatch(sql,d_name.toUpperCase());
conn.destroy();
}
if(list!=null&&list.size()>0){
response.setHeader("Cache-Control", "no-cache");
response.getWriter().write("<table>");
//reurn first 15 record
for(int i=0;i<list.size()&&i<15;i++){
response.getWriter().write("<tr><td><font color="green">"+list.get(i)+"</font></td></tr>");
}
response.getWriter().write("</table>");
response.getWriter().flush();
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}
配置WEB-INF目录下的web.xml,其内容参照如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app id="Ajax_Test">
<display-name>Ajax_Test</display-name>
<servlet>
<servlet-name>TestServlet</servlet-name>
<display-name>TestServlet</display-name>
<description>Test servlet</description>
<servlet-class>com.ajax.servlet.TestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet</servlet-name>
<url-pattern>/test.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
好了,让我们再看一下关键的ajaxTest.js文件,看看怎样用Ajax实现远程访问(对服务器端的访问,并取得数据)。Ajax的核心技术是使用一个叫做XMLHttpRequest对象。这并不是一个新对象,很多浏览器都在Ajax这个名词诞生之前都拥有了她,但实现的方式各有不同。请通过源例子代码查看其区别,IE一般是通过ActiveXObject实现,且不同版本名称可能不同,而FireFox等浏览器则直接有了这个对象(据说IE7也实现了)。 ajaxTest.js的内容如下:
var xmlHttp;
function initXHR(){
xmlHttp = getXmlHttpRequest();
}
function getXmlHttpRequest(){
var xhr;
// Internet Explorer
try{
xhr = new ActiveXObject("Microsoft.XMLHTTP"); //IE5+
}catch(e){
try{
xhr = new ActiveXObject("Msxml2.XMLHTTP");//IE5-
}catch(er){
xhr = false;
}
}
if(!xhr && typeof XMLHttpRequest != 'undefined'){
try{
// Firefox, Opera 8.0+, Safari
xhr = new XMLHttpRequest();
}catch(e){
alert("Your browser dose not support Ajax!");
}
}
return xhr;
}
function callServer(){
var userName = document.getElementById("userName").value();
var url = "test.do?d_name=" + escape(userName);
try{
xmlHttp.open("GET",url, true);
}catch(e){
alert('Request error:'+e);
}
xmlHttp.onreadystatechange=updatePage;
xmlHttp.send(null);
}
function updatePage(){
if(xmlHttp.readyState==4){
var resText = xmlHttp.responseText;
document.getElementById("txtHint").innerHTML= resText ;
}
}
//JS实现trim()
String.prototype.trim = function(){
return this.replace(/(^/s*)|(/s*$)/g, "");
}
好了,即将大功告成了,请将项目部署在tomcat-5.0.28(其他绝大多数版本也是可以的)的webapps下面,启动Tomcat,打开浏览器,在地址栏输入:“http://localhost:8080/AjaxTest/”,如果你配置正确,则会出现一个输入框,请输入任意一个字母,Ajax就会在后台访问数据库,下方显示提示字符串(前提是你数据库里有匹配的),和google的提示输入非常像,是不是很炫呀?
这个例子只是最初步的Ajax应用,只是为了领略一下Ajax的工作方式。在企业级开发中,一般是用到相对成熟的一些Ajax框架的,这样可以大大提高开发效率,并增强安全性与可维护性。目前Ajax的开发框架方兴未艾,比较流行的有Dojo, Prototype, Sajax, DWR(直接Web远程调用,spring的推荐Ajax框架,可在JS中调用Java对象)...以及最近才热起来的JQuery等等。