`

lucene与数据库结合使用

阅读更多

转帖:http://jushi1988.iteye.com/blog/693188

 

---  2010-06-18 17:00 代码修改: 修改重复创建索引,添加双字段高亮。


 

   今天发一个简单的和数据库交互的Lucene示例,只是初步的靠Lucene自带的分词实现中文分词,效果肯定没有网上琳琅的分词器相媲美,只为了示例,用了自带的高亮。页面不好看,将就一下哦。

    主要是由 Spring + Struts1 + Mysql 5 实现, 只是为了实现功能。请各位大侠拍砖。

    好了,不多说了。贴代码:

 

    1. T_ARTICLE 表

Java代码 
DROP TABLE IF EXISTS `t_article`;  
CREATE TABLE `t_article` (  
  `ID` varchar(32) NOT NULL default '',  
  `ARTICLE_TITLE` varchar(255) default NULL,  
  `ARTICLE_TAG` varchar(255) default NULL,  
  `ARTICLE_CONTENT` text,  
  PRIMARY KEY  (`ID`)  
) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

DROP TABLE IF EXISTS `t_article`;
CREATE TABLE `t_article` (
  `ID` varchar(32) NOT NULL default '',
  `ARTICLE_TITLE` varchar(255) default NULL,
  `ARTICLE_TAG` varchar(255) default NULL,
  `ARTICLE_CONTENT` text,
  PRIMARY KEY  (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;    上面的数据 随便加一下吧,主要是article_content和article_title字段的数据,article_content是个text字段,所以你可以粘贴网页的文字内容添加到本字段中。

 

    2.业务接口 ArticleService.java

 

Java代码 
package com.jushi.lucene.business;  
 
import java.util.List;  
import com.jushi.lucene.entities.Article;  
/** 
 * @Author jushi 
 * @CreateDate Jun 4, 2010 1:24:42 PM 
 * @Version V 1.0 
 */ 
 
public interface IArticleService {  
 
    public List<Article> getArticles(String query);  
 
    public boolean createIndex();  
 

package com.jushi.lucene.business;

import java.util.List;
import com.jushi.lucene.entities.Article;
/**
 * @Author jushi
 * @CreateDate Jun 4, 2010 1:24:42 PM
 * @Version V 1.0
 */

public interface IArticleService {

 public List<Article> getArticles(String query);

 public boolean createIndex();

}


   3. 接口的实现 ArticleServiceImpl.java 主要的业务在这里实现:创建索引,搜索数据处理。

 

Java代码 
package com.jushi.lucene.business;  
 
import java.io.File;  
import java.io.StringReader;  
import java.util.ArrayList;  
import java.util.Date;  
import java.util.List;  
 
import org.apache.lucene.analysis.Analyzer;  
import org.apache.lucene.analysis.TokenStream;  
import org.apache.lucene.analysis.standard.StandardAnalyzer;  
import org.apache.lucene.document.Document;  
import org.apache.lucene.document.Field;  
import org.apache.lucene.index.IndexWriter;  
import org.apache.lucene.queryParser.MultiFieldQueryParser;  
import org.apache.lucene.search.BooleanClause;  
import org.apache.lucene.search.Filter;  
import org.apache.lucene.search.IndexSearcher;  
import org.apache.lucene.search.Query;  
import org.apache.lucene.search.ScoreDoc;  
import org.apache.lucene.search.TopDocs;  
import org.apache.lucene.search.highlight.Highlighter;  
import org.apache.lucene.search.highlight.QueryScorer;  
import org.apache.lucene.search.highlight.SimpleFragmenter;  
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;  
import org.apache.lucene.store.Directory;  
import org.apache.lucene.store.FSDirectory;  
 
import com.jushi.lucene.dao.IArticleDAO;  
import com.jushi.lucene.entities.Article;  
 
/** 
 * @Author jushi 
 * @CreateDate Jun 4, 2010 1:25:00 PM 
 * @Version V 1.0 
 */ 
public class ArticleServiceImpl implements IArticleService {  
      
    private IArticleDAO articleDAO;  
      
    private final String INDEXPATH = "g:\\index";  
    private Analyzer analyzer = new StandardAnalyzer();  
      
    public List<Article> getArticles(String query) {  
          
        try{  
        List<Article> qlist = new ArrayList<Article>();  
        String fieldName = "title";  
        IndexSearcher indexSearcher = new IndexSearcher(INDEXPATH);  
          
        //QueryParser parser = new QueryParser(fieldName, analyzer); //单 key 搜索  
        //Query queryOBJ = parser.parse(query);  
        System.out.println(">>> 2.开始读取索引... ... 通过关键字:【 "+ query +" 】");  
        long begin = new Date().getTime();  
          
        //下面的是进行title,content 两个范围内进行收索.  
        BooleanClause.Occur[] clauses = { BooleanClause.Occur.SHOULD,BooleanClause.Occur.SHOULD };  
        Query queryOBJ = MultiFieldQueryParser.parse(query, new String[]{"title","content"}, clauses, new StandardAnalyzer());//parser.parse(query);  
        Filter filter = null;  
          
        //################# 搜索相似度最高的记录 ###################  
        TopDocs topDocs = indexSearcher.search(queryOBJ, filter, 1000);  
        //TopDocs topDocs = indexSearcher.search(queryOBJ , 10000);  
        System.out.println("*** 共匹配:" + topDocs.totalHits + "个 ***");  
          
        Article article = null;  
          
        //输出结果  
        for (ScoreDoc scoreDoc : topDocs.scoreDocs){  
                Document targetDoc = indexSearcher.doc(scoreDoc.doc);  
                article = new Article();  
                  
                //设置高亮显示格式  
                SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<font color='red'><strong>", "</strong></font>");   
                /* 语法高亮显示设置 */ 
                Highlighter highlighter = new Highlighter(simpleHTMLFormatter,new QueryScorer(queryOBJ));   
                highlighter.setTextFragmenter(new SimpleFragmenter(100));   
                  
                // 设置高亮 设置 title,content 字段  
                String title = targetDoc.get("title");  
                String content = targetDoc.get("content");  
                TokenStream titleTokenStream = analyzer.tokenStream(fieldName,new StringReader(title));  
                TokenStream contentTokenStream = analyzer.tokenStream("content",new StringReader(content));  
                String highLightTitle = highlighter.getBestFragment(titleTokenStream, title);  
                String highLightContent = highlighter.getBestFragment(contentTokenStream, content);  
                  
                 if(highLightTitle == null)  
                     highLightTitle = title;  
 
                 if(highLightContent == null)   
                     highLightContent = content;  
                   
                article.setTitle(highLightTitle);  
                article.setContent(highLightContent);  
                article.setTag(targetDoc.get("tag"));  
                article.setTotalHits(topDocs.totalHits);  
                  
                qlist.add(article);  
        }  
          
        long end = new Date().getTime();  
        System.out.println(">>> 3.搜索完毕... ... 共花费:" + (end - begin) +"毫秒...");  
          
        indexSearcher.close();  
          
        return qlist;  
          
        }catch(Exception e){  
            e.printStackTrace();  
            return null;  
        }  
    }  
      
    public boolean createIndex()  
    {  
        //检查索引是否存在  
        if(this.isIndexExisted())  
            return this.isIndexExisted();  
          
        List<Article> list = articleDAO.getArticles();  
          
        try 
        {  
            Directory directory = FSDirectory.getDirectory(INDEXPATH);  
            IndexWriter indexWriter = new IndexWriter(directory, analyzer ,true, IndexWriter.MaxFieldLength.LIMITED);  
              
            long begin = new Date().getTime();  
            for(Article art: list)  
            {  
                Document doc = new Document();  
                String title = art.getTitle() == null ? "" : art.getTitle().trim();  
                String content = art.getContent() == null ? "" : art.getContent();  
                String tag = art.getTag() == null ? "" : art.getTag();  
                doc.add(new Field("title", title, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES));  
                doc.add(new Field("content", content, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES));  
                doc.add(new Field("tag", tag, Field.Store.COMPRESS,Field.Index.NO));  
                indexWriter.addDocument(doc);  
            }  
            long end = new Date().getTime();  
            System.out.println(">>> 1.存入索引完毕.. 共花费:" + (end - begin) +"毫秒...");  
              
            indexWriter.optimize();  
            indexWriter.close();  
            return true;  
              
        }catch(Exception e){  
            e.printStackTrace();  
            return false;  
        }  
    }  
      
    /** 
     * check Index is Existed 
     * @return true or false 
     */ 
    private boolean isIndexExisted()  
    {  
        try 
        {  
            File dir = new File(INDEXPATH);  
            if(dir.listFiles().length>0)  
                return true;  
            else 
                return false;  
              
        }catch(Exception e){  
            e.printStackTrace();  
            return false;  
        }  
    }  
      
    public void setArticleDAO(IArticleDAO articleDAO) {  
        this.articleDAO = articleDAO;  
    }  
 

package com.jushi.lucene.business;

import java.io.File;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleFragmenter;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;

import com.jushi.lucene.dao.IArticleDAO;
import com.jushi.lucene.entities.Article;

/**
 * @Author jushi
 * @CreateDate Jun 4, 2010 1:25:00 PM
 * @Version V 1.0
 */
public class ArticleServiceImpl implements IArticleService {
 
 private IArticleDAO articleDAO;
 
 private final String INDEXPATH = "g:\\index";
 private Analyzer analyzer = new StandardAnalyzer();
 
 public List<Article> getArticles(String query) {
  
  try{
  List<Article> qlist = new ArrayList<Article>();
  String fieldName = "title";
  IndexSearcher indexSearcher = new IndexSearcher(INDEXPATH);
  
  //QueryParser parser = new QueryParser(fieldName, analyzer); //单 key 搜索
  //Query queryOBJ = parser.parse(query);
  System.out.println(">>> 2.开始读取索引... ... 通过关键字:【 "+ query +" 】");
  long begin = new Date().getTime();
  
  //下面的是进行title,content 两个范围内进行收索.
  BooleanClause.Occur[] clauses = { BooleanClause.Occur.SHOULD,BooleanClause.Occur.SHOULD };
  Query queryOBJ = MultiFieldQueryParser.parse(query, new String[]{"title","content"}, clauses, new StandardAnalyzer());//parser.parse(query);
  Filter filter = null;
  
  //################# 搜索相似度最高的记录 ###################
  TopDocs topDocs = indexSearcher.search(queryOBJ, filter, 1000);
  //TopDocs topDocs = indexSearcher.search(queryOBJ , 10000);
  System.out.println("*** 共匹配:" + topDocs.totalHits + "个 ***");
  
  Article article = null;
  
  //输出结果
  for (ScoreDoc scoreDoc : topDocs.scoreDocs){
    Document targetDoc = indexSearcher.doc(scoreDoc.doc);
    article = new Article();
    
    //设置高亮显示格式
    SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<font color='red'><strong>", "</strong></font>");
    /* 语法高亮显示设置 */
    Highlighter highlighter = new Highlighter(simpleHTMLFormatter,new QueryScorer(queryOBJ));
    highlighter.setTextFragmenter(new SimpleFragmenter(100));
    
    // 设置高亮 设置 title,content 字段
    String title = targetDoc.get("title");
    String content = targetDoc.get("content");
    TokenStream titleTokenStream = analyzer.tokenStream(fieldName,new StringReader(title));
    TokenStream contentTokenStream = analyzer.tokenStream("content",new StringReader(content));
    String highLightTitle = highlighter.getBestFragment(titleTokenStream, title);
    String highLightContent = highlighter.getBestFragment(contentTokenStream, content);
    
        if(highLightTitle == null)
         highLightTitle = title;

        if(highLightContent == null)
         highLightContent = content;
       
       article.setTitle(highLightTitle);
    article.setContent(highLightContent);
    article.setTag(targetDoc.get("tag"));
    article.setTotalHits(topDocs.totalHits);
    
    qlist.add(article);
  }
  
  long end = new Date().getTime();
  System.out.println(">>> 3.搜索完毕... ... 共花费:" + (end - begin) +"毫秒...");
  
  indexSearcher.close();
  
  return qlist;
  
  }catch(Exception e){
   e.printStackTrace();
   return null;
  }
 }
 
 public boolean createIndex()
 {
  //检查索引是否存在
  if(this.isIndexExisted())
   return this.isIndexExisted();
  
  List<Article> list = articleDAO.getArticles();
  
  try
  {
   Directory directory = FSDirectory.getDirectory(INDEXPATH);
   IndexWriter indexWriter = new IndexWriter(directory, analyzer ,true, IndexWriter.MaxFieldLength.LIMITED);
   
   long begin = new Date().getTime();
   for(Article art: list)
   {
    Document doc = new Document();
    String title = art.getTitle() == null ? "" : art.getTitle().trim();
    String content = art.getContent() == null ? "" : art.getContent();
    String tag = art.getTag() == null ? "" : art.getTag();
    doc.add(new Field("title", title, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES));
    doc.add(new Field("content", content, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.YES));
    doc.add(new Field("tag", tag, Field.Store.COMPRESS,Field.Index.NO));
    indexWriter.addDocument(doc);
   }
   long end = new Date().getTime();
   System.out.println(">>> 1.存入索引完毕.. 共花费:" + (end - begin) +"毫秒...");
   
   indexWriter.optimize();
   indexWriter.close();
   return true;
   
  }catch(Exception e){
   e.printStackTrace();
   return false;
  }
 }
 
 /**
  * check Index is Existed
  * @return true or false
  */
 private boolean isIndexExisted()
 {
  try
  {
   File dir = new File(INDEXPATH);
   if(dir.listFiles().length>0)
    return true;
   else
    return false;
   
  }catch(Exception e){
   e.printStackTrace();
   return false;
  }
 }
 
 public void setArticleDAO(IArticleDAO articleDAO) {
  this.articleDAO = articleDAO;
 }

}

    4. DAO 接口及 DAO实现 

 

Java代码 
public interface IArticleDAO {  
 
    public List<Article> getArticles();  

public interface IArticleDAO {

 public List<Article> getArticles();
}

 

Java代码 
public class ArticleDAOImpl extends JdbcDaoSupport implements IArticleDAO{  
 
    public List<Article> getArticles() {  
        String sql = "SELECT article_title, article_tag, article_content FROM t_article";  
        return (List<Article>)this.getJdbcTemplate().query(sql, new ArticleRowMapper());  
    }  
 

public class ArticleDAOImpl extends JdbcDaoSupport implements IArticleDAO{

 public List<Article> getArticles() {
  String sql = "SELECT article_title, article_tag, article_content FROM t_article";
  return (List<Article>)this.getJdbcTemplate().query(sql, new ArticleRowMapper());
 }

}

   5. 上面DAO需要的 ArticleRowMapper: 这里做了下小改动

 

Java代码 
package com.jushi.lucene.rowmapper;  
 
import java.sql.ResultSet;  
import java.sql.ResultSetMetaData;  
import java.sql.SQLException;  
 
import org.springframework.jdbc.core.RowMapper;  
 
import com.jushi.lucene.entities.Article;  
 
/** 
 * @Author jushi 
 * @CreateDate Jun 4, 2010 1:31:54 PM 
 * @Version V 1.0 
 */ 
public class ArticleRowMapper implements RowMapper {  
 
    public Object mapRow(ResultSet rs, int rowNum) throws SQLException {  
        Article article = new Article();  
        ResultSetMetaData meta = rs.getMetaData();  
        int colNum = meta.getColumnCount();  
        for (int i = 1; i <= colNum; i++) {  
            String colName = meta.getColumnName(i).toLowerCase();  
            if ("article_title".equals(colName)) {  
                article.setTitle(rs.getString(i));  
            } else if ("article_content".equals(colName)) {  
                article.setContent(rs.getString(i));  
            } else if ("article_tag".equals(colName)) {  
                article.setTag(rs.getString(i));  
                //...  
            }  
        }  
        return article;  
    }  

package com.jushi.lucene.rowmapper;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

import org.springframework.jdbc.core.RowMapper;

import com.jushi.lucene.entities.Article;

/**
 * @Author jushi
 * @CreateDate Jun 4, 2010 1:31:54 PM
 * @Version V 1.0
 */
public class ArticleRowMapper implements RowMapper {

 public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
  Article article = new Article();
  ResultSetMetaData meta = rs.getMetaData();
  int colNum = meta.getColumnCount();
  for (int i = 1; i <= colNum; i++) {
   String colName = meta.getColumnName(i).toLowerCase();
   if ("article_title".equals(colName)) {
    article.setTitle(rs.getString(i));
   } else if ("article_content".equals(colName)) {
    article.setContent(rs.getString(i));
   } else if ("article_tag".equals(colName)) {
    article.setTag(rs.getString(i));
    //...
   }
  }
  return article;
 }
}
 

   6. Article 实体 添加了两个属性: TotalHits, TotalTime

 

Java代码 
package com.jushi.lucene.entities;  
 
/** 
 * @Author jushi 
 * @CreateDate Jun 4, 2010 1:18:48 PM 
 * @Version V 1.0 
 */ 
public class Article {  
 
    private String title;  
    private String content;  
    private String tag;  
    private int TotalHits; //命中率  
    private int TotalTime; //花费时间  
      
    public int getTotalTime() {  
        return TotalTime;  
    }  
    public void setTotalTime(int totalTime) {  
        TotalTime = totalTime;  
    }  
    public String getTitle() {  
        return title;  
    }  
    public void setTitle(String title) {  
        this.title = title;  
    }  
    public String getContent() {  
        return content;  
    }  
    public void setContent(String content) {  
        this.content = content;  
    }  
    public String getTag() {  
        return tag;  
    }  
    public void setTag(String tag) {  
        this.tag = tag;  
    }  
    public int getTotalHits() {  
        return TotalHits;  
    }  
    public void setTotalHits(int totalHits) {  
        TotalHits = totalHits;  
    }  
      

package com.jushi.lucene.entities;

/**
 * @Author jushi
 * @CreateDate Jun 4, 2010 1:18:48 PM
 * @Version V 1.0
 */
public class Article {

 private String title;
 private String content;
 private String tag;
 private int TotalHits; //命中率
 private int TotalTime; //花费时间
 
 public int getTotalTime() {
  return TotalTime;
 }
 public void setTotalTime(int totalTime) {
  TotalTime = totalTime;
 }
 public String getTitle() {
  return title;
 }
 public void setTitle(String title) {
  this.title = title;
 }
 public String getContent() {
  return content;
 }
 public void setContent(String content) {
  this.content = content;
 }
 public String getTag() {
  return tag;
 }
 public void setTag(String tag) {
  this.tag = tag;
 }
 public int getTotalHits() {
  return TotalHits;
 }
 public void setTotalHits(int totalHits) {
  TotalHits = totalHits;
 }
 
}
 

   7. Spring 的配置如下:

   --- applicationContext-lucene.xml

 

Java代码 
<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">  
<beans>  
 
<bean id="articleDAO" class="com.jushi.lucene.dao.ArticleDAOImpl" scope="singleton" >    
    <property name="dataSource" ref="articleDataSource"></property>    
</bean>  
 
<bean id="articleService" class="com.jushi.lucene.business.ArticleServiceImpl" scope="singleton" >    
    <property name="articleDAO" ref="articleDAO"></property>   
</bean>   
    
</beans>  

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>

<bean id="articleDAO" class="com.jushi.lucene.dao.ArticleDAOImpl" scope="singleton" > 
 <property name="dataSource" ref="articleDataSource"></property> 
</bean>

<bean id="articleService" class="com.jushi.lucene.business.ArticleServiceImpl" scope="singleton" > 
 <property name="articleDAO" ref="articleDAO"></property>
</bean>
 
</beans>
   ---  applicationContext-lucene-datasource.xml

 

 

Java代码 
<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">  
<beans>  
 
<bean id="articleDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
    <property name="driverClassName" value="com.mysql.jdbc.Driver" ></property>  
    <property name="url" value="jdbc:mysql://localhost/companyweb?useUnicode=true&amp;characterEncoding=utf-8" />  
    <property name="username" value="root" />  
    <property name="password" value="jushi" />  
    <property name="initialSize" value="5" />  
    <property name="maxActive" value="20" />  
    <property name="maxIdle" value="20" />  
    <property name="minIdle" value="5" />  
</bean>   
 
</beans>  

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>

<bean id="articleDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
 <property name="driverClassName" value="com.mysql.jdbc.Driver" ></property>
 <property name="url" value="jdbc:mysql://localhost/companyweb?useUnicode=true&amp;characterEncoding=utf-8" />
 <property name="username" value="root" />
 <property name="password" value="jushi" />
 <property name="initialSize" value="5" />
 <property name="maxActive" value="20" />
 <property name="maxIdle" value="20" />
 <property name="minIdle" value="5" />
</bean>

</beans>
 

   8. action配置 struts-config.xml

 

Java代码 
<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">  
 
<struts-config>  
 
    <form-beans>  
       <form-bean name="lazyForm" type="org.apache.struts.validator.LazyValidatorForm"/>  
    </form-beans>  
    <action-mappings>  
      
        <action path="/index" 
                type="com.jushi.lucene.businessview.IndexAction" 
                name="lazyForm" parameter="m" scope="request" validate="false">  
                <forward name="result" path="/result.jsp"></forward>  
        </action>  
 
    </action-mappings>  
</struts-config> 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://struts.apache.org/dtds/struts-config_1_2.dtd">

<struts-config>

 <form-beans>
    <form-bean name="lazyForm" type="org.apache.struts.validator.LazyValidatorForm"/>
    </form-beans>
    <action-mappings>
   
     <action path="/index"
             type="com.jushi.lucene.businessview.IndexAction"
             name="lazyForm" parameter="m" scope="request" validate="false">
    <forward name="result" path="/result.jsp"></forward>
  </action>

 </action-mappings>
</struts-config>

    9. web.xml 文件配置: 监听、加载配置文件

 

 

Java代码 
<?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">  
      
    <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>classpath*:/springConfig/applicationContext*.xml</param-value>  
    </context-param>  
      
    <!--  Character Encoding filter -->  
    <filter>  
          <filter-name>encodingFilter</filter-name>  
          <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  
          <init-param>  
                   <param-name>encoding</param-name>  
                   <param-value>UTF-8</param-value>  
          </init-param>  
     </filter>  
     <filter-mapping>  
          <filter-name>encodingFilter</filter-name>  
          <url-pattern>/*</url-pattern>  
     </filter-mapping>  
       
     <listener>  
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    </listener>  
      
    <servlet>  
        <servlet-name>action</servlet-name>  
        <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>  
        <init-param>  
            <param-name>config</param-name>  
            <param-value>/WEB-INF/struts-config.xml</param-value>  
        </init-param>  
    </servlet>  
 
    <servlet-mapping>  
        <servlet-name>action</servlet-name>  
        <url-pattern>*.html</url-pattern>  
    </servlet-mapping>  
      
  <welcome-file-list>  
    <welcome-file>index.jsp</welcome-file>  
  </welcome-file-list>  
</web-app> 

<?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">
 
 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath*:/springConfig/applicationContext*.xml</param-value>
 </context-param>
 
 <!--  Character Encoding filter -->
 <filter>
          <filter-name>encodingFilter</filter-name>
          <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
          <init-param>
                   <param-name>encoding</param-name>
                   <param-value>UTF-8</param-value>
          </init-param>
     </filter>
     <filter-mapping>
          <filter-name>encodingFilter</filter-name>
          <url-pattern>/*</url-pattern>
     </filter-mapping>
    
     <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
 
 <servlet>
  <servlet-name>action</servlet-name>
  <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
  <init-param>
   <param-name>config</param-name>
   <param-value>/WEB-INF/struts-config.xml</param-value>
  </init-param>
 </servlet>

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

   10. 前端 View 两个jsp index.jsp和 result.jsp

 

     index.jsp

Java代码 
<%@ 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%>">  
      
    <title>简单的lucene测试</title>  
    <script type="text/javascript" src="js/CheckFunction.js"></script>  
    <script type="text/javascript">  
        function _search()  
        {  
            var form = document.form1;  
            if(Trim(form.title.value) == '')  
            {  
                alert("输入一个关键字吧!");  
                return false;  
            }  
            form.action = 'index.html?m=index';  
            form.submit();  
        }  
    </script>  
  </head>  
    
  <body>  
          
        <center><h1>测试Lucene</h1>  
        <hr/>  
        <form name="form1" action="index.html" method="post">  
        请输入文章的标题关键字:<input type="text" maxlength="20" name="title" size="40"/>&nbsp;  
        <button onclick="javascript:_search();return false;" style="border: thin;border-color: blue" name="search"> GO </button>  
        </form>  
        </center>  
  </body>  
</html> 

<%@ 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%>">
   
    <title>简单的lucene测试</title>
    <script type="text/javascript" src="js/CheckFunction.js"></script>
 <script type="text/javascript">
  function _search()
  {
   var form = document.form1;
   if(Trim(form.title.value) == '')
   {
    alert("输入一个关键字吧!");
    return false;
   }
   form.action = 'index.html?m=index';
   form.submit();
  }
 </script>
  </head>
 
  <body>
     
     <center><h1>测试Lucene</h1>
     <hr/>
     <form name="form1" action="index.html" method="post">
     请输入文章的标题关键字:<input type="text" maxlength="20" name="title" size="40"/>&nbsp;
     <button onclick="javascript:_search();return false;" style="border: thin;border-color: blue" name="search"> GO </button>
     </form>
     </center>
  </body>
</html>
 

    result.jsp

 

Java代码 
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>  
<%@ page import="com.jushi.lucene.entities.*"%>  
<%  
String path = request.getContextPath();  
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  
%>  
<%  
    List<Article> list = (List<Article>) request.getAttribute("articlelist");  
    String TotalTime = "0.000";  
    int TotalHits = 0;  
    if(request.getAttribute("totalTime")!=null)  
        TotalTime = request.getAttribute("totalTime").toString();  
    if(list.size()>0 && list!=null)  
        TotalHits = list.get(0).getTotalHits();   
%>  
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
<html>  
  <head>  
    <base href="<%=basePath%>">  
    <title>搜索的结果如下:</title>  
    <style type="text/css">  
        .Fee {  
            width: 650px;  
            height:28px;  
            float: right;  
            padding:1px;  
            overflow:hidden;  
            border-bottom:1px solid #bde2ff;  
            line-height:28px;  
            font-family: '宋体';  
            font-size: 15px;  
            font-weight: bold;  
        }  
        .Fee span {  
            color: red;  
            font-size:14px;  
        }  
          
    </style>  
  </head>  
    
  <body>  
    <div class="Fee">共搜到 <span><%=TotalHits %></span> 条结果. 共花费:<span><%=TotalTime %> </span>秒.</div><br/><br/>  
      
    <table width="80%" height="70%" border="1" cellpadding="0" cellspacing="0" align="center">  
            <tr height="20" bgcolor="#CCCCCC">  
            <td align="center" width="20%">标题</td>  
            <td align="center" width="60%">文章内容</td>  
            <td align="center" width="20%">所属标签</td>  
            </tr>  
            <%  
            if(list.size()>0){  
            for(Article art : list){  
                String title = art.getTitle();  
                String content = art.getContent();  
                String tag = art.getTag();  
            %>  
            <tr>  
                <td><%=title %></td>  
                <td><%=content %></td>  
                <td><%=tag %></td>  
            </tr>  
            <%}}else{ %>  
            <tr>  
                <td colspan="3" align="center"><h3>对不起...没有搜到相关信息..请尝试其他关键字!</h3></td>  
            </tr>  
            <%} %>  
        </table>  
        <br/>  
        <center><a href="<%=basePath %>./">返回上一级</a></center>  
  </body>  
</html> 

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ page import="com.jushi.lucene.entities.*"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<%
 List<Article> list = (List<Article>) request.getAttribute("articlelist");
 String TotalTime = "0.000";
 int TotalHits = 0;
 if(request.getAttribute("totalTime")!=null)
  TotalTime = request.getAttribute("totalTime").toString();
 if(list.size()>0 && list!=null)
  TotalHits = list.get(0).getTotalHits();
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>搜索的结果如下:</title>
    <style type="text/css">
     .Fee {
      width: 650px;
      height:28px;
      float: right;
      padding:1px;
      overflow:hidden;
      border-bottom:1px solid #bde2ff;
      line-height:28px;
      font-family: '宋体';
      font-size: 15px;
      font-weight: bold;
     }
     .Fee span {
      color: red;
      font-size:14px;
     }
     
    </style>
  </head>
 
  <body>
   <div class="Fee">共搜到 <span><%=TotalHits %></span> 条结果. 共花费:<span><%=TotalTime %> </span>秒.</div><br/><br/>
   
    <table width="80%" height="70%" border="1" cellpadding="0" cellspacing="0" align="center">
      <tr height="20" bgcolor="#CCCCCC">
      <td align="center" width="20%">标题</td>
      <td align="center" width="60%">文章内容</td>
      <td align="center" width="20%">所属标签</td>
      </tr>
      <%
      if(list.size()>0){
      for(Article art : list){
       String title = art.getTitle();
       String content = art.getContent();
       String tag = art.getTag();
      %>
      <tr>
       <td><%=title %></td>
       <td><%=content %></td>
       <td><%=tag %></td>
      </tr>
      <%}}else{ %>
      <tr>
       <td colspan="3" align="center"><h3>对不起...没有搜到相关信息..请尝试其他关键字!</h3></td>
      </tr>
      <%} %>
     </table>
     <br/>
     <center><a href="<%=basePath %>./">返回上一级</a></center>
  </body>
</html>
 

    12. action:IndexAction.java

 

Java代码 
package com.jushi.lucene.businessview;  
 
import java.text.DecimalFormat;  
import java.util.Date;  
import java.util.List;  
 
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
 
import org.apache.struts.action.ActionForm;  
import org.apache.struts.action.ActionForward;  
import org.apache.struts.action.ActionMapping;  
import org.apache.struts.actions.DispatchAction;  
import org.springframework.web.context.WebApplicationContext;  
import org.springframework.web.context.support.WebApplicationContextUtils;  
 
import com.jushi.lucene.business.IArticleService;  
import com.jushi.lucene.entities.Article;  
 
/** 
 * @Author fenglong 
 * @CreateDate Jun 4, 2010 1:50:02 PM 
 * @Version V 1.0 
 * @CopyRight 2010 jushi 
 */ 
public class IndexAction extends DispatchAction {  
 
    public ActionForward index(ActionMapping mapping, ActionForm form,  
            HttpServletRequest request, HttpServletResponse response)  
            throws Exception {  
 
        WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServlet().getServletContext());  
        IArticleService articleService = (IArticleService) wac.getBean("articleService");  
 
        String q = request.getParameter("title");  
        DecimalFormat df = new DecimalFormat("#0.000");  
          
        if(articleService.createIndex()){  
              
            long begin = new Date().getTime();  
            List<Article> list = articleService.getArticles(q);  
            long end = new Date().getTime();  
            double time = (double) (end - begin) / 1000;  
            String timeStr = df.format(time);  
              
            request.setAttribute("totalTime", timeStr);  
            request.setAttribute("articlelist", list);  
              
        }  
          
        return mapping.findForward("result");  
    }  
 

package com.jushi.lucene.businessview;

import java.text.DecimalFormat;
import java.util.Date;
import java.util.List;

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

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.jushi.lucene.business.IArticleService;
import com.jushi.lucene.entities.Article;

/**
 * @Author fenglong
 * @CreateDate Jun 4, 2010 1:50:02 PM
 * @Version V 1.0
 * @CopyRight 2010 jushi
 */
public class IndexAction extends DispatchAction {

 public ActionForward index(ActionMapping mapping, ActionForm form,
   HttpServletRequest request, HttpServletResponse response)
   throws Exception {

  WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(this.getServlet().getServletContext());
  IArticleService articleService = (IArticleService) wac.getBean("articleService");

  String q = request.getParameter("title");
  DecimalFormat df = new DecimalFormat("#0.000");
  
  if(articleService.createIndex()){
   
   long begin = new Date().getTime();
   List<Article> list = articleService.getArticles(q);
   long end = new Date().getTime();
   double time = (double) (end - begin) / 1000;
   String timeStr = df.format(time);
   
   request.setAttribute("totalTime", timeStr);
   request.setAttribute("articlelist", list);
   
  }
  
  return mapping.findForward("result");
 }

}
 

 

    好了,所有的配置已经完成了。大概就是个Lucene的简单实现。只是稍微的和Spring结合了一下。功能就是搜索数据,高亮显示关键字。页面不好看,逻辑教简单。

     欢迎拍砖。

分享到:
评论

相关推荐

    智慧酒店项目智能化系统汇报方案qy.pptx

    智慧酒店项目智能化系统汇报方案qy.pptx

    基于C语言编写的高并发Epoll服务器.zip

    基于C语言编写的高并发Epoll服务器.zip

    liba2ps1-4.14-bp156.5.5.ppc64le.rpm

    liba2ps1-4.14-bp156.5.5.ppc64le

    基于matlab实现囚徒困境中的博弈策略的模拟:尝试了采用几种策略进行博弈使最终双赢的概率变大.rar

    基于matlab实现囚徒困境中的博弈策略的模拟:尝试了采用几种策略进行博弈使最终双赢的概率变大.rar

    毕业设计:springboot的乐器社区网站设计与实现(源码 + 数据库 + 说明文档)

    毕业设计:springboot的乐器社区网站设计与实现(源码 + 数据库 + 说明文档) 2相关技术介绍 3 2.1 MySQL数据库简介 3 2.2 springboot编程技术 3 2.3 VUE框架 3 2.4 B/S结构 4 3系统可行性分析 5 3.1概况 5 3.2可行性研究的前提 5 3.3可行性分析 6 3.3.1技术的可行性 6 3.3.2经济的可行性 6 3.3.3操作可行性 6 3.3.4法律的可行性 7 3.4设计的基本思想 7 3.5性能需求 7 3.5.1系统的安全性 7 3.5.2数据的完整性 7 4 系统设计 9 4.1总体设计 9 4.2数据库的分析与设计 9 4.3数据库表 10 第五章 系统功能实现 12 5.1 乐器社区网站首页界面 12 5.2 乐器信息列表界面 12 5.3管理员管理界面 13 5.4新建乐器信息界面 14 5.5二手商品购买界面 14 6 系统测试 15 6.1测试说明 15 6.2功能测试 15 6.3可用性测试 15 6.5性能测试 16 6.6用例测试 16 6.7测试结果 16

    2024-2030全球及中国鼓机踏板行业研究及十五五规划分析报告.docx

    2024-2030全球及中国鼓机踏板行业研究及十五五规划分析报告

    毕业设计:基于springboot的中小企业财务管理系统(源码 + 数据库 + 说明文档)

    毕业设计:基于springboot的中小企业财务管理系统(源码 + 数据库 + 说明文档) 2 开发技术简介 6 2.1 基于B/S结构开发 6 2.2 jsp语言简介 6 2.3MYSQL简介 6 2.4 eclipse工具 7 3 需求分析 7 3.1 可行性分析 7 3.1.1 经济可行性 7 3.1.2 技术可行性 7 3.1.3 操作可行性 7 3.2 功能需求分析 8 3.3 非功能需求分析 8 4 系统设计 9 4.1 数据库设计 9 4.2 系统模块总体设计 10 5 系统详细设计 10 5.1 后台登录页面 10 5.2 管理员信息 11 5.3 财务人员信息 11 5.4 资产负债 12 5.5 税收管理 12 6 系统测试 13 6.1 测试的目的 13 6.2 测试的方法 13 6.3 测试的重要性 14 6.4 测试内容 14 6.5 测试结果 14

    基于Springboot集成yolo3构建基于神经网络的图片识别系统源码.zip

    基于Springboot集成yolo3构建基于神经网络的图片识别系统源码.zip基于Springboot集成yolo3构建基于神经网络的图片识别系统源码.zip基于Springboot集成yolo3构建基于神经网络的图片识别系统源码.zip基于Springboot集成yolo3构建基于神经网络的图片识别系统源码.zip基于Springboot集成yolo3构建基于神经网络的图片识别系统源码.zip基于Springboot集成yolo3构建基于神经网络的图片识别系统源码.zip基于Springboot集成yolo3构建基于神经网络的图片识别系统源码.zip基于Springboot集成yolo3构建基于神经网络的图片识别系统源码.zip基于Springboot集成yolo3构建基于神经网络的图片识别系统源码.zip基于Springboot集成yolo3构建基于神经网络的图片识别系统源码.zip基于Springboot集成yolo3构建基于神经网络的图片识别系统源码.zip基于Springboot集成yolo3构建基于神经网络的图片识别系统源码.zip基于Springboot集成yolo3构

    基于C#的开源音乐播放器MetroPlayer.zip

    基于C#的开源音乐播放器MetroPlayer.zip

    MD5哈希算法的C++实现(兼容大端字节序的CPU)

    MD5哈希算法的C++实现(兼容大端字节序的CPU) 测试代码 #include<iostream> #include<iomanip> #include"md5.c" int main() { using namespace std; u8 $finalHash[16] = {}; const char* str = "a"; //调用MD5 int ret = MD5((u8*)str, strnlen_s(str, INT_MAX), $finalHash); cout << ret << "\n\n"; //输出结果 for (int i = 0; i < 16; i++) { cout << hex << setw(2) << setfill('0') << int($finalHash[i]); } cout << "\n\n"; return 0; }

    2024新版Java基础从入门到精通全套视频+资料下载

    2024新版Java基础从入门到精通全套视频+资料下载

    51单片机输出PWM波,可调频率、占空比

    项目基于Proteus仿真,使用at89c52作为主控芯片,输出PWM波,通过按键设置PWM波的频率和占空比,并且将频率和占空比显示在数码管上。

    2024年全球油性皮肤保湿霜行业总体规模、主要企业国内外市场占有率及排名.docx

    2024年全球油性皮肤保湿霜行业总体规模、主要企业国内外市场占有率及排名

    Windows系统下安装与配置Neo4j的步骤

    附件是Windows系统下安装与配置Neo4j的步骤,包含具体的操作步骤, 文件绿色安全,仅供学习交流使用,欢迎大家下载学习交流!

    Bash脚本优化JAR应用启动与停止流程.zip

    本Bash脚本用于自动化管理Java JAR应用的启动、停止及监控。首先检查JAR进程是否在运行,如在运行则安全终止。随后,使用预设的Java参数启动JAR文件,并将输出和错误日志重定向至日志文件。启动后,脚本持续监控JAR进程状态,确保其在预设时间内成功启动。本脚本提供了灵活的配置和错误处理机制,为Java应用的运维管理带来了便捷与可靠性。

    基于python+django+mysql大数据反电信诈骗管理系统(源码+论文+演示视频)

    【基于Python+Django的毕业设计】基于大数据反电信诈骗管理系统(源码+录像演示+说明).zip 【项目技术】 python+Django+mysql 【实现功能】 主要的功能有文本分析、文本管理、修改密码、个人信息和用户管理。 详见:https://blog.csdn.net/Timi2019/article/details/138357613

    libAvogadro1-1.98.1-bp156.1.1.ppc64le.rpm

    libAvogadro1-1.98.1-bp156.1.1.ppc64le

    261ssm-mysql-jsp 高校学生请假管理系统.zip(可运行源码+数据库文件+文档)

    本系统从使用者角度看,分为学生群体、教师群体。学生及教师都在本系统中录入自己的基本信息。当学生需要请假的时候,可以直接在本系统上填写请假事由、请假时间及返校时间,提交申请即可,然后关注老师的审批进度;当老师在系统上查询到请假信息记录时,审批确认是否同意批复学生的请假意向;当老师审批完成之后,学生就可以看到老师对请假单的审批结果。 高校学生请假管理系统可以让老师和学生在任何时间、任何地点都可以完成请假的整个流程工作。系统会有请假历史记录,学校可以按照月、季度、年度对学生的请假情况进行分析。因此,本系统大大提高了学生请假的效率,同时也有助于学校分析学生请假的情况。 关键字:请假;审批;学生;ssm框架;jsp技术;MySQL数据库;

    智慧物流园区整体解决方案--物流园区、物流枢纽、多式联运qy.pptx

    智慧物流园区整体解决方案--物流园区、物流枢纽、多式联运qy.pptx

    JDK1.6.0-37.rar 解压包

    JDK1.6.0_37.rar 解压包,window64位解压然后配置JDK环境变量使用

Global site tag (gtag.js) - Google Analytics