转自:
http://www.blogjava.net/daizhenghenry/archive/2008/05/21/201987.html
--
创建查询信息表
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
xmlns
="http://www.w3.org/1999/xhtml"
>
<
head
>
<
title
>
模拟搜索引擎
</
title
>
<
style
type
="text/css"
>
html
{
filter:progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
}
</
style
>
<
script
type
='text/javascript'
src
='/ajaxTest/dwr/interface/history.js'
></
script
>
<
script
type
='text/javascript'
src
='/ajaxTest/dwr/engine.js'
></
script
>
<
script
type
='text/javascript'
src
='/ajaxTest/dwr/util.js'
></
script
>
<
script
language
="javascript"
>
/*处理用户相关搜索*/
function change(data){
//得到表格中的行数
var count = document.getElementById('tab').rows.length;
//如果表中存在行,将所有行删除
if(count >0){
for(var i=count-1;i>=0;i--){
document.getElementById('tab').deleteRow(i);
}
}
//如果存在相关搜索记录
if(data.length > 0){
document.getElementById('Related').style.display = '';
document.getElementById('x').style.display = '';
for(var i=0;i<data.length;i++){
var objTr = document.getElementById('tab').insertRow();
var objTd1 = objTr.insertCell(0);
objTd1.innerHTML = "<input readonly type='text' "
+"size='35' name='txtHistory' style='border:none;background:#FFFFFF'"
+" value='"+data[i].content+"' onmouseover='overChangeColor(this)'"
+" onmouseleave='leaveChangeColor(this)' "
+"onclick='clickHistory(this)'>";
var objTd2 = objTr.insertCell(1);
objTd2.innerHTML = "<input type='text' name='result' readonly"
+" size='15' style='border:none;background:#FFFFFF;text-align:right'"
+" value='"+data[i].count+"结果"+"' align='right'/>";
objTd2.align = 'right';
}
}else{
document.getElementById('Related').style.display = 'none';
}
}
/*关闭历史查询记录*/
function myClose(){
document.getElementById('Related').style.display = 'none';
}
/*鼠标在相关搜索内容上方时执行*/
function overChangeColor(object){
var histories = document.getElementsByName('txtHistory');
for(var i=0;i<histories.length;i++){
//如果当前鼠标停留在某一行上
if(histories[i].style.background == '#ccffcc'){
histories[i].style.background = '#FFFFFF';
var tdObj1 = histories[i].parentElement;//td
var trObj1 = tdObj1.parentElement;//tr
var childObj1 = trObj1.childNodes(1);
var x1 = childObj1.childNodes(0);
x1.style.background = '#FFFFFF';
break;
}
}
object.style.background = '#CCFFCC';
var tdObj = object.parentElement;//td
var trObj = tdObj.parentElement;//tr
var childObj = trObj.childNodes(1);
var x = childObj.childNodes(0);
x.style.background = '#CCFFCC';
}
/*鼠标离开相关搜索内容上方时执行*/
function leaveChangeColor(object){
object.style.background = '#FFFFFF';
var tdObj = object.parentElement;//td
var trObj = tdObj.parentElement;//tr
var childObj = trObj.childNodes(1);//td
var x = childObj.childNodes(0);//input
x.style.background = '#FFFFFF';
}
/*鼠标点击相关搜索内容时执行*/
function clickHistory(object){
document.frm.content.value = object.value;
document.getElementById('Related').style.display = 'none';
frm.submit();
}
/*用户在搜索框中按键事件处理*/
function keySelectHistory(){
var nKeyCode = window.event.keyCode;
if(nKeyCode == 38 || nKeyCode == 40){
var count = document.getElementById('tab').rows.length;
var tempRowId;//记录鼠标悬浮所在行
var flag = false;//标识是否有已经变色的行
if(count > 0 && (nKeyCode == 38 || nKeyCode == 40)){//如果存在相关搜索信息
var histories = document.getElementsByName('txtHistory');
for(var i=0;i<histories.length;i++){
//如果当前鼠标停留在某一行上
if(histories[i].style.background == '#ccffcc'){
tempRowId = i;
flag = true;
break;
}
}
if(!flag){
tempRowId = 0;
}
if(nKeyCode == 38){//向上键
if(tempRowId > 0){
leaveChangeColor(histories[tempRowId]);
overChangeColor(histories[tempRowId - 1]);
document.frm.content.value = (histories[tempRowId - 1]).value;
}else{
leaveChangeColor(histories[0]);
overChangeColor(histories[count - 1]);
document.frm.content.value = (histories[count - 1]).value;
}
}else if(nKeyCode == 40){//向下键
if(tempRowId == 0 && histories[0].style.background != '#ccffcc'){
overChangeColor(histories[0]);
document.frm.content.value = histories[0].value;
}else if(tempRowId < count -1){
leaveChangeColor(histories[tempRowId]);
overChangeColor(histories[tempRowId + 1]);
document.frm.content.value = (histories[tempRowId + 1]).value;
}else{
leaveChangeColor(histories[tempRowId]);
overChangeColor(histories[0]);
document.frm.content.value = histories[0].value;
}
}
}
}else{//搜索框内容发生改变时(手动使其变化,而非通过上下键)
var str = document.frm.content.value;
history.getHistory(str,change);
}
}
</
script
>
</
head
>
<
body
>
<
b
>
模拟搜索引擎
</
b
>
<
br
/>
<
form
action
="ServletX"
name
="frm"
method
="post"
>
<
img
alt
="逝者安息,生者坚强"
src
="images/daonian.gif"
/>
<
br
/>
<
br
/>
<
input
type
="hidden"
name
="model"
value
="search"
/>
<
input
type
="text"
size
="55"
name
="content"
onkeyup
="keySelectHistory()"
/>
<
input
type
="submit"
value
="搜索"
/>
<
div
id
="Related"
style
="border:1px solid #f990033;display:'none';width:335;"
>
<
table
id
="tab"
cellpadding
="0"
border
="0"
cellspacing
="0"
>
</
table
>
<
a
id
="x"
href
='javascript:;'
onclick
='myClose()'
style
="display:none"
>
关闭
</
a
>
</
div
>
</
form
>
</
body
>
</
html
>
尽情享受dwr为我们开发ajax带来的畅爽吧!
上周末听了在用友工作的两个学长的一个小讲座,虽然时间不长,但还是有些收获的,其中一个开发部的经理就提到了一些小的技术点,其中就包括dwr,回家后上网查了查相关资料,了解到dwr是一个java开源框架,它的诞生就是为了降低开发ajax的难度,原理类似于在javascript中调用java类,于是就使用dwr技术模拟Google首页做了个练习。由于正直全国哀悼日,页面效果与各大网站相同,采用灰色样式,在这里祝愿遭受灾难的亲人们早日重建家园。
运行效果如图:
后台数据库为Oracle:









































































创建控制器ServletX.java,本例中只是判断用户的搜索操作是否成功,并以控制台的形式输出
































































































































































































































































































































































































