上周末听了在用友工作的两个学长的一个小讲座,虽然时间不长,但还是有些收获的,其中一个开发部的经理就提到了一些小的技术点,其中就包括dwr,回家后上网查了查相关资料,了解到dwr是一个java开源框架,它的诞生就是为了降低开发ajax的难度,原理类似于在javascript中调用java类,于是就使用dwr技术模拟Google首页做了个练习。由于正直全国哀悼日,页面效果与各大网站相同,采用灰色样式,在这里祝愿遭受灾难的亲人们早日重建家园。
运行效果如图:

后台数据库为Oracle:
--创建查询信息表
create table searchInfo
(
id number not null primary key,--编号
content varchar2(100) not null,--查询内容
count number not null--查询次数
)
--创建序列
create sequence seq_searchInfo;
--创建插入数据的存储过程
create or replace procedure proc_add(vContent varchar2,vResult out varchar2)
as
vCount number;
begin
select count(*) into vCount from searchInfo where content = vContent;
if vCount = 0 then
insert into searchInfo values(seq_searchInfo.Nextval,vContent,1);
else
update searchInfo set count = count + 1 where content = vContent;
end if;
vResult := 'success';
exception
when others then
vResult := 'fail';
end;
首先需要把dwr.jar导入到WEB-INF\lib目录下,然后在web.xml文件中配置DWRServlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<servlet>
<servlet-name>dwr-invoker</servlet-name>
<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet>
<description>
This is the description of my J2EE component
</description>
<display-name>
This is the display name of my J2EE component
</display-name>
<servlet-name>ServletX</servlet-name>
<servlet-class>control.ServletX</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ServletX</servlet-name>
<url-pattern>/ServletX</url-pattern>
</servlet-mapping>
</web-app>

接着需要在WEB-INF\lib目录下创建dwr.xml文件,并对javascript要调用的类进行声明并公开方法,当然默认公开全部方法,需要提到的是,若类方法的参数或返回值为Bean,则还需要使用convert标签
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 2.0//EN" "http://getahead.org/dwr/dwr20.dtd">
<dwr>
<allow>
<create creator="new" javascript="history">
<param name="class" value="operation.OperSearchInfo" />
<include method="getHistory" />
</create>
<convert converter="bean" match="entity.SearchInfo">
<param name="include" value="content,count" />
</convert>
</allow>
</dwr>
两个xml文件配置好后,可以在地址栏中输入
http://localhost:9527/工程名/dwr进行测试,若测试成功,将显示可用的类及其方法
创建控制器ServletX.java,本例中只是判断用户的搜索操作是否成功,并以控制台的形式输出
package control;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import operation.*;


public class ServletX extends HttpServlet
{

private static final long serialVersionUID = 1L;


public ServletX()
{
super();
}


public void destroy()
{
super.destroy(); // Just puts "destroy" string in log
// Put your code here
}

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException
{
String model = request.getParameter("model");

if(model.equals("search"))
{
String content = Translation.transCode(request.getParameter("content"));
OperSearchInfo obj = new OperSearchInfo();

if(obj.search(content))
{
System.out.println("success");

}else
{
System.out.println("fail");
}
}
}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException
{
this.doGet(request, response);
}


public void init() throws ServletException
{
// Put your code here
}
}

创建与数据库表对应的实体Bean,SearchInfo.java文件
package entity;


/** *//**
* 搜索信息表实体
* @author 非凡DZ
*
*/

public class SearchInfo
{
private int id;//编号
private String content;//查询内容
private int count;//查询次数

public String getContent()
{
return content;
}

public void setContent(String content)
{
this.content = content;
}

public int getCount()
{
return count;
}

public void setCount(int count)
{
this.count = count;
}

public int getId()
{
return id;
}

public void setId(int id)
{
this.id = id;
}
}

创建对数据库表searchInfo进行操作的类OperSearchInfo.java及方法
package operation;

import java.sql.*;
import java.util.*;
import db.DataBase;
import entity.SearchInfo;

/** *//**
* 该类包含对searchInfo表所有操作
* @author 非凡DZ
*
*/

public class OperSearchInfo
{

/** *//**
* 用户点击搜索按钮后执行
* @param content
* @return
*/

public boolean search(String content)
{
boolean flag = false;
DataBase db = new DataBase();
Connection con = db.getConnection();
CallableStatement cs = null;

try
{
cs = con.prepareCall("{call proc_add(?,?)}");
cs.setString(1, content);
cs.registerOutParameter(2, java.sql.Types.CHAR);
cs.execute();

if(cs.getString(2).equals("success"))
{
flag = true;
}

}catch(Exception e)
{
System.out.println("proc异常"+e.getMessage());
e.printStackTrace();

}finally
{

try
{
con.close();

}catch(Exception ex)
{
System.out.println("关闭连接异常"+ex.getMessage());
ex.printStackTrace();
}
}
return flag;
}

/** *//**
* 获得与界面文本框中信息相似的前10条信息
* @param content 界面文本框中的数据
* @return 相似信息
*/

public ArrayList getHistory(String content)
{
DataBase db = new DataBase();
Connection con = db.getConnection();
ResultSet rs = null;
ArrayList<SearchInfo> aryResult = new ArrayList<SearchInfo>();
String sql = "select content,count from searchInfo where content"
+" like ? and rownum <= 10 order by count desc";

try
{

if(!content.equals(""))
{
PreparedStatement pstn = con.prepareStatement(sql);
pstn.setString(1, content+"%");
rs = pstn.executeQuery();

while(rs.next())
{
SearchInfo info = new SearchInfo();
info.setContent(rs.getString(1));
info.setCount(rs.getInt(2));
aryResult.add(info);
}
}

}catch(Exception e)
{
System.out.println("获得历史查询信息异常"+e.getMessage());
e.printStackTrace();

}finally
{

try
{
con.close();

}catch(Exception ex)
{
System.out.println("关闭连接异常"+ex.getMessage());
ex.printStackTrace();
}
}
return aryResult;
}
}

Translation类用于处理数据传输的编码问题
package operation;

import java.io.*;


/** *//**
* 该类用于解决编码问题
* @author 非凡DZ
*
*/

public class Translation
{

public Translation()
{
}


public static String transCode(String str)
{
String temp = null;

if(str == null)
{
temp = "";
}

try
{
temp = new String(str.getBytes("iso8859-1"), "utf-8");

} catch (UnsupportedEncodingException ex)
{
}
return temp;
}
}

DataBase用于获得数据库连接
package db;

import java.sql.*;

/** *//**
* 该类用于获取数据库连接
* @author 非凡DZ
*
*/

public class DataBase
{
private Connection con;
private String driver = "oracle.jdbc.driver.OracleDriver";
private String url = "jdbc:oracle:thin:@localhost:1521:daizhenghenry";
private String uid = "daizheng";
private String pwd = "daizheng";

public Connection getConnection()
{

try
{
Class.forName(driver);
con = DriverManager.getConnection(url, uid, pwd);

}catch(Exception e)
{
System.out.println("连接异常"+e.getMessage());
e.printStackTrace();
}
return con;
}
}

最后是jsp页面

<%
@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html