Servlet+Ajax实现简单的搜索框智能提示


数据库连接信息
driver=com.mysql.jdbc.Driver //数据库连接驱动
url=jdbc:mysql://127.0.0.1:3306/searchofkeyword?useUnicode=true&characterEncoding=utf-8 //连接url
user=root //账户名
password=root //密码

mybatis配置信息

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">

<!-- 通过这个配置文件完成mybatis与数据库的连接 -->
<configuration>

	<!-- 引入 database.properties 文件-->
	<properties resource="database.properties"/>
	
	<!--类型别名-->  
	<typeAliases>
	 	<package name="cn.pojo"/>
	</typeAliases>
	
	<environments default="development">
		<environment id="development">
			<!--配置事务管理,采用JDBC的事务管理  -->
			<transactionManager type="JDBC"></transactionManager>
			<!-- POOLED:mybatis自带的数据源,JNDI:基于tomcat的数据源 -->
			<dataSource type="POOLED">
				<property name="driver" value="${driver}"/>
				<property name="url" value="${url}"/>
				<property name="username" value="${user}"/>
				<property name="password" value="${password}"/>
			</dataSource>
		</environment>
	</environments>
	
	<!-- 将mapper文件加入到配置文件中 -->
	<mappers>
		<mapper resource="cn/dao/SearchDaoMapper.xml"/>
	</mappers>
</configuration>

Dao层

package cn.dao;

import java.util.List;

import cn.pojo.search;

public interface ISearchDao {
	/**
	 * 查询全部
	 * @param name
	 * @return
	 */
	List<search> getList();
}

Mapper映射文件

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.dao.ISearchDao">
	<select id="getList" resultType="search" >
		select name from search 
	</select>
</mapper>

pojo

package cn.pojo;

public class search {
	private Integer id;
	private String name;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
}

service及实现类

package cn.service;

import java.util.List;

import cn.pojo.search;

public interface ISearchService {
	/**
	 * 查询全部
	 * @param name
	 * @return
	 */
	List<search> getList();
}

package cn.service.impl;

import java.util.List;

import cn.dao.ISearchDao;
import cn.pojo.search;
import cn.service.ISearchService;
import cn.utils.MyBatisUtil;

public class ISearchServiceImpl implements ISearchService {
	
	@Override
	public List<search> getList() {
		List<search> list = MyBatisUtil.getSqlSession().getMapper(ISearchDao.class).getList();
		return list;
	}

}

servlet

package cn.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.pojo.search;
import cn.service.impl.ISearchServiceImpl;

import net.sf.json.JSONArray;

public class SearchServlet extends HttpServlet {
		//static List<String> datas = new ArrayList<String>();
		/*static{
			datas.add("ajax");
			datas.add("ajax-post");
			datas.add("beel");
			datas.add("colection");
			datas.add("cav");
			
		}*/
		private ISearchServiceImpl issi = new ISearchServiceImpl();
		List<search> datas = issi.getList();
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		
		response.setContentType("text/html;charset=utf-8");
		request.setCharacterEncoding("utf-8");
		PrintWriter out = response.getWriter();
		
		//1.获得前台传输的关键字
		String keyword = request.getParameter("keyword");
		//2.处理数据
		List<String> listdata = getDatas(keyword);
		//3.返回json格式
		//System.out.println(JSONArray.fromObject(listdata).toString());
		response.getWriter().write(JSONArray.fromObject(listdata).toString());
		
		out.flush();
		out.close();
	}
		public List<String> getDatas(String keyword) {
			List<String> list = new ArrayList<String>();
			for (search da : datas) {
				if (da.getName().contains(keyword)) {
					list.add(da.getName());
				}
			}
			return list;
		}
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
			doGet(request, response);
	}

}

mybatisUtils

package cn.utils;



