您的位置:首页 > 其它

AJAX实现百度搜索栏效果

2012-09-13 20:58 686 查看
刚学了AJAX做了个百度浏览器的实现效果,焦点的地方还不太完善,大家凑合看吧。

先上项目截图,大家可以看清项目各种包:



一、数据库

create table sa.selectinfo(
slid number(5) primary key not null,
scontext varchar2(50) not null,
slnum number(6) default 0 not null
)

insert into sa.selectinfo values(1,'为什么我有了奥特曼变身器不能变身?',13);
insert into sa.selectinfo values(2,'为什么月如走了?',123);
insert into sa.selectinfo values(3,'为什么灵儿走了?',33);
insert into sa.selectinfo values(4,'为什么只剩下逍遥一个人?',54);
insert into sa.selectinfo values(5,'为什么最好的心碰不到最好的人?',6);
insert into sa.selectinfo values(6,'为什么天那么黑?',7);
insert into sa.selectinfo values(7,'钓鱼岛是中国的?',8);
insert into sa.selectinfo values(8,'敢不敢不坑爹?',12);
insert into sa.selectinfo values(9,'我只想对你说呵呵!',32);
insert into sa.selectinfo values(10,'java那点事',11);
commit;

select * from sa.selectinfo;


二、com.ajax.servlet下的AjaxServlet.java类,servlet作为中间层负责V层和C层之间的交互

package com.ajax.servlet;

import java.io.IOException;
import java.io.PrintWriter;
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.bean.SelectInfoEntity;
import com.jdbc.manager.SysManager;

