最近想使用Compass+Spring +Lucene做全文搜索,在网上找了些代码,但是没有完整的。发现网上的东西都是一枝半解,在自己的机器上调试了一下,但没有成功,希望有识之士帮看一下。
错误如下:
java.lang.NullPointerException
sc.compass.CompassSearchService.search(CompassSearchService.java:48)
sc.util.action.SearchAction.s(SearchAction.java:115)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:585)
org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:280)
org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:216)
org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:484)
org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274)
org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482)
org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:507)
javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
由于本人对这几个类的代码很陌生,不知道问题出在哪里,原代码如下:
package sc.compass;
import org.compass.core.Compass;
import org.compass.core.CompassCallback;
import org.compass.core.CompassDetachedHits;
import org.compass.core.CompassException;
import org.compass.core.Compass;
import org.compass.core.CompassQuery;
import org.compass.core.CompassSession;
import org.compass.core.CompassTemplate;
import org.compass.core.CompassTransaction;
import org.compass.spring.web.mvc.CompassSearchCommand;
import org.compass.spring.web.mvc.CompassSearchResults;
import org.springframework.beans.factory.InitializingBean;
import sc.compass.AdvancedSearchCommand.CompassSort;
/**
* 仿照 {@link org.compass.spring.web.mvc.CompassSearchController}
* 中的代码,构建了一个Service,方便不使用Spring MVC
*
* @see org.compass.spring.web.mvc.CompassSearchController
* @see org.compass.spring.web.mvc.AbstractCompassCommandController
*/
public class CompassSearchService implements InitializingBean {
/**
* 每页显示的条目数量
*/
private Integer pageSize;
private Compass compass;
private CompassTemplate compassTemplate;
/**
* 公开的搜索接口,返回匹配的搜索结果,与
* {@link org.compass.spring.web.mvc.CompassSearchController#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, Object, org.springframework.validation.BindException)
* 处理相似
*
* @param command
* @return
* @see org.compass.spring.web.mvc.CompassSearchController#handle(javax.servlet.http.HttpServletRequest,
* javax.servlet.http.HttpServletResponse, java.lang.Object,
* org.springframework.validation.BindException)
*/
public CompassSearchResults search(final CompassSearchCommand command) {
CompassSearchResults searchResults = (CompassSearchResults) getCompassTemplate()
.execute(
CompassTransaction.TransactionIsolation.READ_ONLY_READ_COMMITTED,
new CompassCallback() {
public Object doInCompass(CompassSession session)
throws CompassException {
return performSearch(command, session);
}
});
return searchResults;
}
/**
* 通过此方法调用搜索引擎,进行结果匹配搜索
*
* @param searchCommand
* @param session
* @return
* @see org.compass.spring.web.mvc.CompassSearchController#performSearch(org.compass.spring.web.mvc.CompassSearchCommand,
* org.compass.core.CompassSession)
*/
protected CompassSearchResults performSearch(
CompassSearchCommand searchCommand, CompassSession session) {
if (AdvancedSearchCommand.class.isAssignableFrom(searchCommand
.getClass())) {
AdvancedSearchCommand advancedCommand = (AdvancedSearchCommand) searchCommand;
advancedCommand.setupQuery();
}
long time = System.currentTimeMillis();
CompassQuery query = buildQuery(searchCommand, session);
Compass hits = query.hits();
CompassDetachedHits detachedHits;
CompassSearchResults.Page[] pages = null;
if (pageSize == null) {
doProcessBeforeDetach(searchCommand, session, hits, -1, -1);
detachedHits = hits.detach();
} else {
int iPageSize = pageSize.intValue();
int page = 0;
int hitsLength = hits.getLength();
if (searchCommand.getPage() != null) {
page = searchCommand.getPage().intValue();
}
int from = page * iPageSize;
if (from > hits.getLength()) {
// 如果起始的条目大于搜索到的条目
from = hits.getLength() - iPageSize;
doProcessBeforeDetach(searchCommand, session, hits, from,
hitsLength);
detachedHits = hits.detach(from, hitsLength);
} else if ((from + iPageSize) > hitsLength) {
// 结束的条目大于搜索到的结果
doProcessBeforeDetach(searchCommand, session, hits, from,
hitsLength);
detachedHits = hits.detach(from, hitsLength);
} else {
// 中间的页码,直接取出相应的条目
doProcessBeforeDetach(searchCommand, session, hits, from,
iPageSize);
detachedHits = hits.detach(from, iPageSize);
}
doProcessAfterDetach(searchCommand, session, detachedHits);
int numberOfPages = (int) Math.ceil((float) hitsLength / iPageSize);
pages = new CompassSearchResults.Page[numberOfPages];
for (int i = 0; i < pages.length; i++) {
pages[i] = new CompassSearchResults.Page();
pages[i].setFrom(i * iPageSize + 1);
pages[i].setSize(iPageSize);
pages[i].setTo((i + 1) * iPageSize);
if (from >= (pages[i].getFrom() - 1) && from < pages[i].getTo()) {
pages[i].setSelected(true);
} else {
pages[i].setSelected(false);
}
}
if (numberOfPages > 0) {
CompassSearchResults.Page lastPage = pages[numberOfPages - 1];
if (lastPage.getTo() > hitsLength) {
lastPage.setSize(hitsLength - lastPage.getFrom());
lastPage.setTo(hitsLength);
}
}
}
time = System.currentTimeMillis() - time;
CompassSearchResults searchResults = new CompassSearchResults(
detachedHits.getHits(), time);
searchResults.setPages(pages);
return searchResults;
}
/**
* 构建Lucene 搜索器
*
* @param searchCommand
* @param session
* @return
*/
protected CompassQuery buildQuery(CompassSearchCommand searchCommand,
CompassSession session) {
CompassQuery query = session.queryBuilder().queryString(
searchCommand.getQuery().trim()).toQuery();
if (AdvancedSearchCommand.class.isAssignableFrom(searchCommand
.getClass())) {
AdvancedSearchCommand advancedSearchCommand = (AdvancedSearchCommand) searchCommand;
for (CompassSort sort : advancedSearchCommand.getSortMap()) {
query.addSort(sort.name, sort.type, sort.direction);
}
}
return query;
}
/**
* 在detach 之前,可以做一些操作。比如highlighting...
*
* @param searchCommand
* @param session
* @param hits
* @param from 需要注意的是,如果pageSize 没有指定,那么这里传入的参数为-1
* @param size
*/
protected void doProcessBeforeDetach(CompassSearchCommand searchCommand,
CompassSession session, Compass hits, int from, int size) {
}
/**
* An option to perform any type of processing before the hits are detached.
*/
protected void doProcessAfterDetach(CompassSearchCommand searchCommand,
CompassSession session, CompassDetachedHits hits) {
}
public void afterPropertiesSet() throws Exception {
if (compass == null) {
throw new IllegalArgumentException("Must set compass proerty");
}
this.compassTemplate = new CompassTemplate(compass);
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public void setCompass(Compass compass) {
this.compass = compass;
}
protected CompassTemplate getCompassTemplate() {
return this.compassTemplate;
}
}
Action如下:
public ActionForward s(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws Exception {
CompassSearchService aa = new CompassSearchService();
AdvancedSearchCommand ac = new AdvancedSearchCommand();
//String sm = request.getParameter("query");
ac.addSort("临床医学科研程序与方法", "String", true);
CompassSearchResults result = aa.search(ac);
for(int i=0;i Compas hits=result.getHits()[i];
Book book=(Book)hits.getData();
System.out.println(book.getSm());
System.out.println(book.getId());
}
//request.setAttribute("result", result);
return mapping.findForward("test");
}