Struts 2 动态高级检索的实现

    这几天在写一个高级检索,因为项目的需要,贴出来分享一下:

     其中主要的是对动态表单的值处理,拼接成检索语句:
  
     代码如下:

    package com.trs.xh.search.service.model;

import java.util.List;

public class SearchHelper {
private static String field;// 域对象
private static String text;// 对应的表单信息
private static String logic;// 与下一个字段的 "与 或 非"
private static boolean flag;// 精确 -- 模糊

static String LOGIC = "";// 标识上一个表单域与现在表单域的关系(与,或,非)

/**
* 拼接检索语句
*
* @param list
*            封装用户输入的表单域的list
* @return 拼接好的 检索语句
*/
public static String getSql(List<SearchModel> list) {

StringBuffer sb = new StringBuffer();

for (SearchModel s : list) {

field = s.getField();
text = s.getText();
logic = s.getLogic();
flag = s.getFlag();
// 如果用户该行没有输入,跳过
if (text == null || text.trim().length() == 0) {
continue;
}
text = text.trim();
// text不为空,用空格分隔之
String args[] = text.split(" ");
if (LOGIC.equals("not")) {
// 与上一组条件的关系为 "非"
for (int i = 0; i < args.length; i++) {
if (!args[i].equals("")) {
// 参数不为空,提交参数
if (flag) {
// flag 为 true 表示精确检索
if (i == 0) {
// 第一个
sb.append("and");
sb.append("(" + field + " !=");
sb.append("'" + args[i] + "'");
} else {

sb.append(" and " + field + " !=");
sb.append("'" + args[i] + "'");
}
} else {
// 模糊检索
if (i == 0) {
// 第一个
sb.append("and");
sb.append("(" + field + " !=");
sb.append("'%" + args[i] + "%'");
} else {

sb.append(" and " + field + " !=");
sb.append("'%" + args[i] + "%'");
}
}

}
}
sb.append(")");
LOGIC = logic;// 与下一个字段的 关系
} else {
// LOGIC 标记 不是 not(非)
// 空格之间的关系为 "或" 条件为 "="(等于)
for (int i = 0; i < args.length; i++) {
if (!args[i].equals("")) {
// 参数不为空,提交参数
if (flag) {
// flag 为 true 表示精确检索
if (i == 0) {
// 第一个
sb.append(LOGIC);
sb.append("(" + field + " =");
sb.append("'" + args[i] + "'");
} else {

sb.append(" or " + field + " =");
sb.append("'" + args[i] + "'");
}
} else {
// 模糊检索
if (i == 0) {
// 第一个
sb.append(LOGIC);
sb.append("(" + field + " =");
sb.append("'%" + args[i] + "%'");
} else {
sb.append(" or " + field + " =");
sb.append("'%" + args[i] + "%'");
}
}

}
}
sb.append(")");
LOGIC = logic;// 与下一个字段的 关系
}

}
return sb.toString();
}

}


JSP 页面代码:


<%@ page contentType="text/html; charset=UTF-8"%>
<%@ include file="/WEB-INF/jsp/include/tags.jsp"%>
<!---->
<!--

-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>检索</title>
<style type="text/css" src="css/index.css" ></style>
<script src="js/jquery-1.3.2.min.js" type="text/javascript"></script>
</head>
<body>
<form action="" name="searchForm" id="searchForm" >
  <div id="xinxiziyuanku">
<p>&gt;&gt;信息资源库</p>
<input type="checkbox" id="dbnames" name="dbnames"  value="qikanlunwenku" checked="checked" />期刊论文库
<input type="checkbox" id="dbnames" name="dbnames" value="huiyilunwenku" checked="checked" />会议论文库
<input type="checkbox" id="dbnames" name="dbnames" value="xueweilunwenku" checked="checked" />学位论文库
<br/>
<input type="checkbox" id="dbnames" name="dbnames" value="tushuziliaoku" checked="checked" />图书资料库
<input type="checkbox" id="dbnames" name="dbnames" value="zhengcefaguiku" checked="checked" />政策法规库
<input type="checkbox" id="dbnames" name="dbnames"  value="zhengcefagui_tongjixinxiku" checked="checked" />政策法规、统计信息库
<br/>
<input type="checkbox" id="dbnames" name="dbnames" value="zhuanjiaxinxiku" checked="checked" />专家信息库
<input type="checkbox" id="dbnames" name="dbnames" value="jigouxinxiku" checked="checked" />机构信息库
<input type="checkbox" id="dbnames" name="dbnames" value="jigouzhishiku" checked="checked" />机构知识库
<br/>
<input type="checkbox" id="dbnames" name="dbnames" value="yanjiubaogaoku" checked="checked" />
研究报告库