public class AjaxServlet extends HttpServlet {

/**
* The doGet method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to get.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);
}

/**
* The doPost method of the servlet. <br>
*
* This method is called when a form has its tag value method equals to post.
*
* @param request the request send by the client to the server
* @param response the response send by the server to the client
* @throws ServletException if an error occurred
* @throws IOException if an error occurred
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//清除缓存
response.setHeader("pragma", "no-cache");
response.setHeader("cache-control","no-cache");

response.setCharacterEncoding("utf-8");
request.setCharacterEncoding("utf-8");
String context=request.getParameter("context");
//有时你jsp页面的编码格式为utf-8,并且在request也设置了编码格式,可是保存之后的文件名还是乱码
//那么就采用下面这个方法,国际编码格式,一定可以包子utf-8格式
String ncontext=new String(context.getBytes("ISO8859-1"),"utf-8");
List<SelectInfoEntity> list=SysManager.getAllSelectInfoByPro(ncontext);
if(list==null||list.size()<1){
return;
}
PrintWriter out = response.getWriter();
StringBuffer sb=new StringBuffer("<select id='tishi' style='width: 100%;height: 100px;' multiple='multiple'>");
for (int i = 0; i < list.size(); i++) {
SelectInfoEntity sin=list.get(i);
sb.append("<option value='"+sin.getScontext()+"'>");
sb.append(sin.getScontext());
sb.append("</option>");
}
sb.append("</select>");
out.print(sb.toString());
out.flush();
out.close();
}

}

三、com.bean包下的SelectInfoEntity.java(实体类)

package com.bean;

import java.math.BigDecimal;

public class SelectInfoEntity {

private BigDecimal slid;
private String scontext;
private BigDecimal slnum;

public BigDecimal getSlid() {
return slid;
}

public void setSlid(BigDecimal slid) {
this.slid = slid;
}
public String getScontext() {
return scontext;
}
public void setScontext(String scontext) {
this.scontext = scontext;
}
public BigDecimal getSlnum() {
return slnum;
}
public void setSlnum(BigDecimal slnum) {
this.slnum = slnum;
}
public SelectInfoEntity(BigDecimal slid, String scontext, BigDecimal slnum) {
super();
this.slid = slid;
this.scontext = scontext;
this.slnum = slnum;
}
public SelectInfoEntity() {
}
}

 

四、com.jdbc.manager包下的SysManager(业务逻辑类)

package com.jdbc.manager;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

import com.bean.SelectInfoEntity;
import com.jdbc.tool.DBHelper;
import com.service.SelectInfoService;

public class SysManager {

private static SelectInfoService selectManager=new SelectInfoService();
public static boolean addNewSelectInfo(Object entity){
return selectManager.insertInfo(entity);
}
public static boolean updSelectInfo(Object entity){
return selectManager.updateInfo(entity);
}
public static List<SelectInfoEntity> getAllSelectInfo(){
return selectManager.getAllInfo();
}
public static List<SelectInfoEntity> getAllSelectInfoByPro(String context){
return selectManager.getAllInfoByPro(context);
}
}

 

五、com.jdbc.tool下的DBHelper(数据库连接池)类

package com.jdbc.tool;

import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class DBHelper {

private static ComboPooledDataSource cpds=new ComboPooledDataSource();
//private static OracleDispose od=new OracleDispose("f:/config.properties");
static {
try {
// 驱动器
cpds.setDriverClass("oracle.jdbc.OracleDriver");
// 数据库url
cpds.setJdbcUrl("jdbc:oracle:thin:@127.0.0.1:1521:ORCL");
//cpds.setJdbcUrl(od.jdbcurl);通过properties动态获取文件中存储的jdbcurl
//用户名
cpds.setUser("sa");
//cpds.setUser(od.username);通过properties动态获取文件中存储的用户名称
//密码
cpds.setPassword("sa");
//cpds.setPassword(od.userpwd);通过properties动态获取文件中存储的用户密码
//初始化连接池的大小
cpds.setInitialPoolSize(30);
//最小连接数
cpds.setMinPoolSize(20);
//最大连接数
cpds.setMaxPoolSize(100);
} catch (PropertyVetoException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
/**
* 用于数据库的链接
* @return 返回Connection
*/
public static Connection getConnection(){

try {
return cpds.getConnection();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
/**
*  用于关闭数据库的关闭
* @param rs ResultSet对象
* @param st Statement对象
* @param con Connection对象
*/
public static void  closeJDBC(ResultSet rs,Statement st,Connection con){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(st!=null){
try {
st.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(con!=null){
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 用于获取指定表明的列对应JAVA中的数据类型。
* @param tablename 指定的表名
* @return 列数据类型的数组
*/
public Class[] getTypeOfJava(String tablename){
Connection con=DBHelper.getConnection();
if(con==null){
return null;
}
Statement st=null;
ResultSet rs=null;
Class[] types=null;
try {
st=con.createStatement();
rs=st.executeQuery("select * from "+tablename);
int count=rs.getMetaData().getColumnCount();
types=new Class[count];
for (int i = 0; i < types.length; i++) {
types[i]=Class.forName(rs.getMetaData().getColumnClassName(i+1));
}
return types;

} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
DBHelper.closeJDBC(rs, st, con);
}
return null;

}
}


 

六、com.service下的Manager.java(抽象管理类,负责架构方法,供其他管理子类使用)和SelectInfoService.java(查询信息管理类)

 1.Manager.java(看过我以前博文的都应该知道这个类,一直都是复制用了)

package com.service;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import com.jdbc.tool.DBHelper;
import com.sun.corba.se.spi.orbutil.fsm.State;

public abstract class Manager {

public abstract boolean insertInfo(Object entity);
public abstract boolean deleteInfo(Object id);
public abstract boolean updateInfo(Object entity);
public abstract Object getAllInfoById(Object id);
public abstract List getAllInfo();

/**
* 根据传入的每页行数返回分页数
* @param tname 要分页的表名
* @param rowcount 每页行数
* @return 分页数
*/
int getPageSize(String tname,int rowcount){
Connection con=DBHelper.getConnection();
if(con==null){
return -1;
}
Statement st=null;
ResultSet rs=null;
try {
st=con.createStatement();
rs=st.executeQuery("select count(*) from "+tname);
int size=-1;
if(rs.next()){
size=rs.getInt(1);
if(size%rowcount==0){
return (size/rowcount);
}

return (size/rowcount)+1;
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
DBHelper.closeJDBC(rs, st, con);
}
return -1;
}
/**
* 用于父类 封装 子类根据对象属性查询的方法
* @param tname  表名
* @param clname  要查询的列名
* @param clvalue 传入的列名的值
* @param cl 用于   指定 实体类  类文件
* @return  查询结果集封装的数据(实体类对象集合)
*/
List getInfoByproperty(String tname,String[] clname,String[] clvalue,Class cl){

String sql="select * from "+tname+" where 0=0 ";
for (int i = 0; i < clname.length; i++) {
sql+=" and "+clname[i]+"=?";
}
return this.getAllInfo(sql, clvalue, cl);

}
/**
* 用于父类 封装 子类根据对象属性查询的方法
* @param tname  表名
* @param clname  要查询的列名
* @param clvalue 传入的列名的值
* @param cl 用于   指定 实体类  类文件
* @return  查询结果集封装的数据(实体类对象集合)
*/
List getInfoLikeproperty(String tname,String[] clname,String[] clvalue,Class cl){

String sql="select * from "+tname+" where 0=0 ";
for (int i = 0; i < clname.length; i++) {
sql+=" and "+clname[i]+"like ?";
}
sql+=" and rownum<5 order order by slnum DESC";
return this.getAllInfo(sql, clvalue, cl);

}
/**
*用于父类 封装 增删改 的方法,以外部传取connection作为连接(可控制事务) 不需要关闭connection
*本方方多用于批处理(结合其他业务一起进行操作)
* @param con 外部获取的connection连接
* @param sql 操作的sql指令
* @param args 参数数组
* @return
*/
boolean updateDB(Connection con,String sql,String[] args){
//获取操作指令装置,并执行sql(可赋值)
PreparedStatement ps=null;
try {
ps=con.prepareStatement(sql);
if(args!=null&&args.length>0){
for (int i = 0; i < args.length; i++) {
ps.setString(i+1, args[i]);
}
}
return ps.executeUpdate()>0 ? true:false;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
DBHelper.closeJDBC(null, ps, null);
}
return false;
}
/**
* 用于父类 封装 增删改 的方法,直接利用重载进行dml的操作(多用于单独执行)
* @param sql 操作的sql指令
* @param args 参数数组
* @return
*/
boolean updateDB(String sql,String[] args){
Connection con=DBHelper.getConnection();
try {
return updateDB(con, sql, args);
} catch (Exception e) {
// TODO: handle exception
}finally{
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

return false;
}

/**
* 用于父类 封装 查询 的方法,供子类调用。
* @param sql  查询语句(select .......)
* @param args  查询条件值(可以为null——基本查询)
* @param cl  用于   指定 集合中封装的 实体类  类文件
* @return  查询结果集封装的数据(实体类对象集合)
*/
List getAllInfo(String sql,String[] args,Class cl){
//获取连接并判断
Connection con=DBHelper.getConnection();
//Connection con=DB_helper.getInstance().getConnection();
if(con==null){
return null;
}
//获取操作指令装置,并执行sql(可赋值)
PreparedStatement ps=null;
ResultSet rs=null;
try {
ps=con.prepareStatement(sql);
if(args!=null){
for (int i = 0; i < args.length; i++) {
ps.setString(i+1, args[i]);
}
}
rs=ps.executeQuery();
//获取 rs 的源数据,从中得到操作表的 列数
int colcount=rs.getMetaData().getColumnCount();
//准备构造方法所用参数的数组,长度为 表 列数
Object[] canshu=new Object[colcount];

//封装返回值的容器
List list=new ArrayList();
//遍历 所有指定 实体类的构造方法,用 参数数组去获取 实体类 对象(如成功,则列值被封装成 对象 属性值)
Object ob=null;

//封装返回值的容器
while(rs.next()){
//将一行 表的数据 封装到 参数数组中
for (int i = 0; i < canshu.length; i++) {
canshu[i]=rs.getObject(i+1);
//可用于查看 Oracle数据库对应的 java 数据类型
//System.out.println(canshu[i].getClass());
}
//
ob=getObject(cl, canshu);
//如成功,则将封装有属性值的对象,放入 list 集合
if(ob==null){
return null;
}
//如成功,则将封装有属性值的对象,放入 list 集合
list.add(ob);
}
return new ArrayList(list);
} catch (Exception e) {

}finally{
DBHelper.closeJDBC(rs, ps, con);
}
return null;
}
/**
* 用于自动封装 行数据成为 指定类对象的方法
* @param cl 传进返回的实体类型
* @param canshu 进行参数匹配的数组
* @return 实体类型
*/
private Object getObject(Class cl,Object[] canshu){
Constructor[] cons=cl.getConstructors();
Object ob=null;
for (int i = 0; i < cons.length; i++) {
try {
ob=cons[i].newInstance(canshu);
return ob;
} catch (Exception e) {
continue;
}
}
return null;
}

}

 2.SelectInfoService.java

package com.service;

import java.math.BigDecimal;
import java.util.List;

import com.bean.SelectInfoEntity;
import com.jdbc.manager.SysManager;

public class SelectInfoService extends Manager{

@Override
public boolean deleteInfo(Object id) {
// TODO Auto-generated method stub
return false;
}

@Override
public List<SelectInfoEntity> getAllInfo() {
String sql="select * from sa.selectinfo";
return this.getAllInfo(sql, null, SelectInfoEntity.class);
}
//根据输入的关键字获得查询次数最高的前5条数据
public List<SelectInfoEntity> getAllInfoByPro(String context){
String sql="select * from sa.selectinfo where scontext like ? and rownum<5 order by slnum DESC";
//%放在什么位置完全按照你的需求,我这里是放在后面。查询你输入内容之后为任意的信息
return this.getAllInfo(sql, new String[]{context+"%"}, SelectInfoEntity.class);
}
@Override
public Object getAllInfoById(Object id) {
// TODO Auto-generated method stub
return null;
}

@Override
public boolean insertInfo(Object entity) {
// TODO Auto-generated method stub
return false;
}

@Override
public boolean updateInfo(Object entity) {
SelectInfoEntity sin=(SelectInfoEntity) entity;
String sql="update sa.selectinfo set slnum=? where slid=?";
String[] args=new String[]{sin.getSlnum()+"",sin.getSlid()+""};

return this.updateDB(sql, args);
}
}


七、jsp界面(index.jsp)

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"  %>
<%
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 JSP 'index.jsp' starting page</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="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body style="text-align: center;">
<table style="width: 400px;margin-top: 50px;" cellspacing="0px" cellpadding="0px" >
<tr>
<td width="300px">
<input type="text"  style="width: 100%;height: 25px" id="context" onkeyup="ajaxgo()">
</td>
<td style=""><input type="button" value="百度一下" ></td>
</tr>
<tr >
<td>
<div id="sl" >
</div>
</td>
<td>
</td>
</tr>
</table>

</body>
<script type="text/javascript">
var ajax;
function createAjax(){
try{
return new ActiveXObject("Microsoft.XMLHTTP");
}catch(e){
return null;
}
}
function ajaxgo(){
document.getElementById("context").focus();
if(window.event.keyCode==40){
var sl=document.getElementById("tishi");
if(sl==null){
return;
}
sl.focus();
sl.options[0].selected="selected";
document.getElementById("context").value=sl.value;
sl.onchange=function(){
document.getElementById("context").value=sl.value;
}
sl.onmousedown=function(){
document.getElementById("sl").innerHTML="";
}
return;
}
document.getElementById("sl").innerHTML="";
var v=document.getElementById("context").value;
if(v==""){
document.getElementById("sl").innerHTML="";
return;
}
ajax=createAjax();
ajax.onreadystatechange=rst;
var url="ajaxservlet?context="+v;
url=window.encodeURI(url);
ajax.open("GET",url,true);
ajax.send(null);
}
function rst(){
if(ajax.readyState==4){
document.getElementById("sl").innerHTML=ajax.responseText;
}
}
</script>
</html>


给大家看一下效果图:



基本上就是这样了按钮的onclick没有做,这个也不是重点,主要是AJAX异步请求的运用。

这个例子有一点没有完善好,就是当选中select中的内容后,焦点应该在text内,没有实现,以后实现了在给大家贴上来。希望大家多多指教。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: