java垂直搜索引擎_垂直搜索引擎完整实现

本篇博客是在上一篇《Lucene搜索引擎+HDFS+MR完成垂直搜索》的基础上,在数据收集之后的JSP/Servlet方面,换为SpringMVC框架来实现。

借助SpringMVC技术完成数据库、HDFS、页面的交互,以达到实现垂直搜索引擎。

本篇博客的思想:一是深入数据收集、分析、关键词搜索呈现的流程实现;

一是借此实践学习SpringMVC框架的技术。

首先简单阐述实现垂直搜索引擎的流程:1‘网络爬虫的数据存取到HDFS和数据库中;

2’MR对数据进行分析规约;

3‘SpringMVC实现关键词搜索并呈现到网页(此处为本篇重点阐述)

----->

目录:

1、SpringMVC阐述

2、创建web项目(添加Spring框架支持)

3、配置applicationContext.xml★★

4、配置web.xml文件★★

5、添加log4j.properties文件至src根目录

6、实现DAO操作类

7、修改页面源码

8、编写控制器来自动接收参数,以及进行数据操作★★

9、过滤器解决乱码问题

10、结果显示

11、总结

------>

1、  SpringMVC阐述

SpringMVC是Spring的一个子框架,主要是用来处理MVC设计模式中的View和Control。

MVC:

Model:模型层,也就是数据库操作层。DAO部分代码

View:展示层,也就是页面显示部分。Servlet部分

Controller:控制层,也就是业务逻辑层。JSP部分

使用SpringMVC以后,这三部分代码都会有改变,由Spring来进行调整。

企业用的最多的是SpringMVC + MyBatis。

这里我们就只使用SpringMVC + JDBC来完成。

Spring 在这三层可以有不同的作用:

Model层中Spring可以帮助进行数据源连接池的配置,还可以简化JDBC的操作代码,同时还能帮助完成自动的打开和关闭数据库连接。

View层中,Spring可以帮助我们简化表单提交的参数代码,也可以自动接收Control中返回的数据信息。

Control层中,Spring可以帮助我们自动接收页面提交的参数。

Spring的核心在于配置文件,所有的类的信息基本都要加入到配置文件中或使用Annotation来进行标注。

2、创建web项目(添加Spring框架支持)

e19ca80b4161e6a64f2f37168c2aba56.png【项目整体呈现】

创建一个新的web项目,导入上一篇项目所需的jar包,以及拷贝vo类(DAO接口类)和utils类(关键词查询类)所在的包。

先为项目加入Spring的框架支持。

在项目上点右键,选择MyEclipse,然后找到install Spring … 的选项。

按照固定的步骤加入支持,最后一步时,一定要注意选择好需要的支持库,这里必须用到的是Persistence和Web

1048a6b3b775211a517702459ff81ff9.png

3、配置applicationContext.xml

这个文件Spring的配置文件,主要是将各种POJO,JAVA,action配置到XML转交给beanfactory管理,降低耦合度。

主要的配置组件:

然后就是这些之间的依赖关系,比如:

以上代码的意思会在loginAction的代码里引用MyServiceImpl类,但是只需要用ms代替就可以

例如:

public String execute() throws Exception{

ms.sayhello();

}

正常情况应该 new MyServiceImpl,但是通过XML配置之后就直接用以上代码就可以实现

new 的效果。

以下是该项目的配置文件呈现:

1 <?xml version="1.0" encoding="UTF-8"?>

2

4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

5 xmlns:p="http://www.springframework.org/schema/p"

6

7 xmlns:context="http://www.springframework.org/schema/context"

8 xmlns:mvc="http://www.springframework.org/schema/mvc"

9

10 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd

11 http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.1.xsd

12 http://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

54

55

56

57 PROPAGATION_REQUIRED

58

59

60

61

62

63

64

65

66

67 transactionInterceptor

68

69

70

71

72 *DAOImpl

73

74

75

76

77

78

79

4、配置web.xml文件

这个文件是需要在里面让服务器启动时,可以自动加载spring的配置文件。

