[lucene系列笔记3]用socket把lucene做成一个web服务

上一篇介绍了用lucene建立索引和搜索,但是那些都只是在本机上运行的,如果希望在服务器上做成web服务该怎么办呢?

一个有效的方法就是用socket通信,这样可以实现后端与前端的独立,也就是不管前端用什么(比如PHP)都可以Lucene只提供检索功能。

简单来说,socket就是实现不同的进程之间通讯的一个通道。socket由两部分组成:服务端和客户端。有两种:单进程和多进程。

所以认识socket的阶梯大概是这样的:

1.用java本地做服务端和客户端,实现不同程序之间的单进程通讯;

2.用java在web服务器做服务端,用java本地做客户端,实现不同机器之间的单进程通讯;

3.用java在web服务器做服务端,用PHP在服务器做客户端,实现外网通过PHP网页使用服务(单进程);

4.用java在web服务器做服务端,用PHP在服务器做客户端,实现外网通过PHP网页使用服务(多进程);

下面,这篇文章先介绍第一个:用java本地做服务端和客户端,实现不同程序之间的单进程通讯。

继续上一篇的LuceneTools工程,在里面new一个class命名为LocalSocketServer。

然后在里面加入如下代码(服务端):

import java.nio.file.Paths;
import java.io.*;
import java.net.*; import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.queryparser.classic.QueryParser;
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.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version; /**
* @author song
* @description:
* 依赖jar:Lucene-core,lucene-analyzers-common,lucene-queryparser
* 作用:使用索引搜索文件
*/
public class LocalSocketServer {
public static Version luceneVersion = Version.LATEST;
/**
* 查询内容
*/
public static String indexSearch(String keywords){
String res = "";
DirectoryReader reader = null;
try{
// 1、创建Directory
Directory directory = FSDirectory.open(Paths.get("D:/lucenetest/index"));//在硬盘上生成Directory
// 2、创建IndexReader
reader = DirectoryReader.open(directory);
// 3、根据IndexWriter创建IndexSearcher
IndexSearcher searcher = new IndexSearcher(reader);
// 4、创建搜索的query
// 创建parse用来确定搜索的内容,第二个参数表示搜索的域
QueryParser parser = new QueryParser("content",new StandardAnalyzer());//content表示搜索的域或者说字段
Query query = parser.parse(keywords);//被搜索的内容
// 5、根据Searcher返回TopDocs
TopDocs tds = searcher.search(query, 20);//查询20条记录
// 6、根据TopDocs获取ScoreDoc
ScoreDoc[] sds = tds.scoreDocs;
// 7、根据Searcher和ScoreDoc获取搜索到的document对象
int cou=0;
for(ScoreDoc sd:sds){
cou++;
Document d = searcher.doc(sd.doc);
// 8、根据document对象获取查询的字段值
/** 查询结果中content为空,是因为索引中没有存储content的内容,需要根据索引path和name从原文件中获取content**/
res+=cou+". "+d.get("path")+" "+d.get("name")+" "+d.get("content")+"\n";
} }catch(Exception e){
e.printStackTrace();
}finally{
//9、关闭reader
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return res+"hehehehe";
}
public static void main(String[] args) throws IOException
{
ServerSocket server=new ServerSocket(5678);
while (true)
{
Socket client=server.accept();
BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out=new PrintWriter(client.getOutputStream());
String str=in.readLine();
System.out.println(str);
out.println(indexSearch(str));
out.flush();
client.close();
}
}
}

我们就用上一篇做好的索引来提供服务。

然后客户端我们也用java。在工程里new一个class命名为LocalSocketClient。加入如下代码:

import java.net.*;
import java.io.*; public class LocalSocketClient
{
static Socket server;
public static void main(String[] args)throws Exception
{
//如果127.0.0.1不行可以换成InetAddress.getLocalHost()
server=new Socket("127.0.0.1",5678);
BufferedReader in=new BufferedReader(new InputStreamReader(server.getInputStream()));
PrintWriter out=new PrintWriter(server.getOutputStream());
BufferedReader wt=new BufferedReader(new InputStreamReader(System.in));
String str=wt.readLine();
out.println(str);
out.flush();
String res=in.readLine();
while (!res.equals("hehehehe"))
{
System.out.println(res);
res=in.readLine();
}
out.flush();
server.close();
}
}

然后先运行起服务端程序,然后跑起来以后再运行客户端程序,在客户端输入查询即可得到反馈结果。

至此,我们学会了单进程,本地socket+Lucene提供服务。(提示:由于上面的服务端程序设置的是无限循环,所以一定要手动结束程序!)

上一篇:(四)输入参数与输出类型为复杂类型的web服务


下一篇:So easy Webservice 6.使用EndPoint发布webservice服务