<input type="button" value="全选" id="selectAll" />
<input type="button" value="反选" id="selectOther" />

</div>
  <!--xinxiziyuanku-->
<div id="zhutixinxi">
<p>&gt;&gt;主题信息</p>
<!--动态添加条件模板-->
<div id="conditionTemplate" style="display:none;">
<div>
<a href="#" class="addCondition">[+]</a> <a href="#" class="removeCondition">[-]</a>
<select id="cindex" name="cindex">
<option value="cn_title" selected="selected">题名</option>
<option value="cn_keyword">关键词</option>
<option value="cn_journey_name" >刊名</option>
<option value="cn_abstract">摘要</option>
</select>
<input type="text" id="tindex" name="tindex" />
<select id="flagindex" name="flagindex">
<option value="no" selected="selected">模糊查询</option>
<option value="yes">精确查询</option>
</select>
<select id="logicindex" name="logicindex">
<option value="and" selected="selected">与</option>
<option value="or">或</option>
<option value="not" >非</option>
</select>
</div>
</div>

<div>
<a href="#" class="addCondition">[+]</a> [-]
<select id="c1" name="c1">
<option value="cn_title" selected="selected">题名</option>
<option value="cn_keyword">关键词</option>
<option value="cn_journey_name" >刊名</option>
<option value="cn_abstract">摘要</option>
</select>
<input type="text" id="t1" name="t1" />
<select id="flag1" name="flag1">
<option value="no" selected="selected">模糊查询</option>
<option value="yes">精确查询</option>
</select>
<select id="logic1" name="logic1">
<option value="and" selected="selected">与</option>
<option value="or">或</option>
<option value="not" >非</option>
</select>
</div>
<div>
<a href="#" class="addCondition">[+]</a> <a href="#" class="removeCondition">[-]</a>
<select id="c2" name="c2">
<option value="cn_title" >题名</option>
<option value="cn_keyword" selected="selected">关键词</option>
<option value="cn_journey_name" >刊名</option>
<option value="cn_abstract">摘要</option>
</select>
<input type="text" id="t2" name="t2" />
<select id="flag2" name="flag2">
<option value="no" selected="selected">模糊查询</option>
<option value="yes">精确查询</option>
</select>
<select id="logic2" name="logic2">
<option value="and" selected="selected">与</option>
<option value="or">或</option>
<option value="not" >非</option>
</select>

</div>
<div>
<a href="#" class="addCondition">[+]</a> <a href="#" class="removeCondition">[-]</a>
<select id="c3" name="c3">
<option value="cn_title" >题名</option>
<option value="cn_keyword">关键词</option>
<option value="cn_journey_name" selected="selected">刊名</option>
<option value="cn_abstract">摘要</option>
</select>
<input type="text" id="t3" name="t3" />
<select id="flag3" name="flag3">
<option value="no" selected="selected">模糊查询</option>
<option value="yes">精确查询</option>
</select>
<select id="logic3" name="logic3">
<option value="and" selected="selected">与</option>
<option value="or">或</option>
<option value="not" >非</option>
</select>
</div>
<div>
<a href="#" class="addCondition">[+]</a> <a href="#" class="removeCondition">[-]</a>
<select id="c4" name="c4">
<option value="cn_title" >题名</option>
<option value="cn_keyword">关键词</option>
<option value="cn_journey_name" >刊名</option>
<option value="cn_abstract" selected="selected">摘要</option>
</select>
<input type="text" id="t4"  name="t4"/>
<select id="flag4" name="flag4">
<option value="no" selected="selected">模糊查询</option>
<option value="yes">精确查询</option>
</select>
<select id="logic4" name="logic4">
<option value="and" selected="selected">与</option>
<option value="or">或</option>
<option value="not" >非<br /><br /></option>
</select>
</div>

</div><!--zhutixinxi-->
<p>
<input type="button" value="检索"  id="trsSearch" onclick="getSearchResult()" /><!--AJAX调用检索函数-->
<input type="reset" value="重置" />
<input type="hidden" id="cCount" name="cCount" value="4" /> <!--查询条件总数-->
<input type="hidden" id="lc" name="lc" value="" /><!--授权号-->
<input type="hidden" id="orderBy" name="orderBy" value="" /> <!--排序方式-->
</p>


<div id="showPage" style="display:none;"  >  <!--默认设置为不可见,搜索时显示-->
        <span id="pageInfo">
        </span>
        <br/>
         每页显示记录数:
