课题_自己封装的一个SolrDataImportRequestHandlerScheduler
Solr搜索文档说明
Solr使用教程目录一、软件版本 (2)二、安装教程 (2)1、Solr安装教程 (2)2、solr环境搭建 (4)3、业务字段的实际配置 (7)4、dataimport 导入数据库数据 (8)5、solrj的使用 (10)6、电商平台的应用 (14)一、软件版本Solr版本号:solr-5.5.5jdk版本号:jdk1.8以上Tomcat版本号:Tomcat8.0以上二、安装教程1、Solr安装教程1.创建solrhome以及solrcore(mysolrhome、mycore 名字可以任意指定)1.1在指定的目录下新建文件夹solrhome如:D:\mysolrhome1.2将solr-5.5.4\server\solr\solr.xml拷贝至D:\mysolrhome1.3在solrhome下新建文件夹solrcore如D:\mysolrhome\mycore1.4将solr-5.5.4\server\solr\configsets\basic_configs\conf完整目录拷贝至D:\mysolrhome\mycore\下2.部署到Tomcat2.1将solr-5.5.4\server\solr-webapp\webapp 完整目录复制到Apache Tomcat 8.0.27\webapps下并重命名为solr2.2在Apache Tomcat 8.0.27\webapps\solr\WEB-INF下新建classes文件夹2.3将solr-5.5.4/server/resource/log4j.properties 拷贝至上一步创建的classes2.4把solr-5.5.4/server/lib/ext/目录下的所有jar文件复制到Apache Tomcat 8.0.27/webapp/solr/WEB-INF/lib/中3.配置solrcore3.1修改Apache Tomcat 8.0.27-solr\webapps\solr\WEB-INF\web.xml 新增<env-entry>标签,将你的solrhome配置进去。
handlerinterceptor的三个方法
handlerinterceptor的三个方法一、HandlerInterceptor概述HandlerInterceptor是Spring MVC中的一个重要组件,用于实现对请求和响应的处理。
它可以在请求处理之前、之后或者视图渲染之后执行一些自定义逻辑,从而实现对整个请求的处理过程进行拦截和干预。
HandlerInterceptor接口中定义了三个方法:preHandle()、postHandle()和afterCompletion(),接下来我们将详细介绍这三个方法的作用及应用场景。
二、HandlerInterceptor的三个方法1.preHandle()preHandle()方法在请求处理之前被调用。
在这个方法中,我们可以对请求进行预处理,例如验证请求参数、权限检查等。
如果preHandle()方法返回false,则表示请求被拦截,后续的请求处理过程不会继续执行;如果返回true,则表示请求可以通过,继续执行后续处理。
2.postHandle()postHandle()方法在请求处理完成后被调用。
此时,请求已经成功处理,我们可以在这个方法中对处理结果进行修改或添加一些额外的逻辑。
例如,在处理完请求后,我们可以给用户发送一些通知信息或者记录日志等。
3.afterCompletion()afterCompletion()方法在视图渲染完成后被调用。
此时,整个请求处理过程已经结束,我们可以对这个过程进行清理工作,例如释放资源、关闭连接等。
这个方法在实际应用中不太常用,但可以在某些特殊场景下发挥作用。
三、方法应用场景与实战案例1.登录验证在登录接口中,我们可以使用preHandle()方法对用户输入的账号和密码进行验证。
如果验证失败,返回false拦截请求;如果验证成功,返回true,让请求继续处理。
2.权限控制在需要对不同用户角色进行权限控制的页面,我们可以使用preHandle()方法检查用户权限。
handlerinterceptor参数
handlerinterceptor参数HandlerInterceptor是Spring MVC框架提供的一个接口,用于对请求进行拦截和处理。
它可以在请求到达Controller之前、Controller处理请求之后、视图渲染之前和视图渲染之后进行一些自定义的处理操作。
1. preHandle方法:该方法在请求到达Controller之前被调用,返回一个布尔值。
如果返回true,则继续执行后续的拦截器和Controller处理;如果返回false,则终止执行,不会执行后续的拦截器和Controller处理。
此方法常用于身份验证、权限校验等操作。
我们可以在该方法中实现登录检查、权限认证、参数合法性验证等逻辑。
2. postHandle方法:该方法在Controller处理请求之后、视图渲染之前被调用。
通过该方法,我们可以对请求处理结果进行一些修改和处理。
可以在该方法中获取到Controller方法的返回值,并对返回值进行修改,比如添加一些额外的数据或修改返回的视图。
该方法在视图渲染之后被调用,无论Controller方法是否抛出异常,都会执行该方法。
可以在该方法中进行一些资源清理操作,比如清理临时文件、关闭数据库连接等。
HandlerInterceptor的参数主要包括以下几种:1. HttpServletRequest:可以通过HttpServletRequest获取请求相关的信息,比如请求的URL、请求的参数等。
2. HttpServletResponse:可以通过HttpServletResponse对响应进行一些设置,比如设置响应的状态码、设置响应头信息等。
3. Object handler:表示当前请求所对应的处理器(即Controller中的方法)。
可以通过该参数做一些特定的逻辑处理。
4. ModelAndView:表示当前请求所对应的视图和模型对象。
可以对其进行修改,从而修改返回的视图和模型。
Solr4.7安装及集成
Solr1 Solr4.7 Tomcat部署安装一.下载solr-4.7.1/dyn/closer.cgi/lucene/solr/4.7.1环境需求:java 1.6版本以上;solr运行需要java serverlet 容器,默认使用jetty,或者tomcat,jboss等等。
二.Tomcat部署solr:1. 安装好jdk 1.6以上,安装好tomcat(我用是apache-tomcat-7.0.6),并配置环境变量。
2.将解压包中的solr-4.7.1/dist/solr-4.7.1.war复制到tomcat_dir/webapps /目录,并命名为solr.war。
3.a.将solr-4.7.1/example/lib/ext/目录下的jar文件复制到tomcat/lib目录下;b.将solr-4.7.1/example/resources/下的log4j.properties文件复制到tomcat_dir/lib目录下;c.把solr-4.7.1/example/solr,复制到tomcat_di r/bin下。
4.修改tomcat_dir/conf/server.xml<Connector port="8080" protocol="HTTP/1.1"connectionTimeout="20000"redirectPort="8443"URIEncoding="UTF-8" />5.创建solr.xml,存放在路径:tomcat/conf/Catalina/localhost/solr.xml,内容:<Context path="/solr" docBase="E:\Tomcat7.0\webapps\solr.war"debug="0" crossContext="true"><Environment name="solr/home" type="ng.String" value="E:\Tom cat7.0\bin\solr\"override="true" /></Context>注意:上面的docBase和value路径中不能存在中文字符,否则会出现404错误。
SolrDataimport配置
SolrDataimport配置参考资料:Solr 通过Dataimport可以对各种⽂件类型(包括邮件)建索引,也可以对关系型数据库建索引。
前提依赖Jar包Dataimport从关系型数据库建索引时,依赖以下jar包,这些Jar包位于Solr安装包下⾯的solr-6.1.0\dist\⽬录下⽬录下:本实例是SQL Server关系型数据库,所以还要添加sqljdbc42.jar到指定路径下。
Dataimport为普通⽂件建索引时,依赖以下jar包,这些jar包位于Solr安装包的solr-6.1.0\contrib\extraction\lib⽬录下这些jar包在本机上的统⼀存放位置为:/var/lib/solr/lib/在solrconfig.xml⽂件中添加以上jar包的引⽤。
<lib dir="/var/lib/solr/lib/" regex=".*\.jar" />⼀、配置solrconfig.xml<requestHandler name="/dataimport"class="solr.DataImportHandler"><lst name="defaults"><str name="config">tika-data-config.xml</str><str name="update.chain">uuid</str></lst></requestHandler>⼆、配置tika-data-config.xml在⽂件solrconfig.xml同级⽬录下,新建⽂件tika-data-config.xml,tika-data-config.xml⽂件中的内容配置如下:<dataConfig><!--可以配置多个dataSource,每个都有唯⼀⼀个name--><dataSource name="sqldb2" driver="com.microsoft.sqlserver.jdbc.SQLServerDriver" url="jdbc:sqlserver://10.2.8.170:1433" user="xxx" password="xxxxxxx"/> <dataSource type="BinFileDataSource" name="f1"/><dataSource type="FileReaderDataSource" name="f2"/><document><!--可以配置多个Entity,每个Entity通过name属性来区分--><!--Entity数据源为⽂件--><entity name="files" dataSource="f1" rootEntity="false"processor="FileListEntityProcessor"baseDir="/usr/local/solr/files/"fileName=".*.(doc)|(pdf)|(xls)|(ppt)|(docx)|(txt)|(pptx)|(xlsx)|(xml)|(csv)|(json)|(html)|(sh)|(css)|(png)"recursive="true"><field column="fileAbsolutePath" name="url" /><field column="fileSize" name="size" /><field column="fileLastModified" name="lastModified" /><field column="file" name="fname"/><entityname="documentImport"processor="TikaEntityProcessor"url="${files.fileAbsolutePath}"format="text"><field column="Author" name="author" meta="true"/><field column="title" name="title" meta="true"/><field column="subject" name="subject" meta="true"/><field column="Content-Type" name="content_type" meta="true"/><field column="text" name="content"/></entity></entity><!--Entity数据源为SQL Server数据库--><entity name="DimOrganization" dataSource="sqldb2"query="SELECT [物料类型名称] as 名称 FROM [GreeBGDW].[dbo].[Dim_MaterielType]"><field column="名称" name="name"/></entity><!--Entity数据源为SQL Server数据库--><entity name="180119" dataSource="sqldb2"query="SELECT [name] as name , [name] as cat ,name as manu FROM [GreeBGDW].[dbo].[180119]"><field column="name" name="name"/><field column="cat" name="cat"/><field column="manu" name="manu"/></entity></document></dataConfig>⽂件实体属于简介⼀个简单的实体处理程序,可以⽤于枚举标准⽂件系统中的⽂件列表,它不需要使⽤DataSource.属性如下:fileName:(必填) ⽤正则表达式来标记⽂件名baseDir:(必填) 基础⽬录,绝对路径.recursive:是否递归⽂件列表,默认为false.excludes:不包括的⽂件名的正则表达式newerThan:⽇期参数,格式: (yyyy-MM-dd HH:mm:ss),它也可以是⼀个数学⽇期,如('NOW-3DAYS'),其中的单引号是必填的.也可以是⼀个有效的变量格式,如(${}).olderThan :⽇期格式,规则同上.biggerThan:整型参数.smallerThan:整型参数.rootEntity:它⼀般情况下都是false(除⾮你只索引⽂件名).直属于<document>下的实体才是根实体.那就意味着,根实体发出的每⼀⾏都会被solr/lucene创建.但是在这种情况下,我们不希望⼀个⽂件对应⼀个⽂档(document).我们希望⽣成⼀个⽂档(document),每⼀⾏的发出都是由下⾯的实体'x'来完成的.因为实体'f'包含了rootEntity=false,直属实体f下的实体就变成了⼀个根实体.dataSource:数据源错误记录【错误⼀】 org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode = NoNode for/configs/collection2/dataimport.properties【解决⽅法】在配置⽂件conf/⽬录下添加⼀个空的dataimport.propertie⽂件。
Solr入门实战(4)--Java操作Solr
Solr⼊门实战(4)--Java操作Solr本⽂主要介绍使⽤ Java 来操作 Solr,⽂中所使⽤到的软件版本:Java 1.8.0_191、Solr 8.9.0。
1、定义 Schema 信息假设⼀个描述诗⼈信息的⽂档包含如下字段:字段描述id唯⼀主键age年龄name姓名poems诗歌about简介success成就定义的 schema 信息如下:<field name="about" type="text_ik" uninvertible="true" indexed="true" stored="true"/><field name="age" type="pint" uninvertible="true" indexed="true" stored="true"/><field name="content" type="text_ik" uninvertible="true" indexed="true" stored="true" multiValued="true"/><field name="id" type="string" multiValued="false" indexed="true" required="true" stored="true"/><field name="name" type="text_ik" uninvertible="true" indexed="true" stored="true"/><field name="poems" type="text_ik" uninvertible="true" indexed="true" stored="true"/><field name="success" type="text_ik" uninvertible="true" indexed="true" stored="true"/>2、Java 操作 Solr2.1、引⼊依赖<dependency><groupId>org.apache.solr</groupId><artifactId>solr-solrj</artifactId><version>8.9.0</version></dependency><dependency><groupId>org.apache.solr</groupId><artifactId>solr-core</artifactId><version>8.9.0</version></dependency>2.2、编写 demo2.2.1、增加/更新⽂档@Testpublic void update() throws IOException, SolrServerException {SolrInputDocument document = new SolrInputDocument();document.addField("id", "123456");document.addField("age", 30);document.addField("name", "李⽩2");document.addField("poems", "望庐⼭瀑布");document.addField("about", "字太⽩");document.addField("success", "创造了古代浪漫主义⽂学⾼峰、歌⾏体和七绝达到后⼈难及的⾼度");SolrInputDocument document2 = new SolrInputDocument();document2.addField("id", "123457");document2.addField("age", 31);document2.addField("name", "杜甫");document2.addField("poems", "望岳");document2.addField("about", "字⼦美");document2.addField("success", "唐代伟⼤的现实主义⽂学作家,唐诗思想艺术的集⼤成者");solrClient.add(coreName, document);solrClient.add(coreName, document2);mit(coreName, true,true);}还可以通过实体类来增加/更新⽂档:@Testpublic void update2() throws IOException, SolrServerException {PoetInfo info = new PoetInfo("123456", 40, "李⽩", "望庐⼭瀑布", "字太⽩", "创造了古代浪漫主义⽂学⾼峰、歌⾏体和七绝达到后⼈难及的⾼度"); solrClient.addBean(coreName, info);mit(coreName, true,true);}2.2.2、查询⽂档/*** 通过 MapSolrParams 查询*/@Testpublic void query() throws IOException, SolrServerException {Map<String, String> map = new HashMap<>();//查询条件map.put("q", "*:*");//要显⽰的内容map.put("fl", "id,age,name,poems");//排序⽅式map.put("sort", "id asc");MapSolrParams solrParams = new MapSolrParams(map);QueryResponse queryResponse = solrClient.query(coreName, solrParams); SolrDocumentList documents = queryResponse.getResults();("查询到{}个⽂档!", documents.getNumFound());for (SolrDocument document : documents) {String id = (String)document.getFieldValue("id");Integer age = (Integer)document.getFieldValue("age");String name = (String)document.getFieldValue("name");String poems = (String)document.getFieldValue("poems");("id={},age={},name={},poems={}", id, age, name, poems);}}/*** 通过 solrQuery 查询*/@Testpublic void query2() throws IOException, SolrServerException {SolrQuery solrQuery = new SolrQuery("*:*");solrQuery.addField("id");solrQuery.addField("age");solrQuery.addField("name");solrQuery.addField("poems");solrQuery.addSort("id", SolrQuery.ORDER.asc);//设置返回的⾏数solrQuery.setRows(10);QueryResponse queryResponse = solrClient.query(coreName, solrQuery); SolrDocumentList documents = queryResponse.getResults();("查询到{}个⽂档!", documents.getNumFound());for (SolrDocument document : documents) {String id = (String)document.getFieldValue("id");Integer age = (Integer)document.getFieldValue("age");String name = (String)document.getFieldValue("name");String poems = (String)document.getFieldValue("poems");("id={},age={},name={},poems={}", id, age, name, poems);}}/*** 查询返回实例类对象*/@Testpublic void query3() throws IOException, SolrServerException {SolrQuery solrQuery = new SolrQuery("*:*");solrQuery.addField("id");solrQuery.addField("age");solrQuery.addField("name");solrQuery.addField("poems");solrQuery.addField("about");solrQuery.addField("success");solrQuery.addSort("id", SolrQuery.ORDER.asc);//设置返回的⾏数solrQuery.setRows(10);QueryResponse queryResponse = solrClient.query(coreName, solrQuery); List<PoetInfo> list = queryResponse.getBeans(PoetInfo.class);("查询到{}个⽂档!", list.size());for (PoetInfo info : list) {(info.toString());}}2.2.3、删除⽂档/*** 根据id删除⽂档*/@Testpublic void delete() throws IOException, SolrServerException {solrClient.deleteById(coreName, "123456");mit(coreName, true,true);}/*** 根据查询删除⽂档*/@Testpublic void delete2() throws IOException, SolrServerException {solrClient.deleteByQuery(coreName, "name:杜甫");mit(coreName, true,true);}2.2.4、完整代码package com.abc.demo.general.solr;import org.apache.solr.client.solrj.beans.Field;public class PoetInfo {@Fieldprivate String id;@Fieldprivate Integer age;@Fieldprivate String name;@Fieldprivate String poems;@Fieldprivate String about;@Fieldprivate String success;public PoetInfo() {}public PoetInfo(String id, Integer age, String name, String poems, String about, String success) { this.id = id;this.age = age; = name;this.poems = poems;this.about = about;this.success = success;}@Overridepublic String toString() {return "Info{" +"id='" + id + '\'' +", age=" + age +", name='" + name + '\'' +", poems='" + poems + '\'' +", about='" + about + '\'' +", success='" + success + '\'' +'}';}public String getId() {return id;}public void setId(String id) {this.id = id;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getName() {return name;}public void setName(String name) { = name;}public String getAbout() {return about;}public void setAbout(String about) {this.about = about;}public String getSuccess() {return success;}public void setSuccess(String success) {this.success = success;}}PoetInfopackage com.abc.demo.general.solr;import org.apache.solr.client.solrj.SolrQuery;import org.apache.solr.client.solrj.SolrServerException;import org.apache.solr.client.solrj.impl.HttpSolrClient;import org.apache.solr.client.solrj.response.QueryResponse;import mon.SolrDocument;import mon.SolrDocumentList;import mon.SolrInputDocument;import mon.params.MapSolrParams;import org.junit.After;import org.junit.Before;import org.junit.Test;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.io.IOException;import java.util.HashMap;import java.util.List;import java.util.Map;public class SolrCase {private static Logger logger = LoggerFactory.getLogger(SolrCase.class);private HttpSolrClient solrClient;private String coreName = "new_core";@Beforepublic void before() {solrClient = new HttpSolrClient.Builder("http://10.40.100.69:8983/solr").withConnectionTimeout(10000).withSocketTimeout(60000).build();}@Afterpublic void after() throws IOException {solrClient.close();}@Testpublic void update() throws IOException, SolrServerException {SolrInputDocument document = new SolrInputDocument();document.addField("id", "123456");document.addField("age", 30);document.addField("name", "李⽩2");document.addField("poems", "望庐⼭瀑布");document.addField("about", "字太⽩");document.addField("success", "创造了古代浪漫主义⽂学⾼峰、歌⾏体和七绝达到后⼈难及的⾼度"); SolrInputDocument document2 = new SolrInputDocument();document2.addField("id", "123457");document2.addField("age", 31);document2.addField("name", "杜甫");document2.addField("poems", "望岳");document2.addField("about", "字⼦美");document2.addField("success", "唐代伟⼤的现实主义⽂学作家,唐诗思想艺术的集⼤成者");solrClient.add(coreName, document);solrClient.add(coreName, document2);mit(coreName, true,true);}@Testpublic void update2() throws IOException, SolrServerException {PoetInfo info = new PoetInfo("123456", 40, "李⽩", "望庐⼭瀑布", "字太⽩", "创造了古代浪漫主义⽂学⾼峰、歌⾏体和七绝达到后⼈难及的⾼度"); solrClient.addBean(coreName, info);mit(coreName, true,true);}/*** 通过 MapSolrParams 查询*/@Testpublic void query() throws IOException, SolrServerException {Map<String, String> map = new HashMap<>();//查询条件map.put("q", "*:*");//要显⽰的内容map.put("fl", "id,age,name,poems");//排序⽅式map.put("sort", "id asc");MapSolrParams solrParams = new MapSolrParams(map);QueryResponse queryResponse = solrClient.query(coreName, solrParams);SolrDocumentList documents = queryResponse.getResults();("查询到{}个⽂档!", documents.getNumFound());for (SolrDocument document : documents) {String id = (String)document.getFieldValue("id");Integer age = (Integer)document.getFieldValue("age");String name = (String)document.getFieldValue("name");String poems = (String)document.getFieldValue("poems");("id={},age={},name={},poems={}", id, age, name, poems);}}/*** 通过 solrQuery 查询*/@Testpublic void query2() throws IOException, SolrServerException {SolrQuery solrQuery = new SolrQuery("*:*");solrQuery.addField("id");solrQuery.addField("age");solrQuery.addField("name");solrQuery.addField("poems");solrQuery.addSort("id", SolrQuery.ORDER.asc);//设置返回的⾏数solrQuery.setRows(10);QueryResponse queryResponse = solrClient.query(coreName, solrQuery);SolrDocumentList documents = queryResponse.getResults();("查询到{}个⽂档!", documents.getNumFound());for (SolrDocument document : documents) {String id = (String)document.getFieldValue("id");Integer age = (Integer)document.getFieldValue("age");String name = (String)document.getFieldValue("name");String poems = (String)document.getFieldValue("poems");("id={},age={},name={},poems={}", id, age, name, poems);}}/*** 查询返回实例类对象*/@Testpublic void query3() throws IOException, SolrServerException {SolrQuery solrQuery = new SolrQuery("*:*");solrQuery.addField("id");solrQuery.addField("age");solrQuery.addField("name");solrQuery.addField("poems");solrQuery.addField("about");solrQuery.addField("success");solrQuery.addSort("id", SolrQuery.ORDER.asc);//设置返回的⾏数solrQuery.setRows(10);QueryResponse queryResponse = solrClient.query(coreName, solrQuery);List<PoetInfo> list = queryResponse.getBeans(PoetInfo.class);("查询到{}个⽂档!", list.size());for (PoetInfo info : list) {(info.toString());}}/*** 根据id删除⽂档*/@Testpublic void delete() throws IOException, SolrServerException {solrClient.deleteById(coreName, "123456");mit(coreName, true,true);}/*** 根据查询删除⽂档*/@Testpublic void delete2() throws IOException, SolrServerException {solrClient.deleteByQuery(coreName, "name:杜甫");mit(coreName, true,true);}}SolrCase3、Java 操作 SolrCloudJava 操作 SolrCloud 与 Java 操作 Solr 很类似,主要区别有:1、连接使⽤的类不同,连接 Solr 使⽤的是 HttpSolrClient,连接 SolrColud 使⽤的是 CloudHttp2SolrClient。
handlerinterceptor 获取请求参数 工具类
handlerinterceptor 获取请求参数工具类一、概述在进行Web开发中,我们经常需要获取请求参数进行业务逻辑处理。
而在使用Spring MVC框架时,可以通过编写HandlerInterceptor获取请求参数,并进行相应的处理。
本文将介绍如何编写一个用于获取请求参数的HandlerInterceptor工具类,并详细讨论其使用方法和注意事项。
二、HandlerInterceptor简介2.1 HandlerInterceptor的作用HandlerInterceptor是Spring MVC框架提供的一个拦截器接口,用于在请求处理过程中进行拦截和处理。
它可以对请求进行预处理和后处理,并且能够获取请求参数等信息。
2.2 HandlerInterceptor接口方法HandlerInterceptor接口包含以下三个方法: 1. preHandle:在请求处理之前进行调用,返回值决定是否继续处理请求 2. postHandle:在请求处理之后, 视图渲染之前进行调用 3. afterCompletion:在整个请求处理完毕后进行调用,可以进行一些资源清理工作三、编写HandlerInterceptor获取请求参数的工具类3.1 创建Interceptor类首先,我们需要创建一个继承HandlerInterceptor接口的自定义Interceptor类,用于实现拦截器的具体逻辑。
public class ParamInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 在preHandle方法中获取请求参数并进行处理String param1 = request.getParameter("param1");String param2 = request.getParameter("param2");// 对请求参数进行处理// ...return true; // 返回true表示继续处理请求,返回false表示中断请求}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse res ponse, Object handler, ModelAndView modelAndView) throws Exception {// 在postHandle方法中进行后处理// ...}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {// 在afterCompletion方法中进行一些清理工作// ...}}3.2 配置拦截器在Spring MVC的配置文件中,需要将自定义的Interceptor类配置为一个拦截器,并指定拦截的URL地址。
requesthandlerselectors 用法
requesthandlerselectors 用法
java
RequestHandlerSelectors.any()
.and(RequestHandlerSelectors.basePackage("com.example.controller"))
.or(RequestHandlerSelectors.baseClass(ExampleController.class))
.build();
在上述示例中,RequestHandlerSelectors.any()表示扫描所有接口,RequestHandlerSelectors.basePackage("com.example.controller")表示只扫描指定包下的接口,RequestHandlerSelectors.baseClass(ExampleController.class)表示只扫描指定类的接口。
通过使用and()和or()方法,可以将多个过滤条件组合在一起,以满足更复杂的扫描需求。
除了上述示例中使用的过滤方式,RequestHandlerSelectors 还提供了其他一些过滤方式,例如RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)表示只扫描注解为ApiOperation的方法等。
可以根据具体的需求选择适合的过滤方式来配置接口扫描。
使用RequestHandlerSelectors 时,需要将其与其他配置一起传递给Swagger 或其他API 文档生成工具,以便根据这些配置生成相应的API 文档。
handlerinterceptor的三个方法
handlerinterceptor的三个方法HandlerInterceptor是Spring框架提供的一个拦截器接口,用于拦截处理器的执行,并在特定的时机执行一些增强逻辑。
HandlerInterceptor接口中定义了三个方法,分别是preHandle、postHandle和afterCompletion,下面我将对这三个方法进行详细的介绍。
1. preHandle方法preHandle方法在调用处理器之前执行,可以用于进行一些前置处理逻辑。
这个方法有三个参数,分别是HttpServletRequest、HttpServletResponse和Object handler,其中HttpServletRequest 是请求对象,HttpServletResponse是响应对象,Object handler是被拦截的处理器对象。
preHandle方法的返回值是一个布尔值,如果返回false,则表示拦截器将中断请求的处理,后续的处理器和拦截器都不会再执行;如果返回true,则继续执行后续的拦截器和处理器。
在preHandle方法中,可以根据需要进行一些前置处理逻辑,比如权限验证、参数校验等。
2. postHandle方法postHandle方法在调用处理器之后、视图渲染之前执行,可以对结果进行一些处理或修改。
postHandle方法有三个参数,分别是HttpServletRequest、HttpServletResponse和Object handler,和preHandle方法的参数相同。
postHandle方法没有返回值,它在处理器的执行过程中,会在处理器执行完成后立即调用。
可以使用postHandle方法来对请求的结果进行一些后处理,比如添加一些公共的参数、修改返回的视图名称等。
3. afterCompletion方法afterCompletion方法在整个请求完成后执行,即视图渲染完成后执行。
handlerinterceptor 参数
handlerinterceptor 参数在SpringMVC中,HandlerInterceptor是一个非常重要的组件,它可以在请求到达Controller之前或者Controller处理完请求之后对请求进行拦截和处理。
HandlerInterceptor提供了三个方法,分别是preHandle、postHandle和afterCompletion,这些方法可以让我们在请求处理的不同阶段进行不同的操作。
preHandle方法preHandle方法会在请求到达Controller之前被调用,它有三个参数,分别是HttpServletRequest、HttpServletResponse和Object类型的handler。
HttpServletRequest和HttpServletResponse是请求和响应对象,handler是请求所对应的Controller。
preHandle方法返回一个boolean类型的值,表示是否继续执行后续的拦截器和Controller。
在preHandle方法中,我们可以进行一些操作,例如记录请求日志、进行权限校验、进行请求参数校验等。
如果preHandle方法返回false,请求就会被终止,后续的拦截器和Controller都不会执行。
postHandle方法postHandle方法会在Controller处理完请求之后,但是视图渲染之前被调用,它有三个参数,分别是HttpServletRequest、HttpServletResponse和Object类型的handler。
HttpServletRequest和HttpServletResponse是请求和响应对象,handler是请求所对应的Controller。
postHandle方法没有返回值。
在postHandle方法中,我们可以进行一些操作,例如添加模型数据、记录响应日志等。
由于postHandle方法会在视图渲染之前被调用,所以在这个方法中对模型数据的修改会对视图产生影响。
handlermethod类介绍 -回复
handlermethod类介绍-回复HandlerMethod是Spring MVC框架中的一个关键类,它用于处理请求并且将请求映射到相应的处理方法上。
在这篇文章中,我们将深入了解HandlerMethod类的功能和用法,并以以下几个方面进行讨论:1. HandlerMethod的作用及其在Spring MVC框架中的位置2. HandlerMethod的构造方法和重要属性3. HandlerMethod的执行过程4. 如何为HandlerMethod添加拦截器5. HandlerMethod的异常处理机制6. 如何自定义HandlerMethod1. HandlerMethod的作用及其在Spring MVC框架中的位置HandlerMethod是Spring MVC框架中用于处理请求的核心类之一。
它主要负责将请求映射到相应的处理方法上,并根据处理方法的返回值生成响应。
HandlerMethod通常用于处理带有@Controller注解的类中定义的方法。
在Spring MVC框架中,请求首先被DispatcherServlet接收,然后DispatcherServlet会根据请求的URL路径和HTTP方法选择一个合适的HandlerMapping,HandlerMapping负责确定请求会被映射到哪一个HandlerMethod上。
2. HandlerMethod的构造方法和重要属性HandlerMethod的构造方法有两个参数:Object bean和Method method。
参数bean表示具体处理请求的对象,而method表示处理请求的方法。
HandlerMethod还包含几个重要的属性:- beanType:表示bean的类型,通常是一个带有@Controller注解的类。
- returnType:表示处理方法的返回类型。
- methodParameters:表示处理方法的参数列表。
handlermethod类介绍
handlermethod类介绍
HandlerMethod 是 Spring MVC 框架中的一个类,它代表一个处理请求的方法。
在 Spring MVC 中,控制器(Controller)负责处理用户请求,并将结果返回给用户。
控制器中的每个处理请求的方法都可以被视为一个 HandlerMethod。
HandlerMethod 类封装了处理请求的方法的元数据,包括方法签名、参数类型、返回类型等信息。
这些信息在处理请求的过程中非常重要,例如在类型转换、参数绑定等操作中。
除了封装方法元数据之外,HandlerMethod 类还提供了许多其他功能,例如:
1.获取方法参数:通过 getParameters() 方法可以获取方法的参数信息,包括参数名称、类型、是否必需等。
2.执行方法:通过 getMethod() 方法可以获取方法的字节码,然后使用 invoke() 方法执行该方法。
3.获取返回值:通过 getMethod() 方法可以获取方法的返回类型,然后使用 invoke() 方法执行该方法并获取返回值。
总之,HandlerMethod 类是 Spring MVC 框架中处理请求的重要类之一,它提供了许多方便的方法和功能,使得开发者可以更加方便地处理用户请求。
使用注解+RequestBodyAdvice实现http请求内容加解密方式
使⽤注解+RequestBodyAdvice实现http请求内容加解密⽅式注解主要⽤来指定那些需要加解密的controller⽅法实现⽐较简单@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface SecretAnnotation {boolean encode() default false;boolean decode() default false;}使⽤时添加注解在controller的⽅法上@PostMapping("/preview")@SecretAnnotation(decode = true)public ResponseVO<ContractSignVO> previewContract(@RequestBody FillContractDTO fillContractDTO) {return contractSignService.previewContract(fillContractDTO);}请求数据由⼆进制流转为类对象数据,对于加密过的数据,需要在⼆进制流被处理之前进⾏解密,否则在转为类对象时会因为数据格式不匹配⽽报错。
因此使⽤RequestBodyAdvice的beforeBodyRead⽅法来处理。
@Slf4j@RestControllerAdvicepublic class MyRequestControllerAdvice implements RequestBodyAdvice {@Overridepublic boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {return methodParameter.hasParameterAnnotation(RequestBody.class);}@Overridepublic Object handleEmptyBody(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {return o;}@Autowiredprivate MySecretUtil mySecretUtil;@Overridepublic HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {if (methodParameter.getMethod().isAnnotationPresent(SecretAnnotation.class)) {SecretAnnotation secretAnnotation = methodParameter.getMethod().getAnnotation(SecretAnnotation.class);if (secretAnnotation.decode()) {return new HttpInputMessage() {@Overridepublic InputStream getBody() throws IOException {List<String> appIdList = httpInputMessage.getHeaders().get("appId");if (appIdList.isEmpty()){throw new RuntimeException("请求头缺少appID");}String appId = appIdList.get(0);String bodyStr = IOUtils.toString(httpInputMessage.getBody(),"utf-8");bodyStr = mySecretUtil.decode(bodyStr,appId);return IOUtils.toInputStream(bodyStr,"utf-8");}@Overridepublic HttpHeaders getHeaders() {return httpInputMessage.getHeaders();}};}}return httpInputMessage;}@Overridepublic Object afterBodyRead(Object o, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {return o;}}mySecretUtil.decode(bodyStr,appId)的内容是,通过请求头中的AppID去数据库中查找对于的秘钥,之后进⾏解密,返回解密后的字符串。
handlerinterceptor 实现方法
handlerinterceptor 实现方法在许多编程场景中,我们经常需要处理请求和响应。
在Java Web开发中,HttpServletRequest和HttpServletResponse对象是处理HTTP请求和响应的主要接口。
为了更好地管理这些请求和响应,我们通常会使用拦截器(Interceptor)机制。
HandlerInterceptor是Spring MVC中的一个接口,它允许我们在请求到达目标处理器(Handler)之前和之后执行自定义逻辑。
首先,我们需要定义一个实现了HandlerInterceptor接口的类。
这个类通常包含两个方法:preHandle和postHandle。
* preHandle:这个方法会在请求到达目标处理器之前被调用。
我们可以在这个方法中执行一些前置操作,例如记录日志、权限检查等。
* postHandle:这个方法会在请求处理完毕后被调用。
我们可以在这个方法中执行一些后置操作,例如清理资源、更新数据库状态等。
```javaimport javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {// 在请求到达目标处理器之前执行的逻辑System.out.println("Before handling request...");return true; // 返回true表示继续处理请求,返回false表示停止处理请求}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {// 在请求处理完毕后执行的逻辑System.out.println("After handling request...");}}```三、注册 HandlerInterceptor在Spring MVC中,我们可以通过配置文件或注解来注册我们的Interceptor。
servletrequestdatabinder原理
在Spring 框架中,`ServletRequestDataBinder` 是用于将请求参数绑定到JavaBean 对象的类。
它的原理是通过分析请求中的参数,将这些参数的值绑定到指定的JavaBean 对象上。
`ServletRequestDataBinder` 的工作原理可以简单概括如下:
1. 首先,`ServletRequestDataBinder` 会根据请求中的参数名和JavaBean 对象的属性名进行匹配,尝试将参数值绑定到JavaBean 对象的相应属性上。
2. 如果请求参数的数据类型与JavaBean 对象的属性类型不匹配,`ServletRequestDataBinder` 会尝试进行类型转换。
3. 如果请求参数中的属性在JavaBean 对象中不存在,或者JavaBean 对象中的属性在请求参数中不存在,那么这些属性将被忽略。
4. `ServletRequestDataBinder` 还支持数据校验,可以根据JavaBean 对象上的注解(如`@NotNull`、`@Min`、`@Max` 等)进行数据校验。
总的来说,`ServletRequestDataBinder` 的原理是将请求中的参数值映射到JavaBean 对象的属性上,并提供了数据类型转换和数据校验的功能。
需要注意的是,`ServletRequestDataBinder` 是Spring MVC 框架中的一部分,用于处理Web 请求,因此它是与Servlet 相关的。
handlerinterceptor中获取请求参数和响应参数
handlerinterceptor中获取请求参数和响应参数在Spring框架中,`HandlerInterceptor` 是一个接口,它允许你在请求处理之前和之后进行一些自定义的操作。
但是,直接在`HandlerInterceptor` 中获取请求参数和响应参数是有一些限制的,因为在这个拦截器的上下文中并没有直接暴露这些信息。
不过,你可以通过以下方式间接地获取请求参数和响应参数:1. **获取请求参数**:你可以通过`HttpServletRequest` 对象来获取请求参数。
在`preHandle` 方法中,你可以注入`HttpServletRequest` 对象,然后使用它来获取请求参数。
例如:```java@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String param = request.getParameter("myParam");// ...return true;}```2. **获取响应参数**:对于响应参数,情况要复杂一些,因为响应参数是在请求处理之后才生成的。
在`afterCompletion` 方法中,你可以获取到响应的主体,但这通常不是一个好主意,因为它可能会违反了你的应用程序的逻辑。
如果你确实需要在响应中添加一些参数,我建议你在控制器中返回一个特定的响应对象,然后在`HandlerInterceptor` 中检查这个响应对象。
例如:返回的响应对象:```javapublic class CustomResponse {private String responseParam;// getters and setters}```在控制器中:```java@RequestMapping("/somePath")public CustomResponse someMethod(HttpServletRequest request) {// ... 处理请求...CustomResponse response = new CustomResponse();response.setResponseParam("someValue");return response;}```然后在`HandlerInterceptor` 中:```java@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {if (modelAndView instanceof CustomResponse) {CustomResponse customResponse = (CustomResponse) modelAndView;String responseParam =customResponse.getResponseParam();// ... 处理响应参数...}}```这样,你就可以在`HandlerInterceptor` 中间接地获取请求参数和响应参数了。
handlermethodargumentresolver 用法
handlermethodargumentresolver 用法HandlerMethodArgumentResolver是Spring MVC框架提供的一个接口,用于自定义方法参数的解析器。
通过实现该接口,我们可以自定义对请求参数的解析过程,从而实现更加灵活的方法参数绑定。
使用HandlerMethodArgumentResolver需要以下几步:1. 创建自定义的方法参数解析器类,并实现HandlerMethodArgumentResolver接口。
在实现类中,需要实现两个方法:supportsParameter和resolveArgument。
2. 在实现supportsParameter方法时,我们需要判断当前的方法参数是否需要由该解析器处理。
如果需要处理,则返回true,否则返回false。
3. 在实现resolveArgument方法时,我们需要对请求参数进行解析,并将解析结果封装成一个对象返回。
在这个方法中,我们可以访问到当前的请求对象、响应对象以及控制器方法的参数注解等信息。
4. 在Spring MVC配置文件中注册自定义的方法参数解析器。
可以通过<mvc:annotation-driven>元素的argument-resolvers属性来注册解析器,也可以通过Java代码的方式注册。
下面是一个简单的示例演示了HandlerMethodArgumentResolver的用法:首先,我们定义一个自定义的方法参数解析器类:```javapublic class CustomArgumentResolver implements HandlerMethodArgumentResolver {@Overridepublic boolean supportsParameter(MethodParameter parameter) {// 判断方法参数类型是否为我们需要处理的类型return parameter.getParameterType().equals(CustomParameter.class);}@Overridepublic Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {// 解析请求参数,并将解析结果封装成CustomParameter对象返回HttpServletRequest request =webRequest.getNativeRequest(HttpServletRequest.class);String value = request.getParameter("customParam");return new CustomParameter(value);}}```然后,在Spring MVC的配置文件中注册自定义的解析器:```xml<mvc:annotation-driven><mvc:argument-resolvers><bean class="com.example.CustomArgumentResolver" /></mvc:argument-resolvers></mvc:annotation-driven>```现在,我们可以在控制器方法中使用自定义的方法参数了:```java@RequestMapping("/example")public String exampleMethod(CustomParameter customParam) {// 使用customParam参数进行业务逻辑处理// ...return "example";}```在上面的示例中,我们通过实现HandlerMethodArgumentResolver接口创建了一个自定义的方法参数解析器CustomArgumentResolver。
关于@ApiImplicitParams、ApiImplicitParam的使用说明
关于@ApiImplicitParams、ApiImplicitParam的使⽤说明⽬录@ApiImplicitParam参数类型作⽤@ApiImplicitParamsparamType ⽰例详解⼩结⼀下测试@ApiImplicitParam作⽤在⽅法上,表⽰单独的请求参数参数name:参数名。
value:参数的具体意义,作⽤。
required:参数是否必填。
dataType:参数的数据类型。
paramType:查询参数类型,这⾥有⼏种形式:类型作⽤path 以地址的形式提交数据query 直接跟参数完成⾃动映射赋值body 以流的形式提交仅⽀持POSTheader 参数在request headers ⾥边提交form 以form表单的形式提交仅⽀持POST在这⾥我被坑过⼀次:当我发POST请求的时候,当时接受的整个参数,不论我⽤body还是query,后台都会报Body Missing错误。
这个参数和SpringMvc中的@RequestBody冲突,索性我就去掉了paramType,对接⼝测试并没有影响。
@ApiImplicitParams⽤于⽅法,包含多个 @ApiImplicitParam:例:@ApiOperation("查询测试")@GetMapping("select")//@ApiImplicitParam(name="name",value="⽤户名",dataType="String", paramType = "query")@ApiImplicitParams({@ApiImplicitParam(name="name",value="⽤户名",dataType="string", paramType = "query",example="xingguo"),@ApiImplicitParam(name="id",value="⽤户id",dataType="long", paramType = "query")})public void select(){}paramType ⽰例详解path@RequestMapping(value = "/findById1/{id}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)@PathVariable(name = "id") Long idbody@ApiImplicitParams({ @ApiImplicitParam(paramType = "body", dataType = "MessageParam", name = "param", value = "信息参数", required = true) })@RequestMapping(value = "/findById3", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)@RequestBody MessageParam param提交的参数是这个对象的⼀个json,然后会⾃动解析到对应的字段上去,也可以通过流的形式接收当前的请求数据,但是这个和上⾯的接收⽅式仅能使⽤⼀个(⽤@RequestBody之后流就会关闭了)header@ApiImplicitParams({ @ApiImplicitParam(paramType = "header", dataType = "Long", name = "id", value = "信息id", required = true) })String idstr = request.getHeader("id");if (StringUtils.isNumeric(idstr)) {id = Long.parseLong(idstr);}Form@ApiImplicitParams({ @ApiImplicitParam(paramType = "form", dataType = "Long", name = "id", value = "信息id", required = true) })@RequestMapping(value = "/findById5", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)⼩结⼀下(1)对于@ApiImplicitParam的paramType:query、form域中的值需要使⽤@RequestParam获取, header域中的值需要使⽤@RequestHeader来获取,path域中的值需要使⽤@PathVariable来获取,body域中的值使⽤@RequestBody来获取,否则可能出错;⽽且如果paramType是body,name就不能是body,否则有问题,与官⽅⽂档中的“If paramType is "body", the name should be "body"不符。
handlerinterceptor实现原理
handlerinterceptor实现原理
HandlerInterceptor 是 Spring MVC 提供的拦截器接口,用于在
请求发送到 Handler 前后进行预处理和后处理。
其实现原理如下:
1. DispatcherServlet 接收到请求后,会首先经过各种前置处理
器(HandlerInterceptor)的 preHandle 方法。
2. preHandle 方法中可以进行一些预处理操作,如登录验证、
权限校验等。
3. 如果所有的前置处理器(HandlerInterceptor)的 preHandle
方法都返回 true,则请求会进入 Controller,并执行对应的处
理方法。
4. 在执行完 Controller 方法后,请求会进入后置处理器(HandlerInterceptor)的 postHandle 方法。
5. postHandle 方法中可以进行一些后处理操作,如添加公共参数、设置响应头等。
6. 最后,请求会再次进入所有后置处理器(HandlerInterceptor)的 afterCompletion 方法。
7. afterCompletion 方法中可以进行一些清理工作,如释放资源、记录日志等。
8. 请求处理完成后,DispatcherServlet 会根据响应结果进行渲
染并返回给客户端。
总的来说,HandlerInterceptor 是通过在 DispatcherServlet 中添
加拦截器链来实现的。
在链中,每个拦截器都有机会对请求进行处理,通过返回值控制请求的流程。
这种设计模式使得拦截器能够灵活地进行预处理、后处理和异常处理。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
自己封装的一个SolrDataImportRequestHandlerScheduler经过将近一天的努力,终于搞定了Solr的 Data Import Request Handler Scheduler。
Scheduler主要解决两个问题:1.定时增量更新索引。
2.定时重做索引。
经过测试,Scheduler已经可以实现完全基于配置,无需开发功能,无需人工干预的情况下实现以上两个功能(结合Solr 的 Data Import Request Handler前提下)。
这里贴出一下主要的代码备忘:BaseTimerTask.java TimerTask基类,封装了一些基本的属性读取、请求发送方法:1package org.apache.solr.handler.dataimport.scheduler;23import java.io.IOException;4import .HttpURLConnection;5import .MalformedURLException;6import .URL;7import java.text.DateFormat;8import java.text.ParseException;9import java.text.SimpleDateFormat;10import java.util.Date;11import java.util.Timer;12import java.util.TimerTask;1314import org.slf4j.Logger;15import org.slf4j.LoggerFactory;1617public abstract class BaseTimerTask extends TimerTask {18protected String syncEnabled;19protected String[] syncCores;20protected String server;21protected String port;22protected String webapp;23protected String params;24protected String interval;25protected String cores;26protected SolrDataImportProperties p;27protected boolean singleCore;2829protected String reBuildIndexParams;30protected String reBuildIndexBeginTime;31protected String reBuildIndexInterval;3233protected static final Logger logger = LoggerFactory34.getLogger(BaseTimerTask.class);3536public BaseTimerTask(String webAppName, Timer t) throws Exception {37// load properties from global dataimport.properties38p = new SolrDataImportProperties();39reloadParams();40fixParams(webAppName);4142if (!syncEnabled.equals("1"))43throw new Exception("Schedule disabled");4445if (syncCores == null46|| (syncCores.length == 1 && syncCores[0].isEmpty())) {47singleCore = true;("<index update process> Single core identified in dataimport.properties");49} else {50singleCore = false;("<index update process> Multiple cores identified in dataimport.properties. Sync active for: " 52+ cores);53}54}5556protected void reloadParams() {57p.loadProperties(true);58syncEnabled = p.getProperty(SolrDataImportProperties.SYNC_ENABLED);59cores = p.getProperty(SolrDataImportProperties.SYNC_CORES);60server = p.getProperty(SolrDataImportProperties.SERVER);61port = p.getProperty(SolrDataImportProperties.PORT);62webapp = p.getProperty(SolrDataImportProperties.WEBAPP);63params = p.getProperty(SolrDataImportProperties.PARAMS);64interval = p.getProperty(SolrDataImportProperties.INTERVAL);65syncCores = cores != null ? cores.split(",") : null;6667reBuildIndexParams = p68.getProperty(SolrDataImportProperties.REBUILDINDEXPARAMS); 69reBuildIndexBeginTime = p70.getProperty(SolrDataImportProperties.REBUILDINDEXBEGINTIME); 71reBuildIndexInterval = p72.getProperty(SolrDataImportProperties.REBUILDINDEXINTERVAL); 7374}7576protected void fixParams(String webAppName) {77if (server == null || server.isEmpty())78server = "localhost";79if (port == null || port.isEmpty())80port = "8080";81if (webapp == null || webapp.isEmpty())82webapp = webAppName;83if (interval == null || interval.isEmpty() || getIntervalInt() <= 0)84interval = "30";85if (reBuildIndexBeginTime == null || reBuildIndexBeginTime.isEmpty())86interval = "00:00:00";87if (reBuildIndexInterval == null || reBuildIndexInterval.isEmpty()88|| getReBuildIndexIntervalInt() <= 0)89reBuildIndexInterval = "0";90}9192protected void prepUrlSendHttpPost(String params) {93String coreUrl = "http://" + server + ":" + port + "/" + webapp94+ params;95sendHttpPost(coreUrl, null);96}9798protected void prepUrlSendHttpPost(String coreName, String params) {99String coreUrl = "http://" + server + ":" + port + "/" + webapp + "/"100+ coreName + params;101sendHttpPost(coreUrl, coreName);102}103104protected void sendHttpPost(String completeUrl, String coreName) {105DateFormat df = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss SSS");106Date startTime = new Date();107108// prepare the core var109String core = coreName == null ? "" : "[" + coreName + "] ";110(core112+ "<index update process> Process started at .............. "113+ df.format(startTime));114115try {116117URL url = new URL(completeUrl);118HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 119120conn.setRequestMethod("POST");121conn.setRequestProperty("type", "submit");122conn.setDoOutput(true);123124// Send HTTP POST125conn.connect();126(core + "<index update process> Full URL\t\t\t\t"128+ conn.getURL());(core + "<index update process> Response message\t\t\t"130+ conn.getResponseMessage());(core + "<index update process> Response code\t\t\t"132+ conn.getResponseCode());133134// listen for change in properties file if an error occurs135if (conn.getResponseCode() != 200) {136reloadParams();137}138139conn.disconnect();(core141+ "<index update process> Disconnected from server\t\t"142+ server);143Date endTime = new Date();(core145+ "<index update process> Process ended at ................ "146+ df.format(endTime));147} catch (MalformedURLException mue) {148logger.error("Failed to assemble URL for HTTP POST", mue);149} catch (IOException ioe) {150logger.error(151"Failed to connect to the specified URL while trying to send HTTP POST", 152ioe);153} catch (Exception e) {154logger.error("Failed to send HTTP POST", e);155}156}157158public int getIntervalInt() {159try {160return Integer.parseInt(interval);161} catch (NumberFormatException e) {162logger.warn(163"Unable to convert 'interval' to number. Using default value (30) instead", 164e);165return 30; // return default in case of error166}167}168169public int getReBuildIndexIntervalInt() {170try {171return Integer.parseInt(reBuildIndexInterval);172} catch (NumberFormatException e) {(174"Unable to convert 'reBuildIndexInterval' to number. do't rebuild index.", 175e);176return 0; // return default in case of error177}178}179180public Date getReBuildIndexBeginTime() {181Date beginDate = null;182try {183SimpleDateFormat sdfDate = new SimpleDateFormat("yyyy-MM-dd");184String dateStr = sdfDate.format(new Date());185beginDate = sdfDate.parse(dateStr);186if (reBuildIndexBeginTime == null187|| reBuildIndexBeginTime.isEmpty()) {189}190if (reBuildIndexBeginTime.matches("\\d{2}:\\d{2}:\\d{2}")) {191SimpleDateFormat sdf = new SimpleDateFormat(192"yyyy-MM-dd HH:mm:ss");193beginDate = sdf.parse(dateStr + " " + reBuildIndexBeginTime);194} else if (reBuildIndexBeginTime195.matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}")) {196SimpleDateFormat sdf = new SimpleDateFormat(197"yyyy-MM-dd HH:mm:ss");198beginDate = sdf.parse(reBuildIndexBeginTime);199}200return beginDate;201} catch (ParseException e) {202logger.warn(203"Unable to convert 'reBuildIndexBeginTime' to date. use now time.",204e);205return beginDate;206}207}208209 }DeltaImportHTTPPostScheduler.java 增量索引更新任务计划:1package org.apache.solr.handler.dataimport.scheduler;23import java.util.Timer;45import org.slf4j.Logger;6import org.slf4j.LoggerFactory;78/**9* 增量更新索引的任务10* @author zhangliang11*12*/13public class DeltaImportHTTPPostScheduler extends BaseTimerTask {1415private static final Logger logger = LoggerFactory16.getLogger(DeltaImportHTTPPostScheduler.class);1718public DeltaImportHTTPPostScheduler(String webAppName, Timer t)19throws Exception {20super(webAppName, t);("<index update process> DeltaImportHTTPPostScheduler init");22}2324public void run() {25try {26// check mandatory params27if (server.isEmpty() || webapp.isEmpty() || params == null28|| params.isEmpty()) {29logger.warn("<index update process> Insuficient info provided for data import"); ("<index update process> Reloading global dataimport.properties"); 31reloadParams();32// single-core33} else if (singleCore) {34prepUrlSendHttpPost(params);3536// multi-core37} else if (syncCores.length == 038|| (syncCores.length == 1 && syncCores[0].isEmpty())) {39logger.warn("<index update process> No cores scheduled for data import");("<index update process> Reloading global dataimport.properties");4243} else {44for (String core : syncCores) {45prepUrlSendHttpPost(core, params);46}47}48} catch (Exception e) {49logger.error("Failed to prepare for sendHttpPost", e);50reloadParams();51}52}53 }FullImportHTTPPostScheduler.java 重做索引任务计划:1package org.apache.solr.handler.dataimport.scheduler;23import java.util.Timer;45import org.slf4j.Logger;6import org.slf4j.LoggerFactory;78/**9* 重做索引的任务10* @author zhangliang11*12*/13public class FullImportHTTPPostScheduler extends BaseTimerTask {1415private static final Logger logger = LoggerFactory16.getLogger(FullImportHTTPPostScheduler.class);1718public FullImportHTTPPostScheduler(String webAppName, Timer t)19throws Exception {20super(webAppName, t);("<index update process> DeltaImportHTTPPostScheduler init");22}2324public void run() {25try {26// check mandatory params27if (server.isEmpty() || webapp.isEmpty()28|| reBuildIndexParams == null29|| reBuildIndexParams.isEmpty()) {30logger.warn("<index update process> Insuficient info provided for data import, reBuildIndexParams is null"); ("<index update process> Reloading global dataimport.properties");32reloadParams();33// single-core34} else if (singleCore) {35prepUrlSendHttpPost(reBuildIndexParams);3637// multi-core38} else if (syncCores.length == 039|| (syncCores.length == 1 && syncCores[0].isEmpty())) {40logger.warn("<index update process> No cores scheduled for data import");("<index update process> Reloading global dataimport.properties");42reloadParams();4344} else {45for (String core : syncCores) {46prepUrlSendHttpPost(core, reBuildIndexParams);47}48}49} catch (Exception e) {50logger.error("Failed to prepare for sendHttpPost", e);51reloadParams();52}53}54 }ApplicationListener.java 调用任务计划的Listener:1package org.apache.solr.handler.dataimport.scheduler;23import java.util.Calendar;4import java.util.Date;5import java.util.Timer;67import javax.servlet.ServletContext;8import javax.servlet.ServletContextEvent;9import javax.servlet.ServletContextListener;1011import org.slf4j.Logger;12import org.slf4j.LoggerFactory;1314public class ApplicationListener implements ServletContextListener {1516private static final Logger logger = LoggerFactory17.getLogger(ApplicationListener.class);1819@Override20public void contextDestroyed(ServletContextEvent servletContextEvent) {21ServletContext servletContext = servletContextEvent.getServletContext();2223// get our timer from the context24Timer timer = (Timer) servletContext.getAttribute("timer");25Timer fullImportTimer = (Timer) servletContext26.getAttribute("fullImportTimer");2728// cancel all active tasks in the timers queue29if (timer != null)30timer.cancel();31if (fullImportTimer != null)32fullImportTimer.cancel();3334// remove the timer from the context35servletContext.removeAttribute("timer");36servletContext.removeAttribute("fullImportTimer");3738}3940@Override41public void contextInitialized(ServletContextEvent servletContextEvent) {42ServletContext servletContext = servletContextEvent.getServletContext();43try {44// 增量更新任务计划45// create the timer and timer task objects46Timer timer = new Timer();47DeltaImportHTTPPostScheduler task = new DeltaImportHTTPPostScheduler( 48servletContext.getServletContextName(), timer);4950// get our interval from HTTPPostScheduler51int interval = task.getIntervalInt();5253// get a calendar to set the start time (first run)54Calendar calendar = Calendar.getInstance();5556// set the first run to now + interval (to avoid fireing while the57// app/server is starting)58calendar.add(Calendar.MINUTE, interval);59Date startTime = calendar.getTime();6061// schedule the task62timer.scheduleAtFixedRate(task, startTime, 1000 * 60 * interval);6364// save the timer in context65servletContext.setAttribute("timer", timer);6667// 重做索引任务计划68Timer fullImportTimer = new Timer();69FullImportHTTPPostScheduler fullImportTask = new FullImportHTTPPostScheduler(70servletContext.getServletContextName(), fullImportTimer);7172int reBuildIndexInterval = fullImportTask73.getReBuildIndexIntervalInt();74if (reBuildIndexInterval <= 0) {75logger.warn("Full Import Schedule disabled");76return;77}7879Calendar fullImportCalendar = Calendar.getInstance();80Date beginDate = fullImportTask.getReBuildIndexBeginTime();81fullImportCalendar.setTime(beginDate);82fullImportCalendar.add(Calendar.MINUTE, reBuildIndexInterval);83Date fullImportStartTime = fullImportCalendar.getTime();8485// schedule the task86fullImportTimer.scheduleAtFixedRate(fullImportTask,87fullImportStartTime, 1000 * 60 * reBuildIndexInterval);8889// save the timer in context90servletContext.setAttribute("fullImportTimer", fullImportTimer);9192} catch (Exception e) {93if (e.getMessage().endsWith("disabled")) {94logger.warn("Schedule disabled");95} else {96logger.error("Problem initializing the scheduled task: ", e);97}98}99100}101102 }使用说明1.将上面的编译文件打包成apache-solr-dataimportscheduler-1.0.jar,然后和solr自带的apache-solr-dataimporthandler-*.jar, apache-solr-dataimporthandler-extras-*.jar 放到solr.war的lib目录下面2.修改solr.war中WEB-INF/web.xml, 在servlet节点前面增加:<listener><listener-class>org.apache.solr.handler.dataimport.scheduler.ApplicationListener</listener-class></listener>3.将apache-solr-dataimportscheduler-.jar 中dataimport.properties 取出并根据实际情况修改,然后放到solr.home/conf (不是solr.home/core/conf) 目录下面4.重启tomcat或者jboss 即可dataimport.properties 配置项说明################################################## ## dataimport scheduler properties ## ################################################### to sync or not to sync# 1 - active; anything else - inactivesyncEnabled=1# which cores to schedule# in a multi-core environment you can decide which cores you want syncronized# leave empty or comment it out if using single-core deploymentsyncCores=core1,core2# solr server name or IP address# [defaults to localhost if empty]server=localhost# solr server port# [defaults to 80 if empty]port=8080# application name/context# [defaults to current ServletContextListener's context (app) name]webapp=solr# URL params [mandatory]# remainder of URLparams=/dataimport?command=delta-import&clean=false&commit=true# schedule interval# number of minutes between two runs# [defaults to 30 if empty]interval=1# 重做索引的时间间隔,单位分钟,默认7200,即5天;# 为空,为0,或者注释掉:表示永不重做索引reBuildIndexInterval=7200# 重做索引的参数reBuildIndexParams=/dataimport?command=full-import&clean=true&commit=true# 重做索引时间间隔的计时开始时间,第一次真正执行的时间=reBuildIndexBeginTime+reBuildIndexInterval*60*1000;# 两种格式:2012-04-11 03:10:00 或者03:10:00,后一种会自动补全日期部分为服务启动时的日期reBuildIndexBeginTime=03:10:00。