代码呈现:

1 <?xml version="1.0" encoding="UTF-8"?>

2

3 xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"

5 id="WebApp_ID" version="3.0">

6 SinaNewsSpringMVC

7

8 index.html

9

10

11 org.springframework.web.context.ContextLoaderListener

12

13

14 contextConfigLocation

15 classpath:applicationContext.xml

16

17

18

19

20 springmvc

21 org.springframework.web.servlet.DispatcherServlet

22

23

24 contextConfigLocation

25 /WEB-INF/classes/applicationContext.xml

26

27 1

28

29

30 springmvc

31 *.do

32

33

34

35

36 encoding

37 org.liky.sina.filter.EncodingFilter

38

39

40 encoding

41 /*42 43

5、添加log4j.properties文件至src根目录

Log4j,Apache的一个开源项目,作用:

可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIXSyslog守护进程等;

可以控制每一条日志的输出格式;

通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。

此外,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

1 ### direct log messages to stdout ###2 log4j.appender.stdout=org.apache.log4j.ConsoleAppender3 log4j.appender.stdout.Target=System.out4 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout5 log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n6

7 ### direct messages to file hibernate.log ###8 #log4j.appender.file=org.apache.log4j.FileAppender9 #log4j.appender.file.File=hibernate.log10 #log4j.appender.file.layout=org.apache.log4j.PatternLayout11 #log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n12

13 ### set log levels - for more verbose logging change 'info' to 'debug'###14

15 log4j.rootLogger=warn, stdout16

17 log4j.logger.org.hibernate=info18 #log4j.logger.org.hibernate=debug19

20 ### log HQL query parser activity21 #log4j.logger.org.hibernate.hql.ast.AST=debug22

23 ### log just the SQL24 #log4j.logger.org.hibernate.SQL=debug25

26 ### log JDBC bind parameters ###27 log4j.logger.org.hibernate.type=info28 #log4j.logger.org.hibernate.type=debug29

30 ### log schema export/update ###31 log4j.logger.org.hibernate.tool.hbm2ddl=debug32

33 ### log HQL parse trees34 #log4j.logger.org.hibernate.hql=debug35

36 ### log cache activity ###37 #log4j.logger.org.hibernate.cache=debug38

39 ### log transaction activity40 #log4j.logger.org.hibernate.transaction=debug41

42 ### log JDBC resource acquisition43 #log4j.logger.org.hibernate.jdbc=debug44

45 ### enable the following line ifyou want to track down connection ###46 ### leakages when using DriverManagerConnectionProvider ###47 #log4j.logger.org.hibernate.connection.DriverManagerConnectionProvider=trace

6、实现DAO操作类

之后启动服务器进行测试,如果启动后没有报错,那就表示环境配置成功,可以正常使用。

下面就开始编写DAO操作。

对于DAO接口是没有变化的,所以可以直接拷贝过来。

这里不需要再编写工厂类,因为Spring可以自动帮助创建对象。

实现类需要交给Spring来进行管理和控制,并且简化jdbc代码操作

代码如下:

1 packageorg.liky.sina.dao.impl;2

3 importjava.sql.ResultSet;4 importjava.sql.SQLException;5 importjava.util.List;6

7 importorg.liky.sina.dao.INewsDAO;8 importorg.liky.sina.vo.News;9 importorg.springframework.beans.factory.annotation.Autowired;10 importorg.springframework.jdbc.core.JdbcTemplate;11 importorg.springframework.jdbc.core.RowMapper;12 importorg.springframework.jdbc.core.support.JdbcDaoSupport;13 importorg.springframework.stereotype.Component;14

15 @Component16 public class NewsDAOImpl extends JdbcDaoSupport implements INewsDAO,RowMapper{17

18 @Autowired19 publicNewsDAOImpl(JdbcTemplate jdbcTemplate) {20 super.setJdbcTemplate(jdbcTemplate);21 }22

23

24 public void doCreate(News news) throwsException {25 String sql="insert into news (id,title,description,url) values (?,?,?,?)";26

27 super.getJdbcTemplate().update(sql, news.getId(),news.getTitle(),news.getDescription(),news.getUrl());28 }29

30 public News findById(int id) throwsException {31 String sql="select id,title,description,url from news where id=?";32 News news=super.getJdbcTemplate().queryForObject(sql,new Object[]{id},this);33

34 returnnews;35 }36

37 public List findByIds(Integer[] ids, int start, intpageSize)38 throwsException {39 StringBuilder sql = newStringBuilder(40 "SELECT id,title,description,url FROM new_news WHERE id IN (");41 if (ids != null && ids.length > 0) {42 for (intid : ids) {43 sql.append(id);44 sql.append(",");45 }46 //第一个 ? 表示开始的记录数,第二个 ? 表示每页显示的记录数。

47 String resultSQL = sql.substring(0, sql.length() - 1)48 + ") LIMIT ?,?";49 List allNews = super.getJdbcTemplate().query(resultSQL,50 new Object[] { start, pageSize }, this);51 returnallNews;52 }53 return null;54 }55

56

57 public int getAllCount(Integer[] ids)throwsException{58 StringBuilder sql=new StringBuilder("select count(id) from new_news where id in (");59

60 if(ids!=null&&ids.length>0){61 for(intid:ids){62 sql.append(id);63 sql.append(",");64 }65 //第一个 ? 表示开始的记录数,第二个 ? 表示每页显示的记录数。

66 String resultSQL = sql.substring(0, sql.length() - 1) + ")";67 int count = super.getJdbcTemplate().queryForInt(resultSQL);68 returncount;69 }70 return 0;71 }72

73 public News mapRow(ResultSet rs, int arg1) throwsSQLException {74 News news=newNews();75 news.setId(rs.getInt(1));76 news.setTitle(rs.getString(2));77 news.setDescription(rs.getString(3));78 news.setUrl(rs.getString(4));79 returnnews;80

81 }82

83 }

7、修改页面源码

表单部分进行一些简单的调整,加入了form标签相关的配置。主要在action的值改为了search.do

【1】index.jsp修改

1

2

3 String path =request.getContextPath();4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";5 %>

6

7

8

9

10

11

新浪新闻热词搜索

12

13

14

15

16

17 请输入查询关键字:18

19

20

21

22

23

【2】result.jsp修改

1

2

3

4 String path =request.getContextPath();5 String basePath = request.getScheme() + "://"

6 + request.getServerName() + ":" +request.getServerPort()7 + path + "/";8 %>

9

10

11

12

13

14

15

新浪新闻搜索

16

17

18

19

20

21 List allNews = (List)request.getAttribute("allNews");22 %>

23

24

25 for(News n : allNews) {26

27 %>

28

29

30

31

32


33

34

35

36 }37

38 %>

39

40

41

42 int cp = (Integer)request.getAttribute("currentPage");43 int allPages = (Integer)request.getAttribute("allPages");44 %>

45

46

47 value="首页" οnclick="changeCp(1);">

48 value="上一页" οnclick="changeCp();">

49 value="下一页" οnclick="changeCp();">

50 value="尾页" οnclick="changeCp();">

51 第 页 / 共 页52

53 请输入查询关键字:">

54

55

56

57 function changeCp(newcp) {58 //改变当前页数

59 document.getElementById("cp").value =newcp;60 //提交表单

61 document.getElementById("split_page_form").submit();62 }63

64

65

66

67

8、编写控制器来自动接收参数,以及进行数据操作

之后需要编写SpringMVC的控制器来自动接收参数,并进行数据操作。

代码呈现:

1 packageorg.liky.sina.action;2

3 importjava.util.List;4

5 importjavax.annotation.Resource;6

7 importorg.liky.sina.dao.INewsDAO;8 importorg.liky.sina.utils.HDFSUtils;9 importorg.liky.sina.vo.News;10 importorg.springframework.stereotype.Controller;11 importorg.springframework.web.bind.annotation.RequestMapping;12 importorg.springframework.web.bind.annotation.RequestParam;13 importorg.springframework.web.servlet.ModelAndView;14

15

16 @Controller17 public classNewsAction {18 privateINewsDAO newsdao;19

20 @RequestMapping(value="/search.do")21 public ModelAndView search(@RequestParam String keyword,@RequestParam(defaultValue="1") intcurrentPage){22 ModelAndView mv= newModelAndView();23 //一页显示10条数据

24 int pageSize=10;25

26 try{27 Integer[] ids=HDFSUtils.getIdsByKeyword(keyword);28 //根据这些id查询相应的结果

29 List allNews=newsdao.findByIds(ids, (currentPage-1), pageSize);30

31 int count=newsdao.getAllCount(ids);32 //计算一个关键词读取的数据显示总页数

33 int allPages=count/pageSize;34 if(count%pageSize!=0){35 allPages++;36 }37

38 //结果传递回页面显示

39 mv.addObject("allNews",allNews);40 mv.addObject("allPages", allPages);41 mv.addObject("currentPage", currentPage);42

43 //切换到页面上

44 mv.setViewName("/result.jsp");45 }catch(Exception e){46 e.printStackTrace();47 }48

49 returnmv;50 }51

52 @Resource(name="newsDAOImpl")53 public voidsetNewsdao(INewsDAO newsdao){54 this.newsdao=newsdao;55

56 }57 }

9、过滤器解决乱码问题

测试时会有乱码出现,因此还要编写一个过滤器来处理乱码。

如果是MyEclipse的乱码问题,只需修改:

a4a9d1924cccc468dae951a5432c80d7.png

【1】过滤器代码呈现:

1 packageorg.liky.sina.filter;2 /**

3 * 过滤器,解决网页乱码的问题4 */