<input type="text" id="ps" name="ps" size="5"  value="20" />
         跳转到第
<input type="text" id="pn" name="pn" size="5" value="" />页<input type="button" value="GO" onclick="getSearchResult()" /> 


<div style="position:relative; height:20px; width:50px;">
<div id="load" style="left: 0px; position: absolute; top:100px;">
<img src="images/loading.gif"></img>
</div>
</div>
<table style="display: none" ><!--模板内容  -->
<tr id="template" >
<td id="list_title">
<br /><br /></td>
<td id="list_abstract">
<br /><br /></td>
<td id="list_content">
<br /><br /></td>
<td id="list_date">
<br /><br /></td>
<td id="list_detail">
<br /><br /></td>
</tr>
</table>
<table id="listSearchResult"  border="1" cellspacing="0">
<thead>
<tr>
<th>
标题
<br /><br /></th>
<th>
摘要
<br /><br /></th>
<th>
内容
<br /><br /></th>
<th>
日期
<br /><br /></th>
<th><br />详细信息
<br /><br /><br /></th>
</tr>
</thead>
<tbody id="datas">
</tbody>
</table>
<div id="errorMessage"></div>
    </div>    <!--showPage-->
</form>
</body>
</html>



<script type="text/javascript">
function getSearchResult(){
$("#showPage").show(); //显示搜索结果
//$("#datas").fadeOut("slow"); //将上回搜索结果淡出
$("#load").show(); //AJAX请求前显示loading
$("#errorMessage").html(""); //清除错误提示信息
var params=$('form').serialize(); //序列化表单的值
//alert(params); //********调试,查看传递的参数值*******
$.ajax({
            type:"post", //使用post方法访问后台
            dataType:"json", //返回json格式的数据
            url:"qklwSearch.action", //要访问的后台地址
            data:params, //要发送的数据,从表单中提取,存在params中
            //complete:function(){$("#load").hide();}, //AJAX请求完成时隐藏loading提示
            success: function(msg){ //msg为返回的数据,在这里做数据绑定
$("#load").hide(); //AJAX请求完成时隐藏loading
var Results = msg.Results;
                var data = Results.items;
                if(data!=null && data.length>0){
                $("#datas").html(""); //将datas标签里的内容清理掉 
                $.each(data, function(i, n){               
                    var row = $("#template").clone();
                    row.find("#list_title").text(n.title);
                    row.find("#list_abstract").text(n.contentAbstract);
                    row.find("#list_content").text(n.content);
                    row.find("#list_date").text(n.pubDate);
                   // if(n.发货日期!== undefined) row.find("#ShippedDate").text(ChangeDate(n.发货日期));
                    row.find("#list_detail").text(n.description);
                   // row.find("#more").html("<a href=OrderInfo.aspx?id=" + n.订单ID + "&pageindex="+pageIndex+">&nbsp;More</a>");                   // row.attr("id","ready");//改变绑定好数据的行的id
                    row.appendTo("#datas"); //添加到模板的容器中   
                });
$("#datas").fadeIn("fast"); //将搜索结果淡入

//添加分页信息
//row.find("#preView").click(getSearchResult(currPage-1,cn_title,)); 
//范例:$("p").click( function () { $(this).hide(); });
//row.appendTo("#pageInfo"); //添加到分页栏
var currentPage = Results.pageNumber;  //获取json中的当前页
var pageSize = Results.pageSize; //获取json中的每页显示数
var licenseCode = Results.licenseCode; //授权号
var totalCount = Results.totalCount; //记录总数
var pageCount = Math.floor((totalCount+pageSize-1)/pageSize); //计算总页数
//var lastPage = pageCount;
//var recCount = msg.result.flipInfo.recCount; //获取json数据中的总记录数
//var prePage = msg.result.flipInfo.previousPageNum; //前一页
//var nextPage = msg.result.flipInfo.nextPageNum; //下一页
var pageInfo = ""; //页码信息
pageInfo += "  共<span id='recCount'>" + totalCount + "</span>条记录";
pageInfo += "  共<span id='pageCount'>" + pageCount + "</span>页";
pageInfo += "  当前第<span id='currentPage'>" + currentPage + "</span>页";
//<span id="firstPage"> 首页 </span> <span id="prePage"> 上一页 </span>  <span id="nextPage"> 下一页 </span>   <span id="lastPage"> 尾页 </span>
if(currentPage>1) {
//$("#firstPage").click( function(){ $("#pageNumber").attr("value",1);getSearchResult();return; } );   //给首页添加点击事件
//$("#prePage").click( function(){ $("#pageNumber").attr("value",prePage);getSearchResult();return; } );   //给首页添加点击事件
pageInfo += " <a href='#pageInfo' id='firstPage' style='cursor:hand;' onClick='gotoPage(1)'>首页</a> ";
pageInfo += " <a href='#pageInfo' id='prePage' style='cursor:hand;' onClick='gotoPage(" + currentPage-1 + ")'>上一页</a> ";
}

//下面为分页代码V1.1
if(currentPage>1){
for(var i=currentPage-10;i<currentPage;i++){
if(i>0){
pageInfo += "  <a href='#pageInfo' id='gotoPage" + i + "' onClick='gotoPage(" + i + ")'>[" + i + "]</a>  ";
}
}
}
pageInfo += " " + currentPage + " ";
for( var i=currentPage+1;(i <= currentPage+9)&&(i<=pageCount);i++){
    pageInfo += "  <a href='#pageInfo' id='gotoPage" + i + "' onClick='gotoPage(" + i + ")'>[" + i + "]</a>  ";
}

if(currentPage<lastPage){
//$("#nextPage").click( function(){ $("#pageNumber").attr("value",nextPage);getSearchResult();return; } ); //给下一页添加点击事件
//$("#lastPage").click( function(){ $("#pageNumber").attr("value",lastPage);getSearchResult();return; } );
//pageInfo += "<span id='firstPage' onClick='pageSplit(1)'> 首页 </span>";
pageInfo += " <a href='#pageInfo' id='nextPage' style='cursor:hand;' onClick='gotoPage(" + currentPage+1 + ")'>下一页</a> ";
pageInfo += " <a href='#pageInfo' id='lastPage' style='cursor:hand;' onClick='gotoPage(" + pageCount + ")'>尾 页</a> ";
}
$("#pageInfo").html(pageInfo); //加载页码信息
}else{ //如果没有结果
$("#pageInfo").html(""); //隐藏页码信息
$("#errorMessage").html("您好!没有检索结果。试试调整检索条件^_^");

}

}//end of success函数
});


//分页函数
function gotoPage(i){
$("#pn").attr("value",i);getSearchResult();
}              
</script>

<script type = "text/javascript">
//全选反选代码
$(document).ready(function() {
     $("#selectAll").click( function() {
         $(":checkbox").each( function() { $(this).attr("checked","true"); })
     });
     $("#selectOther").click( function() {
         $(":checkbox").each( function() { $(this).attr("checked",!this.checked); })
     });
});
</script>


<script type="text/javascript">
//动态条件
//载入时给添加删除按钮绑定添加删除事件
$(document).ready(
function()
{
$(".addCondition").bind('click', addConditionFun); //给增加按钮绑定 增加事件
$(".removeCondition").bind('click', removeConditionFun); //给删除按钮绑定 删除事件
$("select:last").hide(); //隐藏最后一个select选择表单(与或非)
}
);
//删除条件函数
var removeConditionFun = function()
{
$(this.parentNode).remove();
$("select").show(); //显示被隐藏的表单
$("select:last").hide(); //隐藏最后一个select选择表单(与或非)
return false;

}
//增加条件函数
var addConditionFun = function()
{
var cCount =eval($("#cCount").attr("value")); //取得cCount条件总数值 并从String 类型转化为Number类型
cCount++;
$("#cCount").attr("value",cCount); //设置得cCount条件总数值加1
//alert(typeof(cCount)+ ':' + cCount);
var newCondition = $("#conditionTemplate").clone(); //拷贝条件模板
var cCountStr = cCount+"";
//alert(typeof(cCountStr));
var newConditionStr = newCondition.html().replace(new RegExp("index",'g'),cCountStr);//构造正则表达式,替换掉条件中的index为实际的数字
//alert(newConditionStr);
$('#zhutixinxi').append(newConditionStr);
$(".removeCondition").bind('click', removeConditionFun); //给新加的删除按钮绑定 删除事件
$(".addCondition").bind('click', addConditionFun); //给新加的增加按钮绑定 增加事件
$("select").show(); //显示被隐藏的表单
$("select:last").hide(); //隐藏最后一个select选择表单(与或非)
}
</script>


  对应的Action :

package com.trs.xh.search.action;

import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.ServletActionContext;
import org.hibernate.hql.ast.tree.Case2Node;
import org.springframework.beans.factory.annotation.Autowired;
import com.googlecode.jsonplugin.annotations.JSON;
import com.opensymphony.xwork2.Action;
import com.trs.xh.exception.XHException;
import com.trs.xh.search.common.PageInfo;
import com.trs.xh.search.common.Results;
import com.trs.xh.search.service.QikanSearchManager;
import com.trs.xh.search.service.SearchManager;
import com.trs.xh.search.service.model.SearchHelper;
import com.trs.xh.search.service.model.SearchModel;
import com.trs.xh.search.service.model.SimpleQKLW;

public class FullSearchAction {

private String pn;
private String ps;
private String cCount;
private Results result;

@Autowired
private QikanSearchManager qklwManager;

@Autowired
private SearchManager searchManager;

/**
* 加载检索S
*
* @return
* @throws XHException
*/
public String execute() throws XHException {

return "input";
}

/**
* 执行检索
*
* @return
* @throws XHException
*/
@SuppressWarnings("unused")
public String search() throws XHException {
// 得到分页信息

// 1,简单检索测试

// SimpleQKLW s = new SimpleQKLW(field1, text1, field2, text2, field3,
// text3, field4, text4);
//
// // 设置分页的页面属性
// int pageNo2 = 0;
// int pageSize2 = 10;
// try {
// pageNo2 = Integer.parseInt(pageNumber) - 1;
// pageSize2 = Integer.parseInt(pageSize);
// } catch (Exception e) {
// }
// Page p = new Page(pageNo2, pageSize2);
// result = qklwManager.searchSimple(s, p);
// int pageCount = result.getFlipInfo().getPageCount();
// // 如果用户输入的页数大于实际的总页数,显示最后一页
//
// if (pageNo2 > pageCount - 1) {
// pageNo2 = pageCount - 1;
// p = new Page(pageNo2, pageSize2);
// result = qklwManager.searchSimple(s, p);
// }

// 2,高级检索测试,带条件的('与','或','非');
/*
* AdvanceQKLW a = new AdvanceQKLW(); // 手动添加测试数据
* a.setFiled11("cn_titile");// 标题 a.setText10("aaa");
* a.setType12("not"); a.setFiled21("cn_keyword");// 中文关键字
* a.setText20("bbb"); a.setType22("and");
* a.setFiled31("cn_abstract");// 中文摘要 a.setText30("aaa");
* a.setType32("or"); //设置分页的页面属性 Page p = new Page(); // ....省略 result =
* qklwManager.searchAdvance(a,p);
*/

HttpServletRequest requst = ServletActionContext.getRequest();
// 定义封装 用户输入的表单域 的list
List<SearchModel> list = new LinkedList<SearchModel>();

for (int i = 1; i < Integer.parseInt(cCount) + 1; i++) {
SearchModel s = new SearchModel();
if (requst.getParameter("t" + i) == null) {
// 该行用户没输入,跳过
continue;
}
s.setField(requst.getParameter("c" + i));
s.setText(requst.getParameter("t" + i));
s.setLogic(requst.getParameter("logic" + i));
if (requst.getParameter("flag" + i).equals("yes")) {
s.setFlag(true);
} else {
s.setFlag(false);
}

list.add(s);
}

System.out.println("检索语句为:  " + SearchHelper.getSql(list));
// int pageNo2 = 0;
// int pageSize2 = 10;
// try {
// pageNo2 = Integer.parseInt(pageNumber) - 1;
// pageSize2 = Integer.parseInt(pageSize);
// } catch (Exception ex) {
// }
// PageInfo p = new PageInfo(pageNo2, pageSize2);
// result = searchManager.searchByDBs("", list, p);
// int pageCount = result.getFlipInfo().getPageCount();
// // 如果用户输入的页数大于实际的总页数,显示最后一页
//
// if (pageNo2 > pageCount - 1) {
// pageNo2 = pageCount - 1;
// p = new Page(pageNo2, pageSize2);
// result = searchManager.searchByDBs("", list, p);
// }
return Action.SUCCESS;

}

public Results getResult() {
return result;
}

public void setResult(Results result) {
this.result = result;
}

@JSON(serialize = false)
// 设置该属性不被序列化
public String getPn() {
return pn;
}

public void setPn(String pn) {
this.pn = pn;
}

@JSON(serialize = false)
// 设置该属性不被序列化
public String getPs() {
return ps;
}

public void setPs(String ps) {
this.ps = ps;
}

@JSON(serialize = false)
// 设置该属性不被序列化
public String getCCount() {
return cCount;
}

public void setCCount(String count) {
cCount = count;
}

}

你可能感兴趣的:(json,jsp,Ajax,正则表达式,struts)