模拟Google首页(dwr实现ajax)

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

运行效果如图:

后台数据库为Oracle:

--创建查询信息表
create table searchInfo
(
  id 
number not null primary key,--编号
  content varchar2(100not 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>
                
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                
<id="x" href='javascript:;' onclick='myClose()'
                    
style="display:none">关闭</a>
            
</div>
        
</form>
    
</body>
</html>
尽情享受dwr为我们开发ajax带来的畅爽吧!

posted on 2008-05-21 18:37 非凡DZ 阅读(3840) 评论(15)  编辑  收藏 所属分类: J2EE

评论

# re: 模拟Google首页(dwr实现ajax) 2008-05-21 18:59 天天基金网

不错,学习中~~~~  回复  更多评论   

# re: 模拟Google首页(dwr实现ajax)[未登录] 2008-05-21 21:45 wst302

学习,dwr倒是经常用,主要看看下拉框的显示  回复  更多评论   

# re: 模拟Google首页(dwr实现ajax) 2008-05-22 18:33 wenlin

iso8859-1 有这个编码么?
好像是 iso-8859-1 吧  回复  更多评论   

# re: 模拟Google首页(dwr实现ajax) 2008-05-22 21:08 银河使者

study  回复  更多评论   

# re: 模拟Google首页(dwr实现ajax) 2008-05-24 17:49 sh

这么简单一个需求被你实现的如此复杂,也算是一种学习了。。。  回复  更多评论   

# re: 模拟Google首页(dwr实现ajax) 2008-05-24 18:57 非凡DZ

当初在动态创建<tr>时,是想直接写<tr>对象的事件来实现鼠标悬浮来着,可就是没效果,到现在还有点不明白,所以只好采用通过文本框的事件再向上找对象的方式来实现,除了这点确实是复杂了点,其他地方还真没想到哪里复杂了,还请这位朋友明示阿 呵呵  回复  更多评论   

# re: 模拟Google首页(dwr实现ajax) 2008-05-27 09:54 zhouyanhui

挺好的! 支持!  回复  更多评论   

# re: 模拟Google首页(dwr实现ajax) 2008-06-03 09:24 zyhxl66

初学dwr 你的这几个js
/ajaxTest/dwr/interface/history.js
/ajaxTest/dwr/engine.js
/ajaxTest/dwr/util.js
是哪的,从哪里可以得到!  回复  更多评论   

# re: 模拟Google首页(dwr实现ajax) 2008-06-03 09:55 非凡DZ

在你对dwr.xml配置完成后,进入测试页面,页面上就有这几个路径,你直接复制到你想应用的页面就行了  回复  更多评论   

# re: 模拟Google首页(dwr实现ajax) 2008-06-05 13:33 zyhxl66

我访问测试地址后 http://localhost:8001/zyhxl66/dwr/index.html
页面上出现这些
Classes known to DWR:
Other Links
Up to top level of web app.
没有出现你所说的那几个js   回复  更多评论   

# re: 模拟Google首页(dwr实现ajax) 2008-06-05 13:54 非凡DZ

测试页到这层即可 http://localhost:8001/zyhxl66/dwr
不用再向下了 页面会出现所有你公开的可供javascript调用的方法
<script type='text/javascript' src='/ajaxTest/dwr/engine.js'></script>
<script type='text/javascript' src='/ajaxTest/dwr/util.js'></script>
除了这两项 都是你定义的 你想在哪个页面用什么方法 你就根据实际情况选择就行了
  回复  更多评论   

# re: 模拟Google首页(dwr实现ajax) 2008-06-05 14:30 zyhxl66

好像是我程序少 jar包 你有qq msn 吗 我的 106054541 zyhbrave@hotmail.com
  回复  更多评论   

# re: 模拟Google首页(dwr实现ajax) 2008-08-30 21:36 桃花岛主

我是一个初学者,感谢楼主,正是我想要的,我也学到了东西啦.  回复  更多评论   

# re: 模拟Google首页(dwr实现ajax) 2009-06-24 17:36 123

1222  回复  更多评论   

# re: 模拟Google首页(dwr实现ajax) 2009-09-02 09:14 ss

好贴 大家顶起来  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
<2009年6月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

导航

统计

常用链接

留言簿(2)

随笔分类(19)

随笔档案(19)

友情链接

搜索

积分与排名

最新评论

阅读排行榜

评论排行榜