- 浏览: 11306 次
- 性别:
- 来自: 深圳
最近访客 更多访客>>
最新评论
-
zhaozhihang:
SearchModel 贴出来呗……
Struts 2 动态高级检索的实现 -
Admin86:
有2个朋友 1年8K 主要还是看能力和机遇吧 杭州的
深圳的javaer们,进来聊聊 -
weixiaozhe:
楼主牛阿,2年8K,
深圳的javaer们,进来聊聊 -
kewell543:
我倒是想知道为什么‘华为和腾讯算了’
深圳的javaer们,进来聊聊 -
starcheney:
目前,广大网友和深圳的企业纷纷表示压力很大!
深圳的javaer们,进来聊聊
这几天在写一个高级检索,因为项目的需要,贴出来分享一下:
其中主要的是对动态表单的值处理,拼接成检索语句:
代码如下:
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>>>信息资源库</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>>>主题信息</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+"> 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;
}
}
其中主要的是对动态表单的值处理,拼接成检索语句:
代码如下:
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>>>信息资源库</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>>>主题信息</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+"> 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;
}
}
相关推荐
在本项目中,开发者利用SSH2(即Struts2、Hibernate和Spring的组合)作为基础框架,并引入Compass来实现全文检索功能,以此提升应用程序的数据查询效率和用户体验。 Struts2 是一个基于MVC(模型-视图-控制器)设计...
Struts2是一个强大的Java Web框架,它为构建MVC(模型-视图-控制器)架构的应用程序提供了全面的支持。...在实际开发中,你还可以探索更高级的主题,如拦截器、结果类型、动态方法调用等,以提升应用的功能和性能。
Struts2是一个强大的MVC(模型-视图-控制器)框架,它被广泛应用于Java Web开发中,提供了结构化的开发模式,...通过不断地学习和实践,开发者可以进一步掌握Struts2的高级特性和最佳实践,提升开发效率和代码质量。
开发者可以通过Jquery美化和优化用户界面,通过Struts2处理用户请求,Spring管理和协调组件,而MyBatis则负责与数据库的交互,实现了完整的数据操作功能。通过这样的集成,开发者可以更专注于业务逻辑,而不是底层的...
Struts2是一个强大的Java web应用程序框架,用于构建和维护可扩展、高效且易于维护的Web应用。这个"struts2增删查改"项目显然旨在帮助初学者掌握...这个项目是一个理想的起点,为更高级的Struts2开发打下坚实基础。
Struts 2是MVC(模型-视图-控制器)架构的一种实现,用于构建Web应用程序。它提供了一种结构化的开发方式,将业务逻辑、数据处理和用户界面分离开来。Struts 2的核心功能包括动作映射、结果渲染、拦截器和插件等,...
7. **性能优化**:为了提高性能,开发者还可以利用Spring的缓存支持(如Hibernate的二级缓存)减少对数据库的访问,通过调整Struts 2和Hibernate的配置实现更高效的请求处理和数据检索。 8. **维护与扩展**:由于这...
第七章则聚焦于值栈和OGNL表达式,这是Struts2中非常重要的两个概念,涉及到数据的存储、检索和表达式的动态执行,对于构建灵活、动态的Web应用至关重要。 ### Struts2的Taglib和其他高级特性 第八章介绍了Struts2...
Struts2负责处理HTTP请求,调用Jdbc与MySQL数据库进行交互,存储和检索数据。系统可能有多个Action类,每个对应一个特定的业务功能,比如“AddStudentAction”用于添加学生,而“QueryGradeAction”则用于查询成绩。...
Struts2是一个强大的Java EE应用程序框架,主要用于构建MVC(模型-视图-控制器)架构的Web应用。...通过深入学习和实践,开发者可以进一步掌握Struts2的高级特性,如自定义拦截器、插件扩展等,从而提升开发技能。
Struts2作为MVC(Model-View-Controller)架构的一部分,负责控制应用程序流程,而Hibernate则提供数据库操作的支持,简化了数据访问层的实现。 【描述】"人工智能-项目实践-信息管理系统"表明这个系统可能应用了...
结合SQL Server数据库,Struts2能够创建数据驱动的动态网站。在这个“luntan.rar_Struts2+Sql”项目中,我们可以探讨以下几个关键知识点: 1. **Struts2框架**:Struts2是Apache软件基金会下的一个开源项目,它基于...
Struts2是一个强大的Java web应用程序框架,用于构建MVC(模型-视图-控制器)架构的应用。...同时,随着对Struts2框架的深入理解,可以进一步探索如拦截器、结果类型、OGNL表达式、插件扩展等高级特性。
5. **Struts2配置**:在实现Ajax查询功能时,需要在Struts2的配置文件(如struts.xml)中定义Action类,配置Action的执行方法,指定其接收的请求URL、返回的结果类型等。 6. **Ajax请求和响应处理**:前端需要使用...
Struts2、iBatis、Spring 和 Lucene 是四个在Java Web开发中广泛使用的开源框架。这个整合项目是将它们结合起来,以实现更高效、更灵活的Web应用程序开发。 Struts2 是一个基于MVC(Model-View-Controller)设计...
Struts2+Spring3+Hibernate3是Java开发中常见的企业级应用框架组合,被称为SSH框架。这个商城系统利用这三个框架的协同工作,构建了一个高效、稳定且功能丰富的平台。接下来,我们将深入探讨这些关键技术及其在商城...
在"struts2+spring2.5+hibernate3.26+compass2.1搜索引擎简单实现"这个项目中,首先你需要配置Struts2、Spring和Hibernate,确保它们能正常工作。这包括编写相应的配置文件(如struts.xml、spring-context.xml、...
在Struts2中,控制器类表现为普通的POJO(Plain Old Java Object),这一设计简化了控制器的实现复杂度,同时也增强了其可测试性和可维护性。为了在JSP页面中运用Struts2的标签库,必须通过taglib指令导入,例如: ``...
本文将深入解析如何实现Struts2、Spring与iBatis的整合,以及如何在项目中有效配置这些框架。 ### Struts2 + Spring + iBatis整合 #### Struts2简介 Struts2是Apache的一个开源Web框架,基于MVC设计模式。它提供...
Struts2的Action类可以实现这些功能,而视图通常由JSP或FreeMarker模板生成。数据库管理个人数据,可能使用Hibernate或MyBatis等ORM工具进行持久化操作。 **安全性考虑** Struts2框架在安全性方面有诸多潜在问题,...