閱讀730 返回首頁    go iPhone_iPad_Mac_apple


struts2實戰:全文搜索引擎

 轉載請注明出處:https://blog.csdn.net/zbf8441372
本文對自己開發的基於lucene和J2EE技術的搜索引擎開發經驗進行簡單總結。今後可能會從性能的角度總結lucene開發經驗。當數據上TB級別後,分布式lucene以及結合分布式文件係統(如HDFS)或NoSQL等問題應該會成為我的技術關鍵點。而本文主要介紹struts2.0的關鍵特性和實踐經驗。


1. struts如何獲得前台參數?

struts2通過struts.xml,使struts中的action或者intercepter與某一jsp對應

<package name="main" extends="struts-default">
       
       <global-results>
          <result name="search">/test.jsp</result>
        </global-results>
        
        <action name="DoSearch"  method="searchResult">
          	<result name="success">/search.jsp</result>
          	<result name="error">/nobook.jsp</result>
        </action>
    
   </package>  

最簡單的是前台可以是一個form表單。這個表單可以是用html的標簽寫,也可以是用struts的標簽寫。表達對應一個action,並傳回一個帶參數的url。

前台的url通過 ActionName?var1=xx&var2=yy 的形式傳給特定action如:

/DoSearch?sk=物理&type=title

這裏的ActionName會在struts.xml裏匹配,找到對應的action.java。

傳進去的參數,如sk和type,需要在action.java裏以同一名稱聲明,並設置getter, setter函數。區別於servlet通過request.getParameterName()的後台讀取前台參數方式,struts的getter和setter將完成這些步驟。


2. 前台如何讀取struts內容?

第一種:struts標簽傳。

<li>總共花費 <font color="red" ><s:text name="time"></s:text></font> ms, 找到 <font color="red" ><s:text name="count"></s:text></font>條記錄</li>

<s:iterator  value="booklist" >
作者:${BookAttributes.creator}   <br />
分類:${BookAttributes.CRC}  <br />
ISBN:${BookAttributes.ISBN}  <br />
出版日期:${BookAttributes.date}  <br />
  <!--  do something-->
</s:iterator>

以上兩種是常用的通過struts標簽來傳輸變量到前台的方式。但是,有時候無法滿足我們的需求。

比如:如何在一個iterator內,加入另一個遍曆?action的兩個list需要在一個遍曆內輸出結果,而且list裏每一個對象又是一個類。

我的解決方法是用request來處理。

有幾點要知道的是:

1. struts的變量是如何用標簽付到前台的?

是用setter函數,或者說本質上就是request來做的。

2. 標簽不是完全可以滿足action變量往前台輸送嗎?

不是的。這裏涉及到Java對象, Js對象, Action內的對象在同一個jsp頁麵內到底能怎樣互通。每個action對應唯一一個jsp,action的標簽按上麵第一個問題說的,本質上是reuqest根據setter函數來回傳的,同時,這個回傳標簽也可以賦給一個html標簽的value值:

<input  type=hidden value="<s:text name='sk'></s:text>" ></input>
(用hidden的原因是,這個是我藏起來讓js代碼去用的方式,可能比較蠢,但是很簡單好操作)

但是,struts標簽無法賦給js變量,無法賦給<% %>內的java變量,他永遠隻是個setter方法,當你的值是一個對象,比如一個List時,你這樣賦的結果,就是一個list.toString()的值,對象的屬性不能獲取,對象在標簽下就死掉了。有的人會說,那就用iterator啊。是的,但是我遇到的問題是iterator下,我需要得到兩個list的遍曆

所以我的方法是結合request,把action中第二個list變量讀給java,處理之後傳給需要的vaue。見下文。

第二種:用request。

一般可以用struts標簽傳就用struts標簽傳。因為那是struts的特性。這種request的方式是最原始的方式。

記得要在jsp聲明導入包

<%@page import="org.apache.struts2.ServletActionContext"%>
然後因為action隻唯一在一個jsp裏書寫,所以
request.getAttribute()

直接獲得值。

iterator下,我需要得到兩個list的遍曆的時候,我就在iterator之前,先聲明一個計數值

<% int i = 0; %>
<s:iterator  value="booklist" >

<%
    i ++;
%>

</s:iterator>

這樣就可以對action中任意多的list進行同時遍曆,並且java代碼來直接操作各種動作。

看個實例:

<%
	// 通過循環變量i和request,從action讀取list,用java處理成正確的url。struts標簽沒辦法做雙重循環,也取不了list內的類的某個變量
	List<BookAttributes> ba = (ArrayList<BookAttributes>)request.getAttribute("booklist");
	String cata1 = ba.get(i).getCRC().substring(0, 1);
	String cata2 = ba.get(i).getCRC().substring(0, 2);
	String cata3 = ba.get(i).getCRC().substring(0, 3);
	String url1 = "Classify.action?CateId=" + cata1;
	String url2 = "Classify.action?CateId=" + cata2;
	String url3 = "Classify.action?CateId=" + cata3;
	i ++;
 %>

<span id=m_fl><a  href=<%=url1%>>${BookAttributes.firstCat}</a>-><a  href=<%=url2%>>${BookAttributes.secondCat}</a>-><a  href=<%=url3%>>${BookAttributes.thirdCat}</a></span><br>


第三種:異步json取。

這種方法在下麵敘述。


3. struts2如何實現異步交互?

struts配置裏可以把action以json格式返回,不指定jsp頁麵。

<package name="test" extends="json-default">

        <action name="ShowAddup" >
        	<result type="json"></result>      
        </action>
        
        <action name="ShowBaidu" >
        	<result type="json"></result>      
        </action>

</package>  

同時,前台可以用Ajax或者Jquery封裝過的Ajax來提交url,並且在回調函數的data內獲得action裏所有的標量

下麵代碼演示了getJSON方法傳參並且通過DOM或者jquery等操作把回調函數內的data裏的相應變量寫到js的某些特定標簽內。這裏麵對於js,jquery的靈活操作和使用就不介紹了,例子中可以看到一些處理方式。

$.getJSON(
   		 url3 ,function(data,state){
   		 	var pagelist = data.pagelist;
   		 	var pagecontentlist = data.pagecontentlist;
   		 	
   		 	var num = pagecontentlist.length;
   		 	
   		 	$("#listbooks").hide();
   		 	//$("#pagecontent").innerHTML = '';
   		 	document.getElementById("pagecontent").innerHTML=" "; // 清空處理
   		 	document.getElementById("pagecontent").style.marginLeft="35px";
   		 	document.getElementById("pagecontent").style.marginRight="20px";
   		 	for (var i = 0; i < num; i ++) {
  		 		$("#pagecontent").append("<font color=blue style='font-size:13px;'><b>出現的書頁在: " + pagelist[i].substring(0,7) + "頁<b/></color>");
   		 		$("#pagecontent").append("<br/>");
   		 		if (pagecontentlist[i].length > 450) {
   		 			pagecontentlist[i] = pagecontentlist[i].substring(0, 450);
   		 			$("#pagecontent").append("<font color=Chocolate>該頁的內容為: </font><font color=darkgrey style='font-size:12px; letter-spacing:0px;'><br />" + pagecontentlist[i] + "</color> " );
   		 			$("#pagecontent").append("<font color=LightSkyBlue style='font-size:13px;'><b><u>more(閱讀全文)...</u></b></font> <br/> <br/>");
   		 			
   		 		} else {
   		 		
   		 		$("#pagecontent").append("<font color=lightblue>該頁的內容為: </font><font color=darkgrey style='font-size:12px; letter-spacing:0px;'><br />" + pagecontentlist[i] + "</color> <br/> <br/>" );
   		 			
   		 		}
   		 		yit(document.body, sk); // 再加亮下
   		 	} 
   		 }
   	, "json");

jquery是js的庫。提供一篇介紹比較清楚的文章, 你就可以很清楚了解到jquery可以為前台做什麼:Jquery學習筆記


上麵的

$.getJSON();

隻是一種,其他方法詳見:深入理解jQuery中$.get、$.post、$.getJSON和$.ajax的用法

異步方法,第一,帶來了更好的用戶體驗。第二,我在搜索的時候,form形式的直接傳遞隻能處理一個action,當我需要進行搜索的同時進行別的操作,比如對搜索結果進行統計的時候,我就不能把兩件事放在同一個action裏做,因為統計會延時搜索結果的輸出,搜索結果必定是ms內的事。這時候,就需要一個請求,對應多個action做。

當時在解決這個問題的時候,繞了很多彎路。簡單的說,action唯一對應一個書寫jsp,而jsp內可以有映射多個action,當然多個action可以指定寫在一個jsp裏。這個基本出發點一定要清晰。這樣的話,異步,同步的調用,返回的結果如何在前台顯示都可迎刃而解,具體各種方式我也在前麵說明了。



對struts,jquery,js,ajax的使用是一邊開發一邊學著用的,以上是我開發過程中總結的一些使用方式和注意點。struts的action同樣可以用spring的bean來管理,struts的intercepter也是一塊內容,我是沒有涉及到的。詳見:Struts2攔截器的使用 或者大家可以查別的資料。

對struts2.0的總體使用感覺是,代碼比servlet少很多,配置很靈活,各種標簽需要熟練掌握,比如上麵沒有提到,可以用這樣的方式來傳遞url給action:

<s:url id='url' action='Classify'>
	<s:param name="CateId" value="%{'N'}"></s:param>
</s:url>
	<s:a href="%{url}">自然科學總論</s:a>

<s:url id='url' action='Classify'>
	<s:param name="CateId" value="%{'O'}"></s:param>
</s:url>
<s:a href="%{url}">數理化</s:a>

 <s:url id='url' action='Classify'>
	<s:param name="CateId" value="%{'P'}"></s:param>
</s:url>
<s:a href="%{url}">天文、地球</s:a>

展示上的問題都克服了之後,再從性能的角度來分析lucene的使用。

最後再給一篇比較簡明易懂的文章:struts2+jquery+json集成



鑒於我拙劣的表達,附上上麵的幾份參考資料:

Jquery學習筆記

深入理解jQuery中$.get、$.post、$.getJSON和$.ajax的用法

Struts2攔截器的使用

struts2+jquery+json集成


最後更新:2017-04-02 17:09:25

  上一篇:go C語言處理圖像之改變背景前景顏色
  下一篇:go 模仿android網易新聞客戶端左右動畫效果