import java.io.IOException;  
import java.io.Reader;  
import org.apache.ibatis.io.Resources;  
import org.apache.ibatis.session.SqlSession;  
import org.apache.ibatis.session.SqlSessionFactory;  
import org.apache.ibatis.session.SqlSessionFactoryBuilder;  
  
/** 
 * 工具类 
 */  
public class MyBatisUtil {  
    private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();  
    private static SqlSessionFactory sqlSessionFactory;  
    /** 
     * 加载位于src/mybatis-config.xml配置文件 
     */  
    static{  
        try {  
            Reader reader = Resources.getResourceAsReader("mybatis-config.xml");  
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);  
        } catch (IOException e) {  
            e.printStackTrace();  
            throw new RuntimeException(e);  
        }  
    }  
    /** 
     * 禁止外界通过new方法创建  
     */  
    private MyBatisUtil(){}  
    /** 
     * 获取SqlSession 
     */  
    public static SqlSession getSqlSession(){  
        //从当前线程中获取SqlSession对象  
        SqlSession sqlSession = threadLocal.get();  
        //如果SqlSession对象为空  
        if(sqlSession == null){  
            //在SqlSessionFactory非空的情况下,获取SqlSession对象  
            sqlSession = sqlSessionFactory.openSession();  
            //将SqlSession对象与当前线程绑定在一起  
            threadLocal.set(sqlSession);  
        }  
        //返回SqlSession对象  
        return sqlSession;  
    }  
    /** 
     * 关闭SqlSession与当前线程分开 
     */  
    public static void closeSqlSession(){  
        //从当前线程中获取SqlSession对象  
        SqlSession sqlSession = threadLocal.get();  
        //如果SqlSession对象非空  
        if(sqlSession != null){  
            //关闭SqlSession对象  
            sqlSession.close();  
            //分开当前线程与SqlSession对象的关系,目的是让GC尽早回收  
            threadLocal.remove();  
        }  
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <display-name></display-name>
  <servlet>
    <servlet-name>SearchServlet</servlet-name>
    <servlet-class>cn.servlet.SearchServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>SearchServlet</servlet-name>
    <url-pattern>/SearchServlet</url-pattern>
  </servlet-mapping>	
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
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%>">
    <script type="text/javascript" src="static/jquery-1.8.3.min.js"></script>
    <style type="text/css">
    	#mydiv{
    		positon:absolute;
    		left:50%;
    		top:50%;
    		margin-left:450px;
    		margin-top:200px;
    	}
    	.mouseOver{
    		background:#708090;
    		color:#FFFAFA
    	}
    	.mouseOut{
    		background:#FFFAFA;
    		color:#000000;
    	}
    </style>
  	<script type="text/javascript">
  		var xmlHttp;
  		//获得用户输入内容的关联信息的函数
  		function getMore(){
  			//1.获得用户输入的内容
  			var content = $("#keyword").val();
  			if (content == null) {
  				clearContent();
				return;
			}
			//2. 给服务器发送用户输入的内容,采用ajax异步提交,使用xmlHttp对象
			xmlHttp = createXMLHttp();
			//alert(xmlHttp);
			
			//3.要给服务器发送数据
			var url = "SearchServlet?keyword="+escape(content);
			//参数true表示JavaScript脚本会在send()方法之后继续执行,而不会等待来自服务器的响应。
			xmlHttp.open("GET",url,true);
			
			//xmlHttp绑定回调方法,这个回调方法会在xmlHttp状态发生改变后被调用;
			//xmlHttp有四种状态0-4,状态0:未初始化(生成xmlHttp对象等一系列初始动作);状态1:正在加载(请求服务器资源)
			//状态2:已加载(资源存在请求成功);状态3:交互(与服务器交互中,接收资源);状态4:完成(完成)
			//我们只关心4这种状态,因为只有数据传输完成后调用这个回调方法才有意义
			xmlHttp.onreadystatechange = callback;
			xmlHttp.send(null);




  		}
  		//获得xmlHttp对象
  		function createXMLHttp(){
  		//对于大多数的浏览器都适用
  			var xmlHttp;
  			if (window.XMLHttpRequest) {
				xmlHttp = new XMLHttpRequest();
			}
		//考虑浏览器的兼容性	
			if (window.ActiveXObject) {
				xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
				if (!xmlHttp) {
					xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
				}
			}
			return xmlHttp;
  		}
  		//回调函数
  		function callback(){
  			//状态4代表已完成
  			if (xmlHttp.readyState == 4) {
				//200代表服务器响应成功 
				if (xmlHttp.status == 200) {
					//交互成功,获得响应的文本格式的数据;
					var result = xmlHttp.responseText;
					//解析获得数据,加上小括号是为了能让js识别出这是json字符串
					var json = eval("("+result+")");
					//获得数据之后就可以动态的在输入框下面展示数据了
					//alert(json);
					setContent(json);
				}
			}
  		}
  		
  		//设置关联数据的展示 	,参数代表的是服务器传输过来的数据 
  		function setContent(contents){
  			//在设置内容之前先清空之前的数据
  			clearContent();
  			//设置关联信息的显示的位置
  			setLocation();
  			//首先获得关联数据的长度,以此确定生成多少个<tr></tr>
  			var size = contents.length;
  			
  			for ( var i = 0; i < size; i++) {
				var nextNode = contents[i];
				var tr = document.createElement("tr");
			
				var td = document.createElement("td");
				
				td.setAttribute("border","0");
				
				td.setAttribute("bgcolor","#FFFAFA");
				td.onmouseover = function(){
					this.className = 'mouseOver';
				};
				td.onmouseout = function(){
					this.className = 'mouseOut';
				};
				td.onclick = function(){
					//这个方法实现的是当鼠标去点击一个关联数据时,输入框的内容设置为所点击的关联数据
				};
				var text = document.createTextNode(nextNode);
				td.appendChild(text);
				tr.appendChild(td);
				document.getElementById("content_table_body").appendChild(tr);	
			}
  		}
  		//清除内容
  		function clearContent(){
  			var contentTableBody = document.getElementById("content_table_body");
  			var size = contentTableBody.childNodes.length;
  			for ( var i = size-1; i >= 0; i--) {
				contentTableBody.removeChild(contentTableBody.childNodes[i]);
			}
			document.getElementById("popDiv").style.border = "none";
  		}
  		//设置位置的方法
  		function setLocation(){
  			//关联信息显示位置要和输入框的位置一致
  			var content = document.getElementById("keyword");
  			var width = content.offsetWidth;//输入框的宽度
  			//alert(width);
  			var left = content["offsetLeft"];
  			var top = content["offsetLeft"] + content.offsetHeight;
  			//获得显示数据的div
  			var popDiv = document.getElementById("popDiv");
  			popDiv.style.border = "black 1px solid";
  			popDiv.left = left + "px";
  			popDiv.top = top + "px";
  			popDiv.width = width + "px";
  			
  			document.getElementById("content_table").style.width = width + "px";
  			document.getElementById("content_table_body").style.width = width + "px";
  			//alert(document.getElementById("content_table").style.width);
  		}
  	</script>
  </head>
  
  <body>
   	<div id="mydiv">
   		<input type="text" style="width:200px" id="keyword" οnkeyup="getMore()" οnblur="clearContent()" οnfοcus="getMore()"/>
   		<input type="button" value="百度一下" style="background-color:#ccc">
   		<!-- 内容展示的区域 -->
   		<div id="popDiv">
   			<table id="content_table" bgcolor="#FFFAFA" border="0" cellspacing="0" cellpadding="0">
   				<tbody id="content_table_body">
   					<!-- 这里用来展示动态查询出来的数据 -->
   					
   				</tbody>
   			</table>
   		</div>
   	</div>
  </body>
</html>
所需JAR放在图片文件

  • 1
    点赞
  • 1
    收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 1

打赏作者

Aaryn30

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值