? 最近,咱组在搞一个物流系统,老大让我搞个类似google/baidu的自动查询匹配功能,第一反应,网上太多例子了,当即回复老大:放心吧,搞得定。
? 网上的资料确实多得很,但想不动脑筋找到适合自己的,总感觉不是那么容易。前前后后,折腾得不行了!
? 在实现这个功能的时候,主要有以下的几个问题:用jquery和dwr,两者有冲突;找到spring与dwr完美整合的,浏览器兼容性差;另一方面,要导入的依赖第三方的js库太多;还有一点很重要,对中文输入好像总不能及时的触发后台调用方法。所以基于上面的一些我强加给他们的缺陷,我决定,自己写个这样的功能组件(说实话,我喜欢干这种事情! )
? 在进入主题之前,罗列出我在网上搜索出来的一些不错的实现autocomplete的例子:
????? 1)http://www.gridshore.nl/blog/index.php?/archives/52-Creating-an-autocomplete-with-Spring-and-DWR.html:spring+dwr实现的一autocompletor,效果还不错,需要依赖prototype.js库及其扩展包,浏览器兼容有点问题,我实现就是基于这个,只不过去掉了prototype.js的支持。
????? 2)jquery autocompletor插件,资料多得令人发指,文档、资料、实例相当的丰富。支持多种数据源查询方式,并且有强大的jquery支持。缺点有点跟我这个平台框架里的dwr有些许的冲突,用jQuery.noConflict();貌似也不能很好的解决,so,对我来说就out!而且要导入的库也实在不少。附上一链接:http://www.iteye.com/topic/284154.
?? 如果你有过DWR的使用经历,那你肯定熟悉dwr.xml,为了把Java文件暴露为JS,我们必须在dwr.xml文件中配置Java文件生成JS的方式(new、Spring等等)。重复的配,项目大了,导致dwr.xml文件异常的庞大,后期也难以维护。如果Spring整合DWR,Spring的配置文件的庞大也可见一斑。我本来就是一个讨厌做重复工作的人,既然DWR3.0引入了annotation,当然得用,Spring也早已引入annotation,用。Spring与DWR的整合?必须的,不要再为每写一个Bean、写一个Service再配置Spring的applicationContext.xml文件了,一切交由Spring的annotation完成。(我看网上好多Spring与DWR的整合示例有欠完整,故贴出Spring与DWR整合的部分代码和说明,具体例子见附件,有兴趣的朋友可以拿下来看看,并请指正,谢谢)
?? 贴出web.xml文件配置代码如下:
?
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" 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_2_5.xsd"> <servlet> <servlet-name>autoComplete-servlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/*-context.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>autoComplete-servlet</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
?? 注意:没org.directwebremoting.servlet.DwrServlet、org.directwebremoting.spring.DwrSpringServlet的配置,一切交由org.springframework.web.servlet.DispatcherServlet,当然了,这得引入spring-webmvc.jar。
?? 现在写一个需要暴露为JS的Bean:
?
package com.autocomplete.web; import java.util.List; import org.directwebremoting.annotations.RemoteMethod; import org.directwebremoting.annotations.RemoteProxy; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import com.autocomplete.logic.IAutoCompleteDemoService; @Component @Scope("prototype") @RemoteProxy(name = "AutoCompleteDemoBean") public class AutoCompleteDemoBean { @Autowired private IAutoCompleteDemoService autoCompleteDemoService; @RemoteMethod public List findDepartmentName(String departmentName){ return autoCompleteDemoService.findDepartmentName(departmentName); } }
?? 对于注释的具体含义,尽可以google/baidu,讲得绝对比我详尽,不再献丑。
?? 其中引入了另外一个Service接口,现贴出该接口的实现类代码:
?
package com.autocomplete.logic; import java.util.ArrayList; import java.util.List; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Service; @Service @Scope("prototype") public class AutoCompleteDemoServiceImpl implements IAutoCompleteDemoService { private static List<String> datas = new ArrayList<String>(); //数据集合初始化 static { datas.add("开发部WMS"); datas.add("开发部EC"); datas.add("开发部CRM"); datas.add("开发部OA"); datas.add("研发部"); datas.add("人力资源部"); datas.add("客服部"); datas.add("财务部"); datas.add("市场部"); datas.add("总载办公室"); } //根据 @Override public List findDepartmentName(String param) { List result = new ArrayList(); if(null!=param&¶m.length()>0){ for(String data:datas){ if(data.startsWith(param)){ result.add(data); } } } return result; } }
?? OK,代码现在算是写完了,每个类的上面都写了些Spring、DWR的注释类,没引入注释类之前,如果我们要让Spring容器知道我们写的类,那我们得在Spring的配置文件里配置这些接口、类。写一个,配置一个,痛苦幺。现在用了annotation注释,Spring容器可扫描并实例化这些类,当然,这个扫描也是设置个范围,也得让Spring容器有的放矢的实例化类呀。
?? 我们都知道,Spring默认加载WEB-INF/applicationContext.xml,为了实现模块化,我现在一分为二:web-context.xml(bean配置文件)、service-context.xml(service配置文件)。当然了,这两个文件也是相当的简单,至少我认为没你想象中的复杂,我保证。
?? web-context.xml:
?
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dwr ="http://www.directwebremoting.org/schema/spring-dwr" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.directwebremoting.org/schema/spring-dwr http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd"> <context:component-scan base-package="com.autocomplete.web" scoped-proxy="targetClass"> <context:include-filter type="regex" expression="com.autocomplete.web.*Bean*"/> </context:component-scan> <dwr:configuration> <dwr:signatures> <![CDATA[ import java.util.List; import java.util.Map; ]]> </dwr:signatures> </dwr:configuration> <dwr:controller id="dwrController" debug="true"> <dwr:config-param name="crossDomainSessionSecurity" value="false"/> <dwr:config-param name="allowScriptTagRemoting" value="true"/> <dwr:config-param name="debug" value="true"/> </dwr:controller> <dwr:annotation-config/> <dwr:url-mapping /> </beans>
?
? service-context.xml:
?
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"> <context:component-scan base-package="com.autocomplete.logic" scoped-proxy="targetClass"> <context:include-filter type="regex" expression="com.autocomplete.logic.*ServiceImpl*"/> </context:component-scan> </beans>?
?基础设施已经搞定,现在,让我们开始autocomplete组件的实现之旅吧:
? autocomplete组件只由一个JS和一个CSS文件组成,分别为autoCompleterSupport.js和autocomplete.css。在需要使用autocomplete的页面上导入即可。具体实现,请看附件。
? 发布到web容器,比如Tomcat,输入“开”,并可看到实现效果。
?
?
?
?
?
?
?
可以下,没有问题!