5 importjava.io.IOException;6

7 importjavax.servlet.Filter;8 importjavax.servlet.FilterChain;9 importjavax.servlet.FilterConfig;10 importjavax.servlet.ServletException;11 importjavax.servlet.ServletRequest;12 importjavax.servlet.ServletResponse;13

14 public class EncodingFilter implementsFilter {15

16 @Override17 public voiddestroy() {18 }19

20 @Override21 public voiddoFilter(ServletRequest arg0, ServletResponse arg1,22 FilterChain arg2) throwsIOException, ServletException {23 //修改编码格式为UTF-8

24 arg0.setCharacterEncoding("UTF-8");25 arg2.doFilter(arg0, arg1);26 }27

28 @Override29 public void init(FilterConfig arg0) throwsServletException {30 //TODO Auto-generated method stub

31

32 }33

34 }

【2】在web.xml中配置这个过滤器:

1

2 encoding

3 org.liky.sina.filter.EncodingFilter

4

5

6 encoding

7 /*8

10、结果显示

运行结果如下:

控制台显示:

49172f43241e45bb0029bccf0db4ee58.png

浏览器index.jsp显示:

edc96a4667282e2b342703e82f1287c8.png

搜索结果   result.jsp  显示,尾部实现了分页功能,并且还可以进行搜索:

598ed1dd39808f7ca0ee22250890e26e.png

11、总结

首先上一篇结尾存在的乱码问题在此处第九部分,给出了过滤器的方法,将编码格式改为UTF-8,已经解决了。

关于垂直搜索引擎,是针对某一个行业的专业搜索引擎(本次项目是对新浪新闻的数据收集,爬取深度为5),是搜索引擎的细分和延伸,是对网页库中的某类专门的信息进行一次整合,定向分字段抽取出需要的数据进行处理后再以某种形式返回给用户。

本篇用SpringMVC框架的技术完成数据的垂直搜索,相比来说,结构更加清晰,难点在于两个配置文件的修改,以及在代码中使用配置文件。

思路流程:

1、  DAO操作类根据首页搜索框关键词的输入,获取HDFS的id,以便从数据库提取一组信息;

2、  配置文件实现了数据库的连接,并简化了DAO的流程实现;

3、SpringMVC的控制器自动接收参数,并进行数据操作;

4、  JSP文件接收控制器传递的数据,呈现在结果页面。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值