客户关系管理系统之动态搜索栏

来源:互联网 发布:知堂回想录 pdf 编辑:程序博客网 时间:2024/06/06 03:42

还记得我的博客使用自己开发好的JDBC框架来升级客户关系管理系统模块吗?在实际开发中,还有一个很实用的功能,那就是动态搜索栏。现在我们就在使用自己开发好的JDBC框架来升级客户关系管理系统模块的基础上来实现这一功能。
实现这一功能,需要用到东西:

  • 淘宝团队开发出来的KISSY.Suggest 提示补全组件:suggest.js。
  • suggest.js组件依赖的YUI2的yahoo-dom-event.js。

将以上两个js文件弄到项目中,如下:
这里写图片描述
不过在此项目中还要用到reset-grids-min.css文件。
要实现这一功能,需要修改head.jsp页面,改后的页面内容如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>XXX客户关系管理系统</title></head><body style="text-align: center;">    <h1>XXX客户关系管理系统</h1>    <br/>                                                                     <!-- target="main"意思是结果显示到name为main的frame中  -->    <a href="${pageContext.request.contextPath }/AddCustomerServlet" target="main">添加客户</a>    <a href="${pageContext.request.contextPath }/ListCustomerServlet" target="main">查看客户</a>    <a href="${pageContext.request.contextPath }/search.jsp" target="main">搜索</a></body></html>

在WebRoot根目录下新建一个搜索页面——search.jsp。
这里写图片描述
search.jsp页面的内容如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>搜索条</title><link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath }/js/suggest/reset-grids-min.css"><!-- yahoo-dom-event.js文件务必要在suggest.js文件之前,切记!!! --><script type="text/javascript" src="${pageContext.request.contextPath }/js/suggest/yahoo-dom-event.js"></script><script type="text/javascript" src="${pageContext.request.contextPath }/js/suggest/suggest.js"></script><style type="text/css">    #page { padding: 50px 50px 300px; width: 750px; margin: 0 auto; }    #h1, h2, h3 { margin: 1em 0 0.3em; }    #.section { margin-bottom: 50px; }    #.section ol { margin: 5px 20px; }    #.section ol li { list-style: decimal inside; margin: 5px 0; }    .search-input { width: 300px; height: 20px; padding: 5px 2px 0 4px; }    #.search-submit { padding: 4px 10px; margin-left: 5px; }    #input.g-submit { padding: 2px 8px; margin-left: 5px; }    #html { overflow-y: scroll; }</style></head><body>    <div id="page">        <div class="section">            <form name="search" method="get" action="#">                <input name="q" id="q" class="search-input"/>                <button type="submit" class="search-submit">搜索客户</button>            </form>            <script type="text/javascript">                (function() {                    var dataUrl = '${pageContext.request.contextPath}/SearchServlet';                    new KISSY.Suggest('q', dataUrl,                        { autoFocus: true,                          resultFormat: '共%result%个客户'                        });                })();            </script>        </div>    </div></body></html>

注意:yahoo-dom-event.js文件务必要在suggest.js文件之前,切记!!!
在cn.itcast.web.controller包下创建一个Servlet——SearchServlet.java。
这里写图片描述
SearchServlet的具体代码如下:

public class SearchServlet extends HttpServlet {    protected void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setCharacterEncoding("UTF-8");        String key = request.getParameter("q");        /*         * 由于我使用的是Tomcat8服务器,所以request内部默认使用的是UTF-8字符集。         * 因此手工处理get方式提交的中文数据的代码反而是没有必要的。         */        // key = new String(key.getBytes("ISO8859-1"), "UTF-8");        // 从数据库中得到数据        CustomerDaoImpl dao = new CustomerDaoImpl();        List<Searcher> list = dao.search(key);        // 以下代码需要学Ajax才知道        List<String[]> gson = new ArrayList<String[]>();        // 把数据组装成一个Json串        for (Searcher search : list) {            gson.add(new String[]{search.getName(), search.getCount()+""});        }        String result = new Gson().toJson(gson); // google的API,把集合中的数据组装成一个json串        // 写给客户机        response.getWriter().write("KISSY.Suggest.callback({'result':"+result+"})");    }    protected void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        doGet(request, response);    }}

注意:以上代码需要用到google的API,即gson-2.3.jar文件,所以应把gson-2.3.jar文件拷到lib目录下。
这里写图片描述
修改CustomerDaoImpl.java的代码,即新增public List<Searcher> search(String key)方法,改后的代码如下:

public class CustomerDaoImpl implements CustomerDao {    @Override    public void add(Customer c) {        try {            String sql = "insert into customer(id, name,gender,birthday,cellphone,email,preference,type,description) values(?,?,?,?,?,?,?,?,?)";            Object[] params = {c.getId(),c.getName(),c.getGender(),c.getBirthday(),c.getCellphone(),c.getEmail(),c.getPreference(),c.getType(),c.getDescription()};            JdbcUtils.update(sql, params);        } catch (SQLException e) {            throw new DaoException(e);        }    }    @Override    public void update(Customer c) {        try {            String sql = "update customer set name=?,gender=?,birthday=?,cellphone=?,email=?,preference=?,type=?,description=? where id=?";            Object[] params = {c.getName(),c.getGender(),c.getBirthday(),c.getCellphone(),c.getEmail(),c.getPreference(),c.getType(),c.getDescription(),c.getId()};            JdbcUtils.update(sql, params);        } catch (SQLException e) {            throw new DaoException(e);        }    }    @Override    public void delete(String id) {        try {            String sql = "delete from customer where id=?";            Object[] params = {id};            JdbcUtils.update(sql, params);        } catch (SQLException e) {            throw new DaoException(e);        }    }    @Override    public Customer find(String id) {        try {            String sql = "select * from customer where id=?";            Object[] params = {id};            return (Customer) JdbcUtils.query(sql, params, new BeanHandler(Customer.class));        } catch (SQLException e) {            throw new DaoException(e);        }       }    @Override    public List<Customer> getAll() {        try {            String sql = "select * from customer";            Object[] params = { };            return (List) JdbcUtils.query(sql, params, new BeanListHandler(Customer.class));        } catch (SQLException e) {            throw new DaoException(e);        }       }    @Override    // 获取到页面数据和页面大小    public QueryResult pageQuery(int startindex, int pagesize) {        QueryResult qr = new QueryResult();        // 还要进行一次查询,查询出总记录数        try {            String sql = "select * from customer limit ?,?";            Object[] params = {startindex, pagesize};            List list = (List) JdbcUtils.query(sql, params, new BeanListHandler(Customer.class));            qr.setList(list);            sql = "select count(*) from customer";            params = new Object[]{ };            int totalrecord = (Integer) JdbcUtils.query(sql, params, new IntHandler());            qr.setTotalrecord(totalrecord);            return qr;        } catch (SQLException e) {            throw new DaoException(e);        }       }    public List<Searcher> search(String key) {        try {            String sql = "select name,count(name) count from customer where name like ? or name like ? group by name";            Object[] params = {key+"%", "%"+key+"%"};            return (List<Searcher>) JdbcUtils.query(sql, params, new BeanListHandler(Searcher.class));        } catch (SQLException e) {            throw new DaoException(e);        }       }}

在cn.itcast.domain包下创建一个JavaBean——Searcher.java,用来表示搜索对象。
这里写图片描述
一开始我们可能会将该JavaBean设计成:

// 搜索对象public class Searcher {    private String name;    private int count;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getCount() {        return count;    }    public void setCount(int count) {        this.count = count;    }}

至此,算是开发好这一功能,现在运行程序,发现这时会报如下异常:

java.lang.RuntimeException: java.lang.IllegalArgumentException: Can not set int field cn.itcast.domain.Searcher.count to java.lang.Long    at cn.itcast.utils.BeanListHandler.handler(BeanListHandler.java:37)    at cn.itcast.utils.JdbcUtils.query(JdbcUtils.java:119)    at cn.itcast.dao.impl.CustomerDaoImpl.search(CustomerDaoImpl.java:113)    at cn.itcast.web.controller.SearchServlet.doGet(SearchServlet.java:35)    at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1099)    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:670)    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)    at java.lang.Thread.run(Unknown Source)Caused by: java.lang.IllegalArgumentException: Can not set int field cn.itcast.domain.Searcher.count to java.lang.Long    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source)    at sun.reflect.UnsafeIntegerFieldAccessorImpl.set(Unknown Source)    at java.lang.reflect.Field.set(Unknown Source)    at cn.itcast.utils.BeanListHandler.handler(BeanListHandler.java:32)    ... 26 more

异常原因是:

Can not set int field cn.itcast.domain.Searcher.count to java.lang.Long

意思是:不能设置int字段cn.itcast.domain.Searcher.count为java.lang.Long类型。
发生的根源是什么呢?我觉得应该是自己开发好的JDBC框架还是有点问题,这个根本不用担心,因为在实际开发中,我们都是使用Apache组织提供commons-dbutils框架。现在为了解决这个问题,只好将Searcher.java修改为:

// 搜索对象public class Searcher {    private String name;    private Long count;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public Long getCount() {        return count;    }    public void setCount(Long count) {        this.count = count;    }}

终于开发好这一功能了,激不激动呢?还不快来测试一下!!
这里写图片描述
经过测试,在Firefox浏览器中圆满通过测试,但在IE9浏览器中,反应还是有些迟钝,甚至出现第二次搜索,根本没有结果的情况,只能再次刷新页面进行搜索,用户体验极差!!!
虽然动态搜索栏这一实用功能实现了,但是我们发现出现以下问题:
这里写图片描述
为了解决这个问题,我们需要重新选择一个新的日期控件,我是从网上下载的一个js日期控件:
这里写图片描述
解压之后,将js日期控件——datetime.js给弄到该项目中。
这里写图片描述
该js日期控件用法如下代码所示:

<dd>    生日:   <input name="birthday" type="text" class="sang_Calender" /></dd><script type="text/javascript" src="${pageContext.request.contextPath }/js/datetime.js"></script>

所以添加客户页面——addcustomer.jsp要修改为:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><script type="text/javascript">    function makepre() {        var pres = document.getElementsByName("pre");        var preference = "";        for(var i=0;i<pres.length;i++) {            var input = pres[i];            if(input.checked==true) {                preference = preference + input.value + ",";             }        }        preference = preference.substring(0, preference.length-1); // preference="唱歌,跳舞,夜生活";        // 在form表单创建一个input隐藏输入项,如:<input type="hidden" name="preference" value="唱歌,跳舞,夜生活,...">        var form =  document.getElementById("form");        var input = document.createElement("input");        input.type = "hidden";        input.name = "preference";        input.value = preference;        form.appendChild(input);        return true;    }</script><title>添加用户的视图</title></head><body style="text-align: center;">    <br/>    <form id="form" action="${pageContext.request.contextPath }/AddCustomerServlet" method="post" onsubmit="return makepre()">    <table border="1" width="50%" align="center">        <tr>            <td>客户姓名</td>            <td>                <input type="text" name="name">            </td>        </tr>        <tr>            <td>客户性别</td>            <td>                <!--                 页面到底输出几个性别,不是在页面中显示的,而是由一个程序维护的,这个程序有几个性别,页面中就输出几个性别                 <input type="radio" name="gender" value="男">男                <input type="radio" name="gender" value="女">女                -->                <c:forEach var="gender" items="${genders }">                    <input type="radio" name="gender" value="${gender }">${gender }                </c:forEach>            </td>        </tr>        <tr>            <td>生日</td>            <td>                <input name="birthday" type="text" class="sang_Calender" />            </td>            <script type="text/javascript" src="${pageContext.request.contextPath }/js/datetime.js"></script>        </tr>        <tr>            <td>手机</td>            <td>                <input type="text" name="cellphone">            </td>        </tr>        <tr>            <td>邮箱</td>            <td>                <input type="text" name="email">            </td>        </tr>        <tr>            <td>爱好</td>            <td>  <!-- pre="唱歌" pre="跳舞" 存到数据库里面是一串字符串:"唱歌,跳舞" -->                <c:forEach var="p" items="${preferences }">                    <input type="checkbox" name="pre" value="${p }">${p }                </c:forEach>            </td>        </tr>        <tr>            <td>客户类型</td>            <td>                <c:forEach var="type" items="${types }">                    <input type="radio" name="type" value="${type }">${type }                </c:forEach>            </td>        </tr>        <tr>            <td>客户备注</td>            <td>                <textarea rows="5" cols="60" name="description"></textarea>            </td>        </tr>        <tr>            <td>                <input type="reset" value="重置">            </td>            <td>                <input type="submit" value="添加客户">            </td>        </tr>    </table>    </form></body></html>

至此,问题得到解决,客户添加生日时,出现如图所示的日期控件
这里写图片描述

0 0
原创粉丝点击