模拟Google首页(dwr实现ajax) 弹出补全搜索结果

上周末听了在用友工作的两个学长的一个小讲座,虽然时间不长,但还是有些收获的,其中一个开发部的经理就提到了一些小的技术点,其中就包括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 xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>模拟搜索引擎</title>
        <mce:style type="text/css"><!--
        html 
        {}{
            filter:progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
        } 
    
--></mce:style><style type="text/css" mce_bogus="1">        html 
        {}{
            filter:progid:DXImageTransform.Microsoft.BasicImage(grayscale=1);
        } 
    </style>
        <mce:script type='text/javascript' src="/ajaxTest/dwr/interface/history.js" mce_src="ajaxTest/dwr/interface/history.js"></mce:script>
        <mce:script type='text/javascript' src="/ajaxTest/dwr/engine.js" mce_src="ajaxTest/dwr/engine.js"></mce:script>
        <mce:script type='text/javascript' src="/ajaxTest/dwr/util.js" mce_src="ajaxTest/dwr/util.js"></mce:script>
        <mce: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" mce_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" mce_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);
            }
        }
    
// --></mce:script>
    </head>
    <body>
        <b>模拟搜索引擎</b>
        <br />
        <form action="ServletX" name="frm" method="post">
            <img alt="逝者安息,生者坚强" src="images/daonian.gif" mce_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:;" mce_href="javascript:;" onclick='myClose()'
                    style="display:none" mce_style="display:none">关闭</a>
            </div>
        </form>
    </body>
</html>

 

 

 

 

 

 

 

 

转载于:https://my.oschina.net/u/3647620/blog/1552316

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值