SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎

任务是实现Struts2 SSH分页浏览新闻、Lucene分页高亮排序搜索新闻这个两个功能。

com.zly.indexManager中两个类,分别创建索引和搜索索引,

com.zly.test.entity中是使用的实体类,分别是NewsType(新闻类型),NewsItem(新闻具体条目),PageControl(分页实体bean) , SearchResultBean(保存搜索结果的bean).

  1. package com.zly.test.entity;
  1. import java.io.Serializable;
  1. import javax.persistence.Column;
  2. import javax.persistence.Entity;
  3. import javax.persistence.GeneratedValue;
  4. import javax.persistence.GenerationType;
  5. import javax.persistence.Id;
  6. import javax.persistence.Table;
  7. @Entity
  8. @Table(name = "t_newsType")
  9. public class NewsType implements Serializable {
  10. private static final long serialVersionUID = -5092622762025999122L;
  11. private Integer id;
  12. private String newsTypeName;
  13. @Column
  14. public String getNewsTypeName() {
  15. return newsTypeName;
  16. }
  17. public void setNewsTypeName(String newsTypeName) {
  18. this.newsTypeName = newsTypeName;
  19. }
  20. @Id
  21. @GeneratedValue(strategy = GenerationType.AUTO)
  22. public Integer getId() {
  23. return id;
  24. }
  25. public void setId(Integer id) {
  26. this.id = id;
  27. }
  28. }
package com.zly.test.entity;import java.io.Serializable;import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "t_newsType")
public class NewsType implements Serializable {private static final long serialVersionUID = -5092622762025999122L;private Integer id;private String newsTypeName;@Columnpublic String getNewsTypeName() {return newsTypeName;}public void setNewsTypeName(String newsTypeName) {this.newsTypeName = newsTypeName;}@Id@GeneratedValue(strategy = GenerationType.AUTO)public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}}

//NewsItem(新闻具体条目)

Java代码  
  1. package com.zly.test.entity;
  2. import java.io.Serializable;
  3. import java.util.Date;
  4. import javax.persistence.Column;
  5. import javax.persistence.Entity;
  6. import javax.persistence.GeneratedValue;
  7. import javax.persistence.GenerationType;
  8. import javax.persistence.Id;
  9. import javax.persistence.JoinColumn;
  10. import javax.persistence.ManyToOne;
  11. import javax.persistence.Table;
  12. import javax.persistence.Temporal;
  13. import javax.persistence.TemporalType;
  14. @Entity
  15. @Table(name = "t_newsItem")
  16. public class NewsItem implements Serializable {
  17. private static final long serialVersionUID = -7532888546907495633L;
  18. private Integer id ;
  19. private String newsTitle ;
  20. private String newsContent;
  21. private Date publishTime;
  22. private String resource;
  23. private NewsType type;
  24. private String editor;
  25. @Column
  26. public String getEditor() {
  27. return editor;
  28. }
  29. public void setEditor(String editor) {
  30. this.editor = editor;
  31. }
  32. @ManyToOne
  33. @JoinColumn(name = "t_newsType_id")
  34. public NewsType getType() {
  35. return type;
  36. }
  37. public void setType(NewsType type) {
  38. this.type = type;
  39. }
  40. @Id
  41. @GeneratedValue(strategy = GenerationType.AUTO)
  42. public Integer getId() {
  43. return id;
  44. }
  45. public void setId(Integer id) {
  46. this.id = id;
  47. }
  48. @Column
  49. public String getNewsTitle() {
  50. return newsTitle;
  51. }
  52. public void setNewsTitle(String newsTitle) {
  53. this.newsTitle = newsTitle;
  54. }
  55. @Temporal(value = TemporalType.TIMESTAMP)
  56. public Date getPublishTime() {
  57. return publishTime;
  58. }
  59. public void setPublishTime(Date publishTime) {
  60. this.publishTime = publishTime;
  61. }
  62. public String getResource() {
  63. return resource;
  64. }
  65. public void setResource(String resource) {
  66. this.resource = resource;
  67. }
  68. public String getNewsContent() {
  69. return newsContent;
  70. }
  71. public void setNewsContent(String newsContent) {
  72. this.newsContent = newsContent;
  73. }
  74. }
package com.zly.test.entity;import java.io.Serializable;
import java.util.Date;import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@Table(name = "t_newsItem")
public class NewsItem implements Serializable {private static final long serialVersionUID = -7532888546907495633L;private Integer id ; private String newsTitle ;private String newsContent;private Date publishTime;private String resource;private NewsType type;private String editor;@Columnpublic String getEditor() {return editor;}public void setEditor(String editor) {this.editor = editor;}@ManyToOne@JoinColumn(name = "t_newsType_id")public NewsType getType() {return type;}public void setType(NewsType type) {this.type = type;}@Id@GeneratedValue(strategy = GenerationType.AUTO)public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}@Columnpublic String getNewsTitle() {return newsTitle;}public void setNewsTitle(String newsTitle) {this.newsTitle = newsTitle;}@Temporal(value = TemporalType.TIMESTAMP)public Date getPublishTime() {return publishTime;}public void setPublishTime(Date publishTime) {this.publishTime = publishTime;}public String getResource() {return resource;}public void setResource(String resource) {this.resource = resource;}public String getNewsContent() {return newsContent;}public void setNewsContent(String newsContent) {this.newsContent = newsContent;}}

添加所有新闻类型的类放在了com.zly.test.newsFetch包下 , 具体代码:

Java代码  
  1. package com.zly.test.newsfetch;
  2. import java.text.DateFormat;
  3. import java.text.SimpleDateFormat;
  4. import java.util.Date;
  5. import java.util.LinkedHashSet;
  6. import java.util.Set;
  7. import java.util.regex.Matcher;
  8. import java.util.regex.Pattern;
  9. import org.hibernate.Session;
  10. import org.hibernate.SessionFactory;
  11. import org.hibernate.cfg.AnnotationConfiguration;
  12. import org.hibernate.cfg.Configuration;
  13. import org.htmlparser.Parser;
  14. import org.htmlparser.Tag;
  15. import org.htmlparser.filters.NodeClassFilter;
  16. import org.htmlparser.tags.Div;
  17. import org.htmlparser.tags.LinkTag;
  18. import org.htmlparser.util.NodeList;
  19. import org.htmlparser.visitors.NodeVisitor;
  20. import com.zly.test.entity.NewsItem;
  21. import com.zly.test.entity.NewsType;
  22. public class GetNews {
  23. public static void main(String[] args) throws Exception {
  24. //插入数据新闻类型
  25. //insertAllTypes();
  26. //插入所有新闻数据
  27. //国内新闻
  28. //insertNewsItems("http://www.chinanews.com.cn/scroll-news/gn/2009/05" ,"/news.shtml" ,1);
  29. //国际新闻
  30. //insertNewsItems("http://www.chinanews.com.cn/scroll-news/gj/2009/05" ,"/news.shtml" ,2);
  31. //社会新闻
  32. //insertNewsItems("http://www.chinanews.com.cn/scroll-news/sh/2009/05" ,"/news.shtml" ,3);
  33. //港澳新闻
  34. //insertNewsItems("http://www.chinanews.com.cn/scroll-news/ga/2009/05" ,"/news.shtml" ,4);
  35. //台湾新闻
  36. //insertNewsItems("http://www.chinanews.com.cn/scroll-news/tw/2009/05" ,"/news.shtml" ,5);
  37. //华人新闻
  38. //insertNewsItems("http://www.chinanews.com.cn/scroll-news/hr/2009/05" ,"/news.shtml" ,6);
  39. //经济新闻
  40. //insertNewsItems("http://www.chinanews.com.cn/scroll-news/cj/2009/05" ,"/news.shtml" ,7);
  41. //文化新闻
  42. //insertNewsItems("http://www.chinanews.com.cn/scroll-news/wh/2009/05" ,"/news.shtml" ,8);
  43. //娱乐新闻
  44. //insertNewsItems("http://www.chinanews.com.cn/scroll-news/yl/2009/05" ,"/news.shtml" ,9);
  45. //体育新闻
  46. //insertNewsItems("http://www.chinanews.com.cn/scroll-news/ty/2009/05" ,"/news.shtml" ,10);
  47. //教育新闻
  48. //insertNewsItems("http://www.chinanews.com.cn/scroll-news/edu/2009/05" ,"/news.shtml" ,11);
  49. //健康新闻
  50. //insertNewsItems("http://www.chinanews.com.cn/scroll-news/jk/2009/05" ,"/news.shtml" ,12);
  51. //生活新闻
  52. //insertNewsItems("http://www.chinanews.com.cn/scroll-news/life/2009/05" ,"/news.shtml" ,13);
  53. //IT新闻
  54. //insertNewsItems("http://www.chinanews.com.cn/scroll-news/it/2009/05" ,"/news.shtml" ,14);
  55. }
  56. public static void insertAllTypes() {
  57. Configuration cfg = new AnnotationConfiguration().configure();
  58. SessionFactory factory = cfg.buildSessionFactory();
  59. Session session = factory.openSession();
  60. String str = new String("国内 国际 社会 港澳 台湾 华人 经济 文化 娱乐 体育 教育 健康 生活 IT");
  61. String[] typesStr = str.split(" ");
  62. NewsType[] types = new NewsType[typesStr.length];
  63. session.beginTransaction();
  64. for (int i = 0; i < typesStr.length; i++) {
  65. types[i] = new NewsType();
  66. types[i].setNewsTypeName(typesStr[i]);
  67. session.save(types[i]);
  68. }
  69. session.getTransaction().commit();
  70. session.close();
  71. }
  72. //处理5.1 - 5.5 所有的具体类型的新闻
  73. public static void insertNewsItems(String before , String after , int type) throws Exception {
  74. Configuration cfg = new AnnotationConfiguration().configure();
  75. SessionFactory factory = cfg.buildSessionFactory();
  76. Session session = factory.openSession();
  77. //得到当前新闻所属类别
  78. NewsType newsType = (NewsType) session.get(NewsType.class, type);
  79. final Set<NewsItem> set = new LinkedHashSet<NewsItem>();
  80. //获取5月1日-5月5日的新闻
  81. for (int i = 1; i <= 5; i++) {
  82. String src = before;
  83. if(i < 10) {
  84. src = src + "0" + i;
  85. }else {
  86. src = src + i ;
  87. }
  88. src = src + after;
  89. //使用htmlParser获取每一条新闻的超链接
  90. Parser parser = new Parser(src);
  91. parser.setEncoding("gb2312");
  92. NodeList divList = parser.parse(new NodeClassFilter(Div.class));
  93. for (int j = 0; j < divList.size(); j++) {
  94. Div div = (Div) divList.elementAt(j);
  95. String divClass = div.getAttribute("id");
  96. //取得id为news_list的div
  97. if(divClass != null && divClass.equals("news_list")) {
  98. div.accept(new NodeVisitor() {
  99. //遍历news_list里面的所有超链接
  100. public void visitTag(Tag tag) {
  101. if(tag instanceof LinkTag) {
  102. String href = ((LinkTag)tag).getLink();
  103. if(!href.startsWith("http")) {
  104. href = "http://www.chinanews.com.cn" + href;
  105. }
  106. System.out.println(href);
  107. //找到超链接,将这个超链接所在的页面进行处理,抓取新闻数据,并将其保存在Set中。
  108. try{
  109. insertOneNews(href , set);
  110. }catch(Exception e) {
  111. e.printStackTrace();
  112. }
  113. }
  114. }
  115. });
  116. }
  117. }
  118. }
  119. //获取新闻完成后,将所有NewsItem添加到数据库
  120. session.beginTransaction();
  121. for (NewsItem newsItem : set) {
  122. newsItem.setType(newsType);
  123. session.save(newsItem);
  124. }
  125. session.getTransaction().commit();
  126. session.close();
  127. }
  128. //处理每一个具体的新闻超链接,得到NewsItem类
  129. public static void insertOneNews(String src , Set<NewsItem> set) throws Exception {
  130. Parser parser = new Parser(src);
  131. parser.setEncoding("gb2312");
  132. NodeList divList = parser.extractAllNodesThatMatch(new NodeClassFilter(Div.class));
  133. NewsItem newsItem = new NewsItem();
  134. String title = "";
  135. Date parse = null;
  136. String content = "";
  137. String editor = "";
  138. //遍历网页的div。将制定div里面的信息设置到NewsItem实体类中
  139. for (int i = 0; i < divList.size(); i++) {
  140. Div div = (Div) divList.elementAt(i);
  141. String divString = div.getAttribute("class");
  142. if(divString != null) {
  143. //设置标题
  144. if(divString.equals("left_bt")) {
  145. title = div.toPlainTextString();
  146. }
  147. //设置发布时间
  148. if(divString.equals("left_time")) {
  149. String publishStr = "";
  150. Pattern pattern = Pattern.compile("[\\d]{4}年[\\d]{2}月[\\d]{2}日 [\\d]{2}:[\\d]{2}");
  151. Matcher matcher = pattern.matcher(div.toPlainTextString()) ;
  152. if(matcher.find()) {
  153. publishStr = matcher.group();
  154. }
  155. DateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH:mm");
  156. parse = format.parse(publishStr);
  157. }
  158. //设置正文内容
  159. if(divString.equals("left_zw")) {
  160. content = div.toHtml();
  161. }
  162. //设置记者名称
  163. if(divString.equals("left_name")) {
  164. editor = div.toPlainTextString().trim();
  165. editor = editor.substring(editor.indexOf(":") + 1, editor.lastIndexOf("】"));
  166. }
  167. }
  168. }
  169. newsItem.setEditor(editor);
  170. newsItem.setNewsContent(content);
  171. newsItem.setNewsTitle(title);
  172. newsItem.setPublishTime(parse);
  173. //设置新闻来源
  174. newsItem.setResource("最快新闻网");
  175. //将新闻添加到set中
  176. set.add(newsItem);
  177. }
  178. }
package com.zly.test.newsfetch;import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.htmlparser.Parser;
import org.htmlparser.Tag;
import org.htmlparser.filters.NodeClassFilter;
import org.htmlparser.tags.Div;
import org.htmlparser.tags.LinkTag;
import org.htmlparser.util.NodeList;
import org.htmlparser.visitors.NodeVisitor;import com.zly.test.entity.NewsItem;
import com.zly.test.entity.NewsType;public class GetNews {public static void main(String[] args) throws Exception {//插入数据新闻类型//insertAllTypes();//插入所有新闻数据//国内新闻//insertNewsItems("http://www.chinanews.com.cn/scroll-news/gn/2009/05" ,"/news.shtml" ,1);//国际新闻//insertNewsItems("http://www.chinanews.com.cn/scroll-news/gj/2009/05" ,"/news.shtml" ,2);//社会新闻//insertNewsItems("http://www.chinanews.com.cn/scroll-news/sh/2009/05" ,"/news.shtml" ,3);//港澳新闻//insertNewsItems("http://www.chinanews.com.cn/scroll-news/ga/2009/05" ,"/news.shtml" ,4);      //台湾新闻//insertNewsItems("http://www.chinanews.com.cn/scroll-news/tw/2009/05" ,"/news.shtml" ,5);        //华人新闻//insertNewsItems("http://www.chinanews.com.cn/scroll-news/hr/2009/05" ,"/news.shtml" ,6);        //经济新闻//insertNewsItems("http://www.chinanews.com.cn/scroll-news/cj/2009/05" ,"/news.shtml" ,7);        //文化新闻//insertNewsItems("http://www.chinanews.com.cn/scroll-news/wh/2009/05" ,"/news.shtml" ,8);        //娱乐新闻//insertNewsItems("http://www.chinanews.com.cn/scroll-news/yl/2009/05" ,"/news.shtml" ,9);        //体育新闻//insertNewsItems("http://www.chinanews.com.cn/scroll-news/ty/2009/05" ,"/news.shtml" ,10);       //教育新闻//insertNewsItems("http://www.chinanews.com.cn/scroll-news/edu/2009/05" ,"/news.shtml" ,11);      //健康新闻//insertNewsItems("http://www.chinanews.com.cn/scroll-news/jk/2009/05" ,"/news.shtml" ,12);       //生活新闻//insertNewsItems("http://www.chinanews.com.cn/scroll-news/life/2009/05" ,"/news.shtml" ,13);     //IT新闻//insertNewsItems("http://www.chinanews.com.cn/scroll-news/it/2009/05" ,"/news.shtml" ,14);       }public static void insertAllTypes() {Configuration cfg = new AnnotationConfiguration().configure();SessionFactory factory = cfg.buildSessionFactory();Session session = factory.openSession();String str = new String("国内 国际 社会 港澳 台湾 华人 经济 文化 娱乐 体育 教育 健康 生活 IT");String[] typesStr = str.split(" ");NewsType[] types = new NewsType[typesStr.length];session.beginTransaction();for (int i = 0; i < typesStr.length; i++) {types[i] = new NewsType();types[i].setNewsTypeName(typesStr[i]);session.save(types[i]);}session.getTransaction().commit();session.close();}//处理5.1 - 5.5 所有的具体类型的新闻public static void insertNewsItems(String before , String after , int type) throws Exception {Configuration cfg = new AnnotationConfiguration().configure();SessionFactory factory = cfg.buildSessionFactory();Session session = factory.openSession();//得到当前新闻所属类别NewsType newsType = (NewsType) session.get(NewsType.class, type);final Set<NewsItem> set = new LinkedHashSet<NewsItem>();//获取5月1日-5月5日的新闻for (int i = 1; i <= 5; i++) {String src = before;if(i < 10) {src = src + "0" + i;}else {src = src + i ; }src = src + after;//使用htmlParser获取每一条新闻的超链接Parser parser = new Parser(src);parser.setEncoding("gb2312");NodeList divList = parser.parse(new NodeClassFilter(Div.class));for (int j = 0; j < divList.size(); j++) {Div div = (Div) divList.elementAt(j);String divClass = div.getAttribute("id");//取得id为news_list的divif(divClass != null && divClass.equals("news_list")) {div.accept(new NodeVisitor() {//遍历news_list里面的所有超链接public void visitTag(Tag tag) {if(tag instanceof LinkTag) {String href = ((LinkTag)tag).getLink();if(!href.startsWith("http")) {href = "http://www.chinanews.com.cn" + href;}System.out.println(href);//找到超链接,将这个超链接所在的页面进行处理,抓取新闻数据,并将其保存在Set中。try{insertOneNews(href , set);}catch(Exception e) {e.printStackTrace();}}}});}}}//获取新闻完成后,将所有NewsItem添加到数据库session.beginTransaction();for (NewsItem newsItem : set) {newsItem.setType(newsType);session.save(newsItem);}session.getTransaction().commit();session.close();}//处理每一个具体的新闻超链接,得到NewsItem类public static void insertOneNews(String src , Set<NewsItem> set) throws Exception {Parser parser = new Parser(src);parser.setEncoding("gb2312");NodeList divList = parser.extractAllNodesThatMatch(new NodeClassFilter(Div.class));NewsItem newsItem = new NewsItem();String title = "";Date parse = null;String content = "";String editor = "";//遍历网页的div。将制定div里面的信息设置到NewsItem实体类中for (int i = 0; i < divList.size(); i++) {Div div = (Div) divList.elementAt(i);String divString = div.getAttribute("class");if(divString != null) {//设置标题if(divString.equals("left_bt")) {title = div.toPlainTextString();}//设置发布时间if(divString.equals("left_time")) {String publishStr = "";Pattern pattern = Pattern.compile("[\\d]{4}年[\\d]{2}月[\\d]{2}日 [\\d]{2}:[\\d]{2}");Matcher matcher = pattern.matcher(div.toPlainTextString()) ;if(matcher.find()) {publishStr = matcher.group();}DateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH:mm");parse = format.parse(publishStr);}//设置正文内容if(divString.equals("left_zw")) {content = div.toHtml();}//设置记者名称if(divString.equals("left_name")) {editor = div.toPlainTextString().trim();editor = editor.substring(editor.indexOf(":") + 1, editor.lastIndexOf("】"));}}}newsItem.setEditor(editor);newsItem.setNewsContent(content);newsItem.setNewsTitle(title);newsItem.setPublishTime(parse);//设置新闻来源newsItem.setResource("最快新闻网");//将新闻添加到set中set.add(newsItem);}
}

通过上面的代码完成了所有的数据添加工作。

下面根据ssh的流程分别定制dao , manager , action

com.zly.test.dao包中是所有操作dao的抽象类和接口

我们直接看这些接口的实现

//NewsItemDaoHibernate  新闻实体类dao

Java代码  
  1. @SuppressWarnings("unchecked")
  2. //根据分页得到具体页的内容
  3. public List<com.zly.test.entity.NewsItem> getNewsItemByFirstResultAndMaxResult(
  4. final int firstResult, final int maxResult , final int type) {
  5. return (List<NewsItem>) this.getHibernateTemplate().execute(new HibernateCallback() {
  6. public Object doInHibernate(Session session)
  7. throws HibernateException, SQLException {
  8. return session.createQuery(" from NewsItem where type.id = '" + type + "'").setFirstResult(firstResult).setMaxResults(maxResult).list();
  9. }
  10. });
  11. }
  12. //得到数据总条数 , 以便计算总页数
  13. public Long getItemCount(final int id) {
  14. return (Long) this.getHibernateTemplate().execute(new HibernateCallback(){
  15. public Object doInHibernate(Session session)
  16. throws HibernateException, SQLException {
  17. return session.createQuery("select count(*) from NewsItem where type.id = '" + id + "'").uniqueResult();
  18. }
  19. });
  20. }
  21. //显示新闻数据页面用到, 查询具体新闻属于哪个新闻类别
  22. public int getNewsType(final int id) {
  23. return (Integer) this.getHibernateTemplate().execute(new HibernateCallback() {
  24. public Object doInHibernate(Session session)
  25. throws HibernateException, SQLException {
  26. NewsItem newsItem = get(id);
  27. NewsType type = newsItem.getType();
  28. return type.getId();
  29. }
  30. });
  31. }
@SuppressWarnings("unchecked")//根据分页得到具体页的内容public List<com.zly.test.entity.NewsItem> getNewsItemByFirstResultAndMaxResult(final int firstResult, final int maxResult , final int type) {return (List<NewsItem>) this.getHibernateTemplate().execute(new HibernateCallback() {public Object doInHibernate(Session session)throws HibernateException, SQLException {return session.createQuery(" from NewsItem where type.id = '" + type + "'").setFirstResult(firstResult).setMaxResults(maxResult).list();}});}//得到数据总条数 , 以便计算总页数public Long getItemCount(final int id) {return (Long) this.getHibernateTemplate().execute(new HibernateCallback(){public Object doInHibernate(Session session)throws HibernateException, SQLException {return session.createQuery("select count(*) from NewsItem where type.id = '" + id + "'").uniqueResult();}});}//显示新闻数据页面用到, 查询具体新闻属于哪个新闻类别public int getNewsType(final int id) {return (Integer) this.getHibernateTemplate().execute(new HibernateCallback() {public Object doInHibernate(Session session)throws HibernateException, SQLException {NewsItem newsItem = get(id);NewsType type = newsItem.getType();return type.getId();}});}

只用到了一个   NewsManagerImpl

Java代码  
  1. package com.zly.test.service.impl;
  2. import java.util.List;
  3. import com.zly.test.dao.NewsItemDao;
  4. import com.zly.test.entity.NewsItem;
  5. import com.zly.test.service.NewsManager;
  6. public class NewsManagerImpl implements NewsManager {
  7. //新闻条目dao
  8. private NewsItemDao newsItemDao;
  9. public NewsItemDao getNewsItemDao() {
  10. return newsItemDao;
  11. }
  12. public void setNewsItemDao(NewsItemDao newsItemDao) {
  13. this.newsItemDao = newsItemDao;
  14. }
  15. //根据分页得到内容
  16. public List<NewsItem> getNewsItemByFirstResultAndMaxResult(int firstResult,
  17. int maxResult , int type) {
  18. return newsItemDao.getNewsItemByFirstResultAndMaxResult(firstResult, maxResult ,  type);
  19. }
  20. //得到总记录数,以便计算总页数
  21. public Long getItemCounts(int id) {
  22. return newsItemDao.getItemCount(id);
  23. }
  24. //通过id得到具体新闻
  25. public NewsItem getNewsById(int id) {
  26. return newsItemDao.get(id);
  27. }
  28. //通过id得到所属新闻类别的id
  29. public int getNewsType(int id) {
  30. return newsItemDao.getNewsType(id);
  31. }
  32. }
package com.zly.test.service.impl;import java.util.List;import com.zly.test.dao.NewsItemDao;
import com.zly.test.entity.NewsItem;
import com.zly.test.service.NewsManager;public class NewsManagerImpl implements NewsManager {//新闻条目daoprivate NewsItemDao newsItemDao;public NewsItemDao getNewsItemDao() {return newsItemDao;}public void setNewsItemDao(NewsItemDao newsItemDao) {this.newsItemDao = newsItemDao;}//根据分页得到内容public List<NewsItem> getNewsItemByFirstResultAndMaxResult(int firstResult,int maxResult , int type) {return newsItemDao.getNewsItemByFirstResultAndMaxResult(firstResult, maxResult ,  type);}//得到总记录数,以便计算总页数public Long getItemCounts(int id) {return newsItemDao.getItemCount(id);}//通过id得到具体新闻public NewsItem getNewsById(int id) {return newsItemDao.get(id);}//通过id得到所属新闻类别的idpublic int getNewsType(int id) {return newsItemDao.getNewsType(id); }}

在applicationContext-action.xml中配置action类别

Java代码  
  1. <bean class="com.zly.test.action.NewsAction" id="newsAction" scope="request">
  2. <property name="newsManager" ref="newsManager"></property>
  3. <property name="map" ref="map"></property>
  4. <property name="map1" ref="map1"></property>
  5. </bean>
     <bean class="com.zly.test.action.NewsAction" id="newsAction" scope="request"><property name="newsManager" ref="newsManager"></property><property name="map" ref="map"></property><property name="map1" ref="map1"></property></bean>

其中定一个两个map , 因为主页的查看分类新闻的url是采用的这种形式<a href="newsAction.action?category=china" target="_blank">国内</a>   名字为map的Map中保存信息如下

Java代码  
  1. <bean id="map" class="java.util.HashMap">
  2. <constructor-arg>
  3. <map>
  4. <entry key="china" value="1###国内新闻" />
  5. <entry key="world" value="2###国际新闻" />
  6. <entry key="society" value="3###社会新闻" />
  7. <entry key="compatriot" value="4###港台新闻" />
  8. <entry key="taiwan" value="5###台湾新闻" />
  9. <entry key="huaren" value="6###华人新闻" />
  10. <entry key="economic" value="7###经济新闻" />
  11. <entry key="wenhua" value="8###文化新闻" />
  12. <entry key="entertainment" value="9###娱乐新闻" />
  13. <entry key="sports" value="10###体育新闻" />
  14. <entry key="jiaoyu" value="11###教育新闻" />
  15. <entry key="jiankang" value="12###健康新闻" />
  16. <entry key="life" value="13###生活新闻" />
  17. <entry key="keji" value="14###科技新闻" />
  18. </map>
  19. </constructor-arg>
  20. </bean>
 <bean id="map" class="java.util.HashMap"><constructor-arg><map><entry key="china" value="1###国内新闻" /><entry key="world" value="2###国际新闻" /><entry key="society" value="3###社会新闻" /><entry key="compatriot" value="4###港台新闻" /><entry key="taiwan" value="5###台湾新闻" /><entry key="huaren" value="6###华人新闻" /><entry key="economic" value="7###经济新闻" /><entry key="wenhua" value="8###文化新闻" /><entry key="entertainment" value="9###娱乐新闻" /><entry key="sports" value="10###体育新闻" /><entry key="jiaoyu" value="11###教育新闻" /><entry key="jiankang" value="12###健康新闻" /><entry key="life" value="13###生活新闻" /><entry key="keji" value="14###科技新闻" /></map></constructor-arg></bean>

key是?category后面的值 , value是两部分 , 被###分割开 , 前面的数值是所属新闻类别的id值, 后面的文字是其类别的文字。将其保存在map中,避免不停地查询数据库。

分页类PageControl的代码如下:

Java代码  
  1. package com.zly.test.entity;
  2. import java.util.List;
  3. public class PageControl {
  4. private int curPage ; //当前是第几页
  5. private int maxPage ; //一共有多少页
  6. private Long maxRowCount ; //一共有多少行
  7. private int rowsPerPage = 8 ; //每页有多少行
  8. private List<?> data;//每页的User
  9. public int getCurPage() {
  10. return curPage;
  11. }
  12. public void setCurPage(int curPage) {
  13. this.curPage = curPage;
  14. }
  15. public int getMaxPage() {
  16. return maxPage;
  17. }
  18. public void setMaxPage(int maxPage) {
  19. this.maxPage = maxPage;
  20. }
  21. public List<?> getUserList() {
  22. return data;
  23. }
  24. public void setUserList(List<?> data) {
  25. this.data = data;
  26. }
  27. public Long getMaxRowCount() {
  28. return maxRowCount;
  29. }
  30. public void setMaxRowCount(Long amaxRowCountxRowCount) {
  31. this.maxRowCount = amaxRowCountxRowCount;
  32. }
  33. public int getRowsPerPage() {
  34. return rowsPerPage;
  35. }
  36. public void setRowsPerPage(int rowsPerPage) {
  37. this.rowsPerPage = rowsPerPage;
  38. }
  39. public void countMaxPage() {   //根据总行数计算总页数
  40. if (this.maxRowCount % this.rowsPerPage ==0){
  41. this.maxPage = (int) (this.maxRowCount/this.rowsPerPage);
  42. }else{
  43. this.maxPage = (int) (this.maxRowCount/this.rowsPerPage + 1);
  44. }
  45. }
  46. }
package com.zly.test.entity;import java.util.List;public class PageControl {private int curPage ; //当前是第几页 private int maxPage ; //一共有多少页 private Long maxRowCount ; //一共有多少行 private int rowsPerPage = 8 ; //每页有多少行 private List<?> data;//每页的Userpublic int getCurPage() {return curPage;}public void setCurPage(int curPage) {this.curPage = curPage;}public int getMaxPage() {return maxPage;}public void setMaxPage(int maxPage) {this.maxPage = maxPage;}public List<?> getUserList() {return data;}public void setUserList(List<?> data) {this.data = data;}public Long getMaxRowCount() {return maxRowCount;}public void setMaxRowCount(Long amaxRowCountxRowCount) {this.maxRowCount = amaxRowCountxRowCount;}public int getRowsPerPage() {return rowsPerPage;}public void setRowsPerPage(int rowsPerPage) {this.rowsPerPage = rowsPerPage;}public void countMaxPage() {   //根据总行数计算总页数  if (this.maxRowCount % this.rowsPerPage ==0){this.maxPage = (int) (this.maxRowCount/this.rowsPerPage);}else{this.maxPage = (int) (this.maxRowCount/this.rowsPerPage + 1);        }}}

被许多页所包含的page.jsp代码如下:

Java代码  
  1. <%@ page language="java"  contentType="text/html;charset=utf-8"
  2. pageEncoding="utf-8"%>
  3. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  4. <html>
  5. <head>
  6. <script language="javascript">
  7. function jumping() {
  8. document.pageForm.submit();
  9. return true;
  10. }
  11. function gotoPage(pageNum) {
  12. document.pageForm.jumpPage.value = pageNum ;
  13. document.pageForm.submit();
  14. return true;
  15. }
  16. </script>
  17. </head>
  18. <body>
  19. <c:if test="${pageControl.maxPage != 1}">
  20. <form method="post" action="pageAction.action" name="pageForm">
  21. <table>
  22. <tr>
  23. <td>
  24. 每页${pageControl.rowsPerPage}行
  25. </td>
  26. <td>
  27. 共${pageControl.maxRowCount }行
  28. </td>
  29. <td>
  30. 第${pageControl.curPage }页
  31. </td>
  32. <td>
  33. 共${pageControl.maxPage }页
  34. </td>
  35. <td>
  36. <c:choose>
  37. <c:when test="${pageControl.curPage == 1}">
  38. 首页 上一页
  39. </c:when>
  40. <c:otherwise>
  41. <A HREF="javascript:gotoPage(1)">首页</A>
  42. <A HREF="javascript:gotoPage(${pageControl.curPage - 1} )">上一页</A>
  43. </c:otherwise>
  44. </c:choose>
  45. <c:choose>
  46. <c:when test="${pageControl.curPage == pageControl.maxPage}">
  47. 下一页 尾页
  48. </c:when>
  49. <c:otherwise>
  50. <A HREF="javascript:gotoPage(${pageControl.curPage + 1})">下一页</A>
  51. <A HREF="javascript:gotoPage(${pageControl.maxPage })">尾页</A>
  52. </c:otherwise>
  53. </c:choose>
  54. 转到第
  55. <SELECT name="jumpPage" οnchange="jumping()">
  56. <c:forEach var="i" begin="1" end="${pageControl.maxPage}" step="1">
  57. <c:choose>
  58. <c:when test="${i == pageControl.curPage}">
  59. <OPTION selected value="${i}">${i }</OPTION>
  60. </c:when>
  61. <c:otherwise>
  62. <OPTION value="${i}">${i}</OPTION>
  63. </c:otherwise>
  64. </c:choose>
  65. </c:forEach>
  66. </SELECT>
  67. </td>
  68. </tr>
  69. </table>
  70. </form>
  71. </c:if>
  72. </body>
  73. </html>
<%@ page language="java"  contentType="text/html;charset=utf-8"pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head><script language="javascript">function jumping() {document.pageForm.submit();return true;}function gotoPage(pageNum) {document.pageForm.jumpPage.value = pageNum ;document.pageForm.submit();return true;}</script>
</head>
<body><c:if test="${pageControl.maxPage != 1}"><form method="post" action="pageAction.action" name="pageForm"><table><tr><td>每页${pageControl.rowsPerPage}行</td><td>共${pageControl.maxRowCount }行</td><td>第${pageControl.curPage }页</td><td>共${pageControl.maxPage }页</td><td><c:choose><c:when test="${pageControl.curPage == 1}">首页 上一页</c:when><c:otherwise><A HREF="javascript:gotoPage(1)">首页</A><A HREF="javascript:gotoPage(${pageControl.curPage - 1} )">上一页</A> </c:otherwise></c:choose><c:choose><c:when test="${pageControl.curPage == pageControl.maxPage}">下一页 尾页</c:when><c:otherwise><A HREF="javascript:gotoPage(${pageControl.curPage + 1})">下一页</A><A HREF="javascript:gotoPage(${pageControl.maxPage })">尾页</A></c:otherwise></c:choose>转到第<SELECT name="jumpPage" οnchange="jumping()"><c:forEach var="i" begin="1" end="${pageControl.maxPage}" step="1"><c:choose><c:when test="${i == pageControl.curPage}"><OPTION selected value="${i}">${i }</OPTION></c:when><c:otherwise><OPTION value="${i}">${i}</OPTION>                    </c:otherwise></c:choose></c:forEach></SELECT>页</td></tr></table></form></c:if></body>
</html>

下面是struts.xml中关于页面展示新闻的配置

Java代码  
  1. <action name="newsAction" class="newsAction" >
  2. <result type="redirect">pageAction.action</result>
  3. </action>
  4. <action name="pageAction" class="newsAction" method="pageAction">
  5. <result>/result.jsp</result>
  6. </action>
  7. <action name="detailAction" class="newsAction" method="showDetail">
  8. <result>/detail.jsp</result>
  9. </action>
         <action name="newsAction" class="newsAction" ><result type="redirect">pageAction.action</result>                 </action><action name="pageAction" class="newsAction" method="pageAction"><result>/result.jsp</result></action><action name="detailAction" class="newsAction" method="showDetail"><result>/detail.jsp</result></action>

NewsAction代码如下:

Java代码  
  1. package com.zly.test.action;
  2. import java.util.List;
  3. import java.util.Map;
  4. import com.zly.test.entity.NewsItem;
  5. import com.zly.test.entity.PageControl;
  6. import com.zly.test.service.NewsManager;
  7. public class NewsAction extends BaseAction {
  8. private static final long serialVersionUID = 7780804627621048756L;
  9. //对应分页jsp中的跳转到第几页
  10. private String jumpPage;
  11. //对应url?category的值
  12. private String category;
  13. //对新闻数据进行处理
  14. private NewsManager newsManager;
  15. //保存<entry key="china" value="1###国内新闻" />这样的信息
  16. private Map<String , String> map;
  17. //保存<entry key="1" value="china###国内新闻" />这样的信息
  18. private Map<String , String> map1;
  19. public Map<String, String> getMap1() {
  20. return map1;
  21. }
  22. public void setMap1(Map<String, String> map1) {
  23. this.map1 = map1;
  24. }
  25. public Map<String, String> getMap() {
  26. return map;
  27. }
  28. public void setMap(Map<String, String> map) {
  29. this.map = map;
  30. }
  31. public String getJumpPage() {
  32. return jumpPage;
  33. }
  34. public void setJumpPage(String jumpPage) {
  35. this.jumpPage = jumpPage;
  36. }
  37. public NewsManager getNewsManager() {
  38. return newsManager;
  39. }
  40. public void setNewsManager(NewsManager newsManager) {
  41. this.newsManager = newsManager;
  42. }
  43. //处理newsAction.action?category=xxx
  44. public String execute() {
  45. //得到相应的    1###国内新闻
  46. String typeIdInfo = map.get(category);
  47. //这里得到的是新闻类别id
  48. Integer typeId = Integer.parseInt(typeIdInfo.split("###")[0]);
  49. //这里得到的是新闻类别字符串
  50. String typeString = typeIdInfo.split("###")[1];
  51. //将上面三个变量保存在session中,在jsp页面中显示
  52. this.getSession().setAttribute("category", category);
  53. this.getSession().setAttribute("typeString" , typeString);
  54. this.getSession().setAttribute("id", typeId);
  55. //跳转到pageAction中,处理分页
  56. return SUCCESS;
  57. }
  58. public String pageAction() {
  59. //取出新闻类别id
  60. Integer id = (Integer) this.getSession().getAttribute("id");
  61. //查看是不是第一次来分页,如果是,当前页设置成第一个
  62. if(jumpPage == null) {
  63. jumpPage = "1";
  64. }
  65. //从request范围内取出PageControl , 如为空,则第一次分页,创建pageControl对象
  66. PageControl pageControl  = (PageControl) this.getRequest().getAttribute("pageControl");
  67. if(pageControl == null) {
  68. pageControl = new PageControl();
  69. //第一次的时候得到相应新闻类别所对应的记录的总数
  70. pageControl.setMaxRowCount(newsManager.getItemCounts(id));
  71. //计算一共多少页
  72. pageControl.countMaxPage();
  73. }
  74. //设置jumpPage的值为当前页
  75. pageControl.setCurPage(Integer.parseInt(jumpPage));
  76. //计算出hibernate中firstResult的值
  77. int firstResult = (pageControl.getCurPage() - 1) * pageControl.getRowsPerPage() + 1;
  78. //设置hibernate中maxResult的值
  79. int maxResult = pageControl.getRowsPerPage();
  80. //利用hibernate得到当前页的数据,并保存在pageControl分页实体类中
  81. List<NewsItem> userList = newsManager.getNewsItemByFirstResultAndMaxResult(firstResult, maxResult , id);
  82. pageControl.setData(userList);
  83. //将分页实体类保存在request范围内。
  84. this.getRequest().setAttribute("pageControl", pageControl);
  85. //将页面视图跳转到result.jsp
  86. return SUCCESS;
  87. }
  88. public String showDetail() {
  89. //得到url中的?id=xxx
  90. String newsId = this.getRequest().getParameter("id");
  91. int id = Integer.parseInt(newsId);
  92. //使用hibernate得到具体id的新闻记录
  93. NewsItem item = newsManager.getNewsById(id);
  94. //得到id记录所对应的新闻类型的值   map1这种形式<entry key="1" value="china###国内新闻" />
  95. int typeId = newsManager.getNewsType(id);
  96. //得到china,添加到jsp页面的<a href="newsAction?category=">里面
  97. String category = map1.get("" + typeId).split("###")[0];
  98. //得到国内新闻,显示在jsp页面的多个位置
  99. String typeString = map1.get("" + typeId).split("###")[1];
  100. //将以上多个数据添加到request范围内,以便显示。
  101. this.getRequest().setAttribute("news", item);
  102. this.getRequest().setAttribute("category", category);
  103. this.getRequest().setAttribute("typeString", typeString);
  104. return SUCCESS;
  105. }
  106. public String getCategory() {
  107. return category;
  108. }
  109. public void setCategory(String category) {
  110. this.category = category;
  111. }
  112. }
package com.zly.test.action;import java.util.List;
import java.util.Map;import com.zly.test.entity.NewsItem;
import com.zly.test.entity.PageControl;
import com.zly.test.service.NewsManager;public class NewsAction extends BaseAction {private static final long serialVersionUID = 7780804627621048756L;//对应分页jsp中的跳转到第几页private String jumpPage;//对应url?category的值private String category;//对新闻数据进行处理private NewsManager newsManager;//保存<entry key="china" value="1###国内新闻" />这样的信息private Map<String , String> map;//保存<entry key="1" value="china###国内新闻" />这样的信息private Map<String , String> map1;public Map<String, String> getMap1() {return map1;}public void setMap1(Map<String, String> map1) {this.map1 = map1;}public Map<String, String> getMap() {return map;}public void setMap(Map<String, String> map) {this.map = map;}public String getJumpPage() {return jumpPage;}public void setJumpPage(String jumpPage) {this.jumpPage = jumpPage;}public NewsManager getNewsManager() {return newsManager;}public void setNewsManager(NewsManager newsManager) {this.newsManager = newsManager;}//处理newsAction.action?category=xxxpublic String execute() {//得到相应的    1###国内新闻String typeIdInfo = map.get(category);//这里得到的是新闻类别idInteger typeId = Integer.parseInt(typeIdInfo.split("###")[0]);//这里得到的是新闻类别字符串String typeString = typeIdInfo.split("###")[1];//将上面三个变量保存在session中,在jsp页面中显示this.getSession().setAttribute("category", category);this.getSession().setAttribute("typeString" , typeString);this.getSession().setAttribute("id", typeId);//跳转到pageAction中,处理分页return SUCCESS;}public String pageAction() {//取出新闻类别idInteger id = (Integer) this.getSession().getAttribute("id");//查看是不是第一次来分页,如果是,当前页设置成第一个if(jumpPage == null) {jumpPage = "1";}//从request范围内取出PageControl , 如为空,则第一次分页,创建pageControl对象PageControl pageControl  = (PageControl) this.getRequest().getAttribute("pageControl");if(pageControl == null) {pageControl = new PageControl();//第一次的时候得到相应新闻类别所对应的记录的总数pageControl.setMaxRowCount(newsManager.getItemCounts(id));//计算一共多少页pageControl.countMaxPage();}//设置jumpPage的值为当前页pageControl.setCurPage(Integer.parseInt(jumpPage));//计算出hibernate中firstResult的值int firstResult = (pageControl.getCurPage() - 1) * pageControl.getRowsPerPage() + 1;//设置hibernate中maxResult的值int maxResult = pageControl.getRowsPerPage();//利用hibernate得到当前页的数据,并保存在pageControl分页实体类中List<NewsItem> userList = newsManager.getNewsItemByFirstResultAndMaxResult(firstResult, maxResult , id);pageControl.setData(userList);//将分页实体类保存在request范围内。this.getRequest().setAttribute("pageControl", pageControl);//将页面视图跳转到result.jspreturn SUCCESS;}public String showDetail() {//得到url中的?id=xxxString newsId = this.getRequest().getParameter("id");int id = Integer.parseInt(newsId);//使用hibernate得到具体id的新闻记录NewsItem item = newsManager.getNewsById(id);//得到id记录所对应的新闻类型的值   map1这种形式<entry key="1" value="china###国内新闻" />int typeId = newsManager.getNewsType(id);//得到china,添加到jsp页面的<a href="newsAction?category=">里面String category = map1.get("" + typeId).split("###")[0];//得到国内新闻,显示在jsp页面的多个位置String typeString = map1.get("" + typeId).split("###")[1];//将以上多个数据添加到request范围内,以便显示。this.getRequest().setAttribute("news", item);this.getRequest().setAttribute("category", category);this.getRequest().setAttribute("typeString", typeString);return SUCCESS;}public String getCategory() {return category;}public void setCategory(String category) {this.category = category;}}

首页页面index.jsp,里面有几个分类超链接和搜索对话框

Java代码  
  1. <%@ page language="java"  pageEncoding="utf-8"%>
  2. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  3. <html>
  4. <head>
  5. <title>最快新闻网</title>
  6. <link href="css/main.css" rel="stylesheet" type="text/css" />
  7. </head>
  8. <body>
  9. <div id="mainlink">
  10. <span><a href="index.jsp">最快新闻网</a></span><br /><br />
  11. <a href="newsAction.action?category=china" target="_blank">国内</a> | <a href="newsAction.action?category=world" target="_blank">国际</a> | <a href="newsAction.action?category=society" target="_blank">社会</a> | <a href="newsAction.action?category=compatriot" target="_blank">港澳</a> | <a href="newsAction.action?category=taiwan" target="_blank">台湾</a> | <a href="newsAction.action?category=huaren" target="_blank">华人</a> | <a href="newsAction.action?category=economic" target="_blank">经济</a> | <a href="newsAction.action?category=wenhua" target="_blank">文化</a> | <a href="newsAction.action?category=entertainment" target="_blank">娱乐</a> | <a href="newsAction.action?category=sports" target="_blank">体育</a> | <a href="newsAction.action?category=jiaoyu" target="_blank">教育</a> | <a href="newsAction.action?category=jiankang" target="_blank">健康</a> | <a href="newsAction.action?category=life" target="_blank">生活</a> | <a href="newsAction.action?category=keji" target="_blank">IT</a><br />
  12. <form action="searchAction.action" method="post" target="_blank">
  13. 本站搜索:
  14. <input type="text" name="searchParam" style="height:20px"/>
  15. <select name="searchWhich">
  16. <option value="title"/>标题
  17. <option value="content"/>内容
  18. </select>
  19. <input type="submit" value="搜索" style="height:23px"/>
  20. </form>
  21. </div>
  22. </body>
  23. </html>
<%@ page language="java"  pageEncoding="utf-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><title>最快新闻网</title><link href="css/main.css" rel="stylesheet" type="text/css" /></head><body><div id="mainlink"><span><a href="index.jsp">最快新闻网</a></span><br /><br /><a href="newsAction.action?category=china" target="_blank">国内</a> | <a href="newsAction.action?category=world" target="_blank">国际</a> | <a href="newsAction.action?category=society" target="_blank">社会</a> | <a href="newsAction.action?category=compatriot" target="_blank">港澳</a> | <a href="newsAction.action?category=taiwan" target="_blank">台湾</a> | <a href="newsAction.action?category=huaren" target="_blank">华人</a> | <a href="newsAction.action?category=economic" target="_blank">经济</a> | <a href="newsAction.action?category=wenhua" target="_blank">文化</a> | <a href="newsAction.action?category=entertainment" target="_blank">娱乐</a> | <a href="newsAction.action?category=sports" target="_blank">体育</a> | <a href="newsAction.action?category=jiaoyu" target="_blank">教育</a> | <a href="newsAction.action?category=jiankang" target="_blank">健康</a> | <a href="newsAction.action?category=life" target="_blank">生活</a> | <a href="newsAction.action?category=keji" target="_blank">IT</a><br /><form action="searchAction.action" method="post" target="_blank">本站搜索:<input type="text" name="searchParam" style="height:20px"/><select name="searchWhich"><option value="title"/>标题<option value="content"/>内容</select><input type="submit" value="搜索" style="height:23px"/></form>            </div></body>
</html>

其表现形式如下:

新闻分页展示页面result.jsp代码如下:

Html代码  
  1. <%@ page language="java" contentType="text/html;charset=utf-8"
  2. pageEncoding="utf-8"%>
  3. <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  4. <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
  5. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  6. <html>
  7. <head>
  8. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  9. <title>${typeString} -- 最快新闻网</title>
  10. </head>
  11. <body>
  12. <jsp:include page="index.jsp"></jsp:include>
  13. <div id="content">
  14. <font color="red" size="5">${typeString}</font>
  15. <br /><br /><br /><br />
  16. <div id="newsListTitle" style="float:left;">
  17. <c:forEach items="${pageControl.data}" var="news">
  18. <div style="margin-top: 20px;">
  19. <span>
  20. <a href="detailAction.action?id=${news.id }">${news.newsTitle }</a>
  21. </span>
  22. <br />
  23. </div>
  24. </c:forEach>
  25. </div>
  26. <div id="newsListTime">
  27. <c:forEach items="${pageControl.data}" var="news">
  28. <div style="margin-top: 20px;">
  29. <span>
  30. <fmt:formatDate value="${news.publishTime}" pattern="MM-dd HH:mm"/>
  31. </span>
  32. <br />
  33. </div>
  34. </c:forEach>
  35. </div>
  36. <br /><br /><br /><br />
  37. <%@ include file="page.jsp" %>
  38. </div>
  39. </body>
  40. </html>
<%@ page language="java" contentType="text/html;charset=utf-8"pageEncoding="utf-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>${typeString} -- 最快新闻网</title>
</head>
<body><jsp:include page="index.jsp"></jsp:include><div id="content"><font color="red" size="5">${typeString}</font><br /><br /><br /><br /><div id="newsListTitle" style="float:left;"><c:forEach items="${pageControl.data}" var="news"><div style="margin-top: 20px;"><span><a href="detailAction.action?id=${news.id }">${news.newsTitle }</a></span><br /></div></c:forEach>     </div><div id="newsListTime"><c:forEach items="${pageControl.data}" var="news"><div style="margin-top: 20px;"><span><fmt:formatDate value="${news.publishTime}" pattern="MM-dd HH:mm"/></span><br /></div></c:forEach></div><br /><br /><br /><br /><%@ include file="page.jsp" %></div>
</body>
</html>

显示效果如下:

其中点击具体超链接的效果图如下:

任务1 到此完成,新闻显示工作结束。下面是搜索引擎部分。

搜索的工具类放置在com.zly.indexManager包下面

说明,本程序使用了庖丁解牛中文分词,用户使用时需要中文字典,我的字典放在了c:\dic下面,使用庖丁还需要配置环境变量PAODING_DIC_HOME , 其值为c:\dic , (就是你的字典文件所在的目录)

代码如下:

创建索引类IndexCreateUtil

Java代码  
  1. package com.zly.indexManager;
  2. import java.io.File;
  3. import java.text.DateFormat;
  4. import java.text.SimpleDateFormat;
  5. import java.util.List;
  6. import net.paoding.analysis.analyzer.PaodingAnalyzer;
  7. import org.apache.lucene.analysis.Analyzer;
  8. import org.apache.lucene.document.Document;
  9. import org.apache.lucene.document.Field;
  10. import org.apache.lucene.index.IndexWriter;
  11. import org.hibernate.SessionFactory;
  12. import org.hibernate.cfg.AnnotationConfiguration;
  13. import org.hibernate.cfg.Configuration;
  14. import org.hibernate.Session;
  15. import org.htmlparser.Parser;
  16. import com.zly.test.entity.NewsItem;
  17. public class IndexCreateUtil {
  18. @SuppressWarnings("unchecked")
  19. public void createIndexForNews() throws Exception {
  20. //存放索引的文件夹
  21. File indexFile = new File("c:/index/news");
  22. //使用了庖丁解牛分词器
  23. Analyzer analyzer = new PaodingAnalyzer();
  24. //使用索引文件夹,庖丁解牛分词器创建IndexWriter
  25. IndexWriter indexWriter = new IndexWriter(indexFile , analyzer , true);
  26. //从数据库中读取出所有的新闻记录以便进行索引的创建
  27. Configuration cfg = new AnnotationConfiguration().configure();
  28. SessionFactory factory = cfg.buildSessionFactory();
  29. Session session = factory.openSession();
  30. List<NewsItem> list = session.createQuery(" from NewsItem").list();
  31. DateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
  32. //对所有的新闻实体进行索引创建
  33. for (NewsItem newsItem : list) {
  34. //建立一个lucene文档
  35. Document doc = new Document();
  36. //得到新闻标题
  37. String newsTitle = newsItem.getNewsTitle();
  38. //得到新闻内容
  39. String newsContent = newsItem.getNewsContent();
  40. //得到新闻事件
  41. String publishDate = format.format(newsItem.getPublishTime());
  42. //得到新闻主键id
  43. String id = newsItem.getId() + "";
  44. //将新闻标题加入文档,因为要搜索和高亮,所以index是tokennized,TermVector是WITH_POSITIONS_OFFSETS
  45. doc.add(new Field("title" , newsTitle , Field.Store.YES , Field.Index.TOKENIZED , Field.TermVector.WITH_POSITIONS_OFFSETS));
  46. //利用htmlparser得到新闻内容html的纯文本
  47. Parser parser = new Parser();
  48. parser.setInputHTML(newsContent);
  49. String strings = parser.parse(null).elementAt(0).toPlainTextString().trim();
  50. //添加新闻内容至文档,与标题相似
  51. doc.add(new Field("content" , strings , Field.Store.COMPRESS , Field.Index.TOKENIZED , Field.TermVector.WITH_POSITIONS_OFFSETS));
  52. //添加时间至文档,因为要按照此字段降序排列排序,所以tokenzied,不用高亮所以TermVector是no就行了
  53. doc.add(new Field("date" , publishDate , Field.Store.YES , Field.Index.TOKENIZED , Field.TermVector.NO));
  54. //添加主键至文档,不分词,不高亮。
  55. doc.add(new Field("id" , id , Field.Store.YES , Field.Index.NO , Field.TermVector.NO));
  56. indexWriter.addDocument(doc);
  57. }
  58. //创建索引
  59. indexWriter.optimize();
  60. indexWriter.close();
  61. //关闭session
  62. session.close();
  63. }
  64. public static void main(String[] args) throws Exception {
  65. IndexCreateUtil util  = new IndexCreateUtil();
  66. util.createIndexForNews();
  67. }
  68. }
package com.zly.indexManager;import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.List;import net.paoding.analysis.analyzer.PaodingAnalyzer;import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.hibernate.Session;
import org.htmlparser.Parser;import com.zly.test.entity.NewsItem;public class IndexCreateUtil {@SuppressWarnings("unchecked")public void createIndexForNews() throws Exception {//存放索引的文件夹File indexFile = new File("c:/index/news");//使用了庖丁解牛分词器Analyzer analyzer = new PaodingAnalyzer();//使用索引文件夹,庖丁解牛分词器创建IndexWriterIndexWriter indexWriter = new IndexWriter(indexFile , analyzer , true);//从数据库中读取出所有的新闻记录以便进行索引的创建Configuration cfg = new AnnotationConfiguration().configure();SessionFactory factory = cfg.buildSessionFactory();Session session = factory.openSession();List<NewsItem> list = session.createQuery(" from NewsItem").list();DateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");//对所有的新闻实体进行索引创建for (NewsItem newsItem : list) {//建立一个lucene文档Document doc = new Document();//得到新闻标题String newsTitle = newsItem.getNewsTitle();//得到新闻内容String newsContent = newsItem.getNewsContent();//得到新闻事件String publishDate = format.format(newsItem.getPublishTime());//得到新闻主键idString id = newsItem.getId() + "";//将新闻标题加入文档,因为要搜索和高亮,所以index是tokennized,TermVector是WITH_POSITIONS_OFFSETSdoc.add(new Field("title" , newsTitle , Field.Store.YES , Field.Index.TOKENIZED , Field.TermVector.WITH_POSITIONS_OFFSETS));//利用htmlparser得到新闻内容html的纯文本Parser parser = new Parser();parser.setInputHTML(newsContent);String strings = parser.parse(null).elementAt(0).toPlainTextString().trim();//添加新闻内容至文档,与标题相似doc.add(new Field("content" , strings , Field.Store.COMPRESS , Field.Index.TOKENIZED , Field.TermVector.WITH_POSITIONS_OFFSETS));//添加时间至文档,因为要按照此字段降序排列排序,所以tokenzied,不用高亮所以TermVector是no就行了doc.add(new Field("date" , publishDate , Field.Store.YES , Field.Index.TOKENIZED , Field.TermVector.NO));//添加主键至文档,不分词,不高亮。doc.add(new Field("id" , id , Field.Store.YES , Field.Index.NO , Field.TermVector.NO));indexWriter.addDocument(doc);}//创建索引indexWriter.optimize();indexWriter.close();//关闭sessionsession.close();}public static void main(String[] args) throws Exception {IndexCreateUtil util  = new IndexCreateUtil();util.createIndexForNews();}
}

对索引进行搜索的代码如下:

Java代码  
  1. package com.zly.indexManager;
  2. import java.io.File;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. import net.paoding.analysis.analyzer.PaodingAnalyzer;
  6. import org.apache.lucene.analysis.Analyzer;
  7. import org.apache.lucene.document.Document;
  8. import org.apache.lucene.index.IndexReader;
  9. import org.apache.lucene.queryParser.QueryParser;
  10. import org.apache.lucene.search.Hits;
  11. import org.apache.lucene.search.IndexSearcher;
  12. import org.apache.lucene.search.Query;
  13. import org.apache.lucene.search.Sort;
  14. import org.apache.lucene.search.highlight.Highlighter;
  15. import org.apache.lucene.search.highlight.QueryScorer;
  16. import org.apache.lucene.search.highlight.SimpleFragmenter;
  17. import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
  18. import com.zly.test.entity.SearchResultBean;
  19. public class IndexSearchUtil {
  20. public List<SearchResultBean> getSearchResult(String searchWhich , String searchParam , int firstResult , int maxResult) throws Exception{
  21. //索引所在文件夹
  22. File indexFile = new File("c:/index/news");
  23. //读取索引的indexReader
  24. IndexReader reader = IndexReader.open(indexFile);
  25. //庖丁解牛分词器
  26. Analyzer analyzer = new PaodingAnalyzer();
  27. //指定对content还是title进行查询
  28. QueryParser parser = new QueryParser(searchWhich , analyzer);
  29. //创建indexSearcher
  30. IndexSearcher searcher  = new IndexSearcher(reader);
  31. //对用户的输入进行查询
  32. Query query = parser.parse(searchParam);
  33. //根据date字段进行排序,得到查询结果
  34. Hits hits = searcher.search(query , new Sort("date" , true));
  35. //创建list,将结果保存其中,以便在jsp页面中进行显示
  36. List<SearchResultBean> list = new ArrayList<SearchResultBean>();
  37. //模拟hibernate的serFirstResult和setMaxResult以便返回指定条目的结果
  38. for (int i = firstResult - 1; i < firstResult + maxResult - 1; i++) {
  39. Document doc = hits.doc(i);
  40. //取得该条索引文档
  41. SearchResultBean srb = new SearchResultBean();
  42. //从中取出标题
  43. String title = doc.get("title");
  44. //从中取出内容
  45. String content = doc.get("content");
  46. //从中取出主键id
  47. String id = doc.get("id");
  48. //从中取出发布时间
  49. String date = doc.get("date");
  50. //高亮htmlFormatter对象
  51. SimpleHTMLFormatter sHtmlF = new SimpleHTMLFormatter("<b><font color='red'>", "</font></b>");
  52. //高亮对象
  53. Highlighter highlighter = new Highlighter(sHtmlF,new QueryScorer(query));
  54. //设置高亮附近的字数
  55. highlighter.setTextFragmenter(new SimpleFragmenter(100));
  56. //如果查询的是标题,进行处理
  57. if(searchWhich.equals("title")) {
  58. String bestFragment = highlighter.getBestFragment(analyzer,searchWhich,title);
  59. //获得高亮后的标题内容
  60. srb.setTitle(bestFragment);
  61. //如果内容不足150个字,全部设置
  62. if(content.length() < 150) {
  63. srb.setContent(content);
  64. }else {
  65. //如果内容多于150个字,只取出前面150个字
  66. srb.setContent(content.substring(0 , 150));
  67. }
  68. } else {
  69. //如果查询的是内容字段
  70. String bestFragment = highlighter.getBestFragment(analyzer,searchWhich,content);
  71. //取得高亮内容并设置
  72. srb.setContent(bestFragment);
  73. //设置标题,全部设置
  74. srb.setTitle(title);
  75. }
  76. //设置日期
  77. srb.setDate(date);
  78. //设置主键
  79. srb.setId(id);
  80. //添加到list中,以便在jsp页面上显示
  81. list.add(srb);
  82. }
  83. return list;
  84. }
  85. //取得符合搜索条件的所有记录总数,以便分页 , 与上面方法类似
  86. public int getResultCount(String searchWhich , String searchParam) throws Exception {
  87. File indexFile = new File("c:/index/news");
  88. IndexReader reader = IndexReader.open(indexFile);
  89. Analyzer analyzer = new PaodingAnalyzer();
  90. QueryParser parser = new QueryParser(searchWhich , analyzer);
  91. IndexSearcher searcher  = new IndexSearcher(reader);
  92. Query query = parser.parse(searchParam);
  93. Hits hits = searcher.search(query);
  94. return hits.length();
  95. }
  96. }
package com.zly.indexManager;import java.io.File;
import java.util.ArrayList;
import java.util.List;import net.paoding.analysis.analyzer.PaodingAnalyzer;import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Sort;
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 com.zly.test.entity.SearchResultBean;public class IndexSearchUtil {public List<SearchResultBean> getSearchResult(String searchWhich , String searchParam , int firstResult , int maxResult) throws Exception{//索引所在文件夹File indexFile = new File("c:/index/news");//读取索引的indexReaderIndexReader reader = IndexReader.open(indexFile);//庖丁解牛分词器Analyzer analyzer = new PaodingAnalyzer();//指定对content还是title进行查询QueryParser parser = new QueryParser(searchWhich , analyzer);//创建indexSearcherIndexSearcher searcher  = new IndexSearcher(reader);//对用户的输入进行查询Query query = parser.parse(searchParam);//根据date字段进行排序,得到查询结果Hits hits = searcher.search(query , new Sort("date" , true));//创建list,将结果保存其中,以便在jsp页面中进行显示List<SearchResultBean> list = new ArrayList<SearchResultBean>();//模拟hibernate的serFirstResult和setMaxResult以便返回指定条目的结果for (int i = firstResult - 1; i < firstResult + maxResult - 1; i++) {Document doc = hits.doc(i);//取得该条索引文档SearchResultBean srb = new SearchResultBean();//从中取出标题String title = doc.get("title");//从中取出内容String content = doc.get("content");//从中取出主键idString id = doc.get("id");//从中取出发布时间String date = doc.get("date");//高亮htmlFormatter对象SimpleHTMLFormatter sHtmlF = new SimpleHTMLFormatter("<b><font color='red'>", "</font></b>");//高亮对象Highlighter highlighter = new Highlighter(sHtmlF,new QueryScorer(query));//设置高亮附近的字数highlighter.setTextFragmenter(new SimpleFragmenter(100));//如果查询的是标题,进行处理if(searchWhich.equals("title")) {String bestFragment = highlighter.getBestFragment(analyzer,searchWhich,title);//获得高亮后的标题内容srb.setTitle(bestFragment);//如果内容不足150个字,全部设置if(content.length() < 150) {srb.setContent(content);}else {//如果内容多于150个字,只取出前面150个字srb.setContent(content.substring(0 , 150));}} else {//如果查询的是内容字段String bestFragment = highlighter.getBestFragment(analyzer,searchWhich,content);//取得高亮内容并设置srb.setContent(bestFragment);//设置标题,全部设置srb.setTitle(title);}//设置日期srb.setDate(date);//设置主键srb.setId(id);//添加到list中,以便在jsp页面上显示list.add(srb);}return list;}//取得符合搜索条件的所有记录总数,以便分页 , 与上面方法类似public int getResultCount(String searchWhich , String searchParam) throws Exception {File indexFile = new File("c:/index/news");IndexReader reader = IndexReader.open(indexFile);Analyzer analyzer = new PaodingAnalyzer();QueryParser parser = new QueryParser(searchWhich , analyzer);IndexSearcher searcher  = new IndexSearcher(reader);Query query = parser.parse(searchParam);Hits hits = searcher.search(query);return hits.length();}
}

分页action代码如下:

Java代码  
  1. package com.zly.test.action;
  2. import java.util.List;
  3. import com.zly.indexManager.IndexSearchUtil;
  4. import com.zly.test.entity.PageControl;
  5. import com.zly.test.entity.SearchResultBean;
  6. public class SearchAction extends BaseAction {
  7. private static final long serialVersionUID = -2387037924517370511L;
  8. //查询索引实体类
  9. private IndexSearchUtil indexSearcher;
  10. //对应搜索字段是标题还是内容
  11. private String searchWhich;
  12. //对应用户输入的搜索内容
  13. private String searchParam;
  14. //对应分页跳转到的页面
  15. private String jumpPage;
  16. public String getJumpPage() {
  17. return jumpPage;
  18. }
  19. public void setJumpPage(String jumpPage) {
  20. this.jumpPage = jumpPage;
  21. }
  22. public String getSearchWhich() {
  23. return searchWhich;
  24. }
  25. public void setSearchWhich(String searchWhich) {
  26. this.searchWhich = searchWhich;
  27. }
  28. public String getSearchParam() {
  29. return searchParam;
  30. }
  31. public void setSearchParam(String searchParam) {
  32. this.searchParam = searchParam;
  33. }
  34. public String search() throws Exception {
  35. //如果为空,说明第一次进入分页
  36. if(jumpPage == null) {
  37. jumpPage = "1";
  38. }
  39. //从request范围内取得pageControl对象
  40. PageControl pageControl  = (PageControl) this.getRequest().getAttribute("pageControl");
  41. //如果为空,则是第一次分页,创建分页对象,并且设置总的记录条数,以便设置最大页数
  42. if(pageControl == null) {
  43. pageControl = new PageControl();
  44. pageControl.setMaxRowCount((long)indexSearcher.getResultCount(searchWhich, searchParam));
  45. pageControl.countMaxPage();
  46. }
  47. //设置当前页
  48. pageControl.setCurPage(Integer.parseInt(jumpPage));
  49. //计算firstResult
  50. int firstResult = (pageControl.getCurPage() - 1) * pageControl.getRowsPerPage() + 1;
  51. //计算从当前条数算还有多少条记录
  52. long left = pageControl.getMaxRowCount() - firstResult;
  53. int maxResult = -1;
  54. //如果剩余的记录数不如每页显示数,就设置maxResult为剩余条数
  55. if(left < pageControl.getRowsPerPage()) {
  56. maxResult = Integer.valueOf(left + "");
  57. //如果剩余记录数大于每页显示页数,就设置maxResult为每页条数
  58. }else {
  59. maxResult = pageControl.getRowsPerPage();
  60. }
  61. //取得查询结果集
  62. List<SearchResultBean> userList = indexSearcher.getSearchResult(searchWhich, searchParam, firstResult, maxResult);
  63. //设置为pageControl
  64. pageControl.setData(userList);
  65. //将pageControl设置到request范围,以便在jsp现实结果
  66. this.getRequest().setAttribute("pageControl", pageControl);
  67. //将searchWhich和searchParam设置到request范围,以便添加到分页jsp的form里面的hidden表单域,以便下次分页时,能够将值提交过来
  68. this.getRequest().setAttribute("searchWhich", searchWhich);
  69. this.getRequest().setAttribute("searchParam", searchParam);
  70. //跳转到分页视图
  71. return SUCCESS;
  72. }
  73. public IndexSearchUtil getIndexSearcher() {
  74. return indexSearcher;
  75. }
  76. public void setIndexSearcher(IndexSearchUtil indexSearcher) {
  77. this.indexSearcher = indexSearcher;
  78. }
  79. }
package com.zly.test.action;import java.util.List;import com.zly.indexManager.IndexSearchUtil;
import com.zly.test.entity.PageControl;
import com.zly.test.entity.SearchResultBean;public class SearchAction extends BaseAction {private static final long serialVersionUID = -2387037924517370511L;//查询索引实体类private IndexSearchUtil indexSearcher;//对应搜索字段是标题还是内容private String searchWhich;//对应用户输入的搜索内容private String searchParam;//对应分页跳转到的页面private String jumpPage;public String getJumpPage() {return jumpPage;}public void setJumpPage(String jumpPage) {this.jumpPage = jumpPage;}public String getSearchWhich() {return searchWhich;}public void setSearchWhich(String searchWhich) {this.searchWhich = searchWhich;}public String getSearchParam() {return searchParam;}public void setSearchParam(String searchParam) {this.searchParam = searchParam;}public String search() throws Exception {//如果为空,说明第一次进入分页if(jumpPage == null) {jumpPage = "1";}//从request范围内取得pageControl对象PageControl pageControl  = (PageControl) this.getRequest().getAttribute("pageControl");//如果为空,则是第一次分页,创建分页对象,并且设置总的记录条数,以便设置最大页数 if(pageControl == null) {pageControl = new PageControl();pageControl.setMaxRowCount((long)indexSearcher.getResultCount(searchWhich, searchParam));pageControl.countMaxPage();}//设置当前页pageControl.setCurPage(Integer.parseInt(jumpPage));//计算firstResultint firstResult = (pageControl.getCurPage() - 1) * pageControl.getRowsPerPage() + 1;//计算从当前条数算还有多少条记录long left = pageControl.getMaxRowCount() - firstResult;int maxResult = -1;//如果剩余的记录数不如每页显示数,就设置maxResult为剩余条数if(left < pageControl.getRowsPerPage()) {maxResult = Integer.valueOf(left + "");//如果剩余记录数大于每页显示页数,就设置maxResult为每页条数}else {maxResult = pageControl.getRowsPerPage(); }//取得查询结果集List<SearchResultBean> userList = indexSearcher.getSearchResult(searchWhich, searchParam, firstResult, maxResult);//设置为pageControlpageControl.setData(userList);//将pageControl设置到request范围,以便在jsp现实结果this.getRequest().setAttribute("pageControl", pageControl);//将searchWhich和searchParam设置到request范围,以便添加到分页jsp的form里面的hidden表单域,以便下次分页时,能够将值提交过来this.getRequest().setAttribute("searchWhich", searchWhich);this.getRequest().setAttribute("searchParam", searchParam);//跳转到分页视图return SUCCESS;}public IndexSearchUtil getIndexSearcher() {return indexSearcher;}public void setIndexSearcher(IndexSearchUtil indexSearcher) {this.indexSearcher = indexSearcher;}}

搜索的action在struts.xml中设置如下:

Xml代码  
  1. <action name="searchAction" class="searchAction" method="search">
  2. <result>/searchResult.jsp</result>
  3. </action>
            <action name="searchAction" class="searchAction" method="search"><result>/searchResult.jsp</result></action>

//searchResult.jsp代码如下:

Html代码  
  1. <%@ page language="java" contentType="text/html;charset=utf-8"
  2. pageEncoding="utf-8"%>
  3. <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  4. <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
  5. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  6. <html>
  7. <head>
  8. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  9. <title>${searchParam} 的搜查结果 -- 最快新闻网</title>
  10. </head>
  11. <body>
  12. <jsp:include page="index.jsp"></jsp:include>
  13. <div id="content">
  14. <div id="searchResults" >
  15. <c:forEach items="${pageControl.data}" var="result">
  16. <div style="margin-top: 20px;">
  17. <span>
  18. <a href="detailAction.action?id=${result.id }">${result.title}</a><br />
  19. ${result.content }
  20. <font color="green">http://localhost:8080/NewsWithSearch/detailAction.action?id=${result.id } ${result.date }</font>
  21. </span>
  22. <br />
  23. </div>
  24. </c:forEach>
  25. </div>
  26. <br /><br /><br /><br />
  27. <%@ include file="searchPage.jsp" %>
  28. </div>
  29. </body>
  30. </html>
<%@ page language="java" contentType="text/html;charset=utf-8"pageEncoding="utf-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>${searchParam} 的搜查结果 -- 最快新闻网</title>
</head>
<body><jsp:include page="index.jsp"></jsp:include><div id="content"><div id="searchResults" ><c:forEach items="${pageControl.data}" var="result"><div style="margin-top: 20px;"><span><a href="detailAction.action?id=${result.id }">${result.title}</a><br />${result.content }<font color="green">http://localhost:8080/NewsWithSearch/detailAction.action?id=${result.id } ${result.date }</font></span><br /></div></c:forEach>     </div><br /><br /><br /><br /><%@ include file="searchPage.jsp" %></div>
</body>
</html>

所有的资源我都添加到了附件中,学过ssh的同学应该能够成功部署项目并运行。

其中NewsWithSearch.rar是工程文件夹,包含了所有的代码文件和jar包,加压完直接引到MyEclipse里就行,data.rar是所有的sql语句,插入到MySQL之前应先建立数据库mynews  ,     dic.rar是庖丁解牛用到的字典文件,

解压成一个文件夹,并配置环境变量PAODING_DIC_HOME,其值就是你把它解压成的文件夹(例如c:\dic),最后如果你不想创建索引的话,可以把news.rar解压成一个文件夹,拷贝到c:\index\news下面。

原文地址:http://shuaigg-babysky.iteye.com/blog/414477

SSH + Lucene + 分页 + 排序 + 高亮 模拟简略新闻网站搜索引擎相关推荐

  1. SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎

    http://shuaigg-babysky.iteye.com/blog/414477 前两天看到了一个中国新闻网,这个网站的搜索form的action是 http://search.chinane ...

  2. SSH + Lucene + 分页 + 排序 + 高亮 模拟简单新闻网站搜索引擎 .

    IDE使用的MyEclipse6.5,数据库使用MySQL 5.0.37 , 另装了Navicat for MySQL , jdk版本是6.0 工程做完的效果图如下,com.zly.indexMana ...

  3. Solr分页与高亮(使用SolrNet实现)

    Solr分页与高亮(使用SolrNet实现) 本节我们使用Asp.net MVC实现Solr客户端查询,建议使用SolrNet这个客户端,开源地址在:https://github.com/mausch ...

  4. SqlServer分页排序存储过程 V1.0

    set ANSI_NULLS ON  set QUOTED_IDENTIFIER ON  GO  /*  分页排序存储过程 V1.0  */ ALTER procedure [dbo].[sp_Key ...

  5. jooq 分页排序_将jOOQ与Spring结合使用:排序和分页

    jooq 分页排序 JOOQ是一个库,可以帮助我们控制SQL. 它可以从我们的数据库生成代码,并允许我们使用其流畅的API来构建类型安全的数据库查询. 本教程前面的部分向我们介绍了如何配置应用程序的应 ...

  6. jpa 分页 排序 过滤_使用JPA标准@ViewScoped通过分页,过滤和排序进行Primefaces DataTable延迟加载...

    jpa 分页 排序 过滤 Primefaces数据表惰性分页有效,但是在Web上使用Criteria搜索完整示例后,我感到非常沮丧. 所以我混合了来自 http://stackoverflow.com ...

  7. Spring Boot 学习[四] web项目实战训练(增删改查,分页,排序)

    Spring boot非常适合Web应用程序开发.您可以轻松创建自包含的HTTP应用.web服务器采用嵌入式Tomcat,或者Jetty等. 几点说明: Spring boot开发web项目,通常打成 ...

  8. MybatisPlus 分页排序封装

    思路 采用 HandlerMethodArgumentResolver 预先对排序数据处理. 代码 MybatisPlusProperties @ConfigurationProperties(&qu ...

  9. elementUi设置表格分页排序

    elementUi设置表格分页排序 (scope.$index+1)+(tableModel.pageNum-1)*(tableModel.pageSize) 效果图 <template> ...

最新文章

  1. JS中的作用域(一)-详谈
  2. mysql 绿色版远程访问_【Linux】MySQL解压版安装及允许远程访问
  3. 关于英伟达数字人文章的致歉和说明
  4. Qt / 窗体设置 Qt::WA_TranslucentBackground 为全黑的原因
  5. 工信部印发《信息安全产业“十二五”发展规划》
  6. 利用福禄克DSX2-5000 CH解决双绞线布线中常见的故障
  7. linux中文件属性mtime,linux stat (三个时间属性命令可用来列出文件的 atime、ctime 和 mtime。)...
  8. 图解WinCE6.0下的内核驱动和用户驱动
  9. greenfoot推箱子游戏_推箱子小游戏V2.0更新
  10. 电大法学本科计算机考试题,2016年电大-电大法学本科计算机网考答案.doc
  11. 写一个生产者消费者的例子
  12. ab测试工具结果分析
  13. 【老生谈算法】matlab实现自适应滤波器源码——自适应滤波器
  14. 微信的自动回复接入聊天机器人
  15. 穿膜肽TAT修饰载荧光探针香豆素-6脂质体
  16. 福特汉姆大学计算机科学专业,福特汉姆大学计算机科学排名第131(2018年TFE美国排名)...
  17. 猜单词游戏更新啦 (0.88.2及1.88.3)
  18. java 时间间隔 工作日_计算Java中两个日期之间的工作日数
  19. sstream类的详解
  20. 亚甲基蓝在胃肠道恶性肿瘤淋巴结检获中应用价值的Meta分析

热门文章

  1. 7.MPLS VP恩 后门链路shamlink
  2. 2019全球程序员薪酬报告:软件开发比机器学习抢手,40岁后收入下滑!
  3. 《流浪地球2》票房突破18亿
  4. 宏基linux连不上wifi,宏基电脑连不上无线网络怎么回事
  5. CSU OJ 代码搜集(1000-1100)
  6. android setBackground
  7. torch.nn.Unfold类
  8. 人本界面:交互式系统设计
  9. Linux banner/konsole
  10. DXSDK_Jun10安装错误解决!/directX安装错误