本文对自己开发的基于lucene和J2EE技术的搜索引擎开发经验进行简单总结。今后可能会从性能的角度总结lucene开发经验。当数据上TB级别后,分布式lucene以及结合分布式文件系统(如HDFS)或NoSQL等问题应该会成为我的技术关键点。而本文主要介绍struts2.0的关键特性和实践经验。

1. struts如何获得前台参数?

本文对自己开发的基于lucene和J2EE技术的搜索引擎开发经验进行简单总结。今后可能会从性能的角度总结lucene开发经验。当数据上TB级别后,分布式lucene以及结合分布式文件系统(如HDFS)或NoSQL等问题应该会成为我的技术关键点。而本文主要介绍struts2.0的关键特性和实践经验。

1. struts如何获得前台参数?

struts2通过struts.xml,使struts中的action或者intercepter与某一jsp对应

  1. <package name="main" extends="struts-default">
  2. <global-results>
  3. <result name="search">/test.jsp</result>
  4. </global-results>
  5. <action name="DoSearch" class="action.searchAciton" method="searchResult">
  6. <result name="success">/search.jsp</result>
  7. <result name="error">/nobook.jsp</result>
  8. </action>
  9. </package>

最简单的是前台可以是一个form表单。这个表单可以是用html的标签写,也可以是用struts的标签写。表达对应一个action,并传回一个带参数的url。

前台的url通过 ActionName?var1=xx&var2=yy 的形式传给特定action如:

  1. /DoSearch?sk=物理&type=title

这里的ActionName会在struts.xml里匹配,找到对应的action.Java

传进去的参数,如sk和type,需要在action.java里以同一名称声明,并设置getter, setter函数。区别于servlet通过request.getParameterName()的后台读取前台参数方式,struts的getter和setter将完成这些步骤。

2. 前台如何读取struts内容?

第一种:struts标签传。

  1. <li>总共花费 <font color="red" ><s:text name="time"></s:text></font> ms, 找到 <font color="red" ><s:text name="count"></s:text></font>条记录</li>
  1. <s:iterator id="BookAttributes" value="booklist" >
  2. 作者:${BookAttributes.creator}   <br />
  3. 分类:${BookAttributes.CRC}  <br />
  4. ISBN:${BookAttributes.ISBN}  <br />
  5. 出版日期:${BookAttributes.date}  <br />
  6. <!--  do something-->
  7. </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值:

  1. <input id="js" 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声明导入包

  1. <%@page import="org.apache.struts2.ServletActionContext"%>

然后因为action只唯一在一个jsp里书写,所以

  1. request.getAttribute()

直接获得值。

iterator下,我需要得到两个list的遍历的时候,我就在iterator之前,先声明一个计数值

  1. <% int i = 0; %>
  2. <s:iterator id="BookAttributes" value="booklist" >
  3. <%
  4. i ++;
  5. %>
  6. </s:iterator>

这样就可以对action中任意多的list进行同时遍历,并且java代码来直接操作各种动作。

看个实例:

  1. <%
  2. // 通过循环变量i和request,从action读取list,用java处理成正确的url。struts标签没办法做双重循环,也取不了list内的类的某个变量
  3. List<BookAttributes> ba = (ArrayList<BookAttributes>)request.getAttribute("booklist");
  4. String cata1 = ba.get(i).getCRC().substring(0, 1);
  5. String cata2 = ba.get(i).getCRC().substring(0, 2);
  6. String cata3 = ba.get(i).getCRC().substring(0, 3);
  7. String url1 = "Classify.action?CateId=" + cata1;
  8. String url2 = "Classify.action?CateId=" + cata2;
  9. String url3 = "Classify.action?CateId=" + cata3;
  10. i ++;
  11. %>
  12. <span id=m_fl><a class="l" href=<%=url1%>>${BookAttributes.firstCat}</a>-><a class="l" href=<%=url2%>>${BookAttributes.secondCat}</a>-><a class="l" href=<%=url3%>>${BookAttributes.thirdCat}</a></span><br>

第三种:异步json取。

这种方法在下面叙述。

3. struts2如何实现异步交互?

struts配置里可以把action以json格式返回,不指定jsp页面。

  1. <package name="test" extends="json-default">
  2. <action name="ShowAddup" class="action.addupAction">
  3. <result type="json"></result>
  4. </action>
  5. <action name="ShowBaidu" class="action.baiduAction">
  6. <result type="json"></result>
  7. </action>
  8. </package>

同时,前台可以用Ajax或者jQuery封装过的Ajax来提交url,并且在回调函数的data内获得action里所有的标量

下面代码演示了getJSON方法传参并且通过DOM或者jquery等操作把回调函数内的data里的相应变量写到js的某些特定标签内。这里面对于js,jquery的灵活操作和使用就不介绍了,例子中可以看到一些处理方式。

  1. $.getJSON(
  2. url3 ,function(data,state){
  3. var pagelist = data.pagelist;
  4. var pagecontentlist = data.pagecontentlist;
  5. var num = pagecontentlist.length;
  6. $("#listbooks").hide();
  7. //$("#pagecontent").innerHTML = '';
  8. document.getElementById("pagecontent").innerHTML=" "; // 清空处理
  9. document.getElementById("pagecontent").style.marginLeft="35px";
  10. document.getElementById("pagecontent").style.marginRight="20px";
  11. for (var i = 0; i < num; i ++) {
  12. $("#pagecontent").append("<font color=blue style='font-size:13px;'><b>出现的书页在: " + pagelist[i].substring(0,7) + "页<b/></color>");
  13. $("#pagecontent").append("<br/>");
  14. if (pagecontentlist[i].length > 450) {
  15. pagecontentlist[i] = pagecontentlist[i].substring(0, 450);
  16. $("#pagecontent").append("<font color=Chocolate>该页的内容为: </font><font color=darkgrey style='font-size:12px; letter-spacing:0px;'><br />" + pagecontentlist[i] + "</color> " );
  17. $("#pagecontent").append("<font color=LightSkyBlue style='font-size:13px;'><b><u>more(阅读全文)...</u></b></font> <br/> <br/>");
  18. } else {
  19. $("#pagecontent").append("<font color=lightblue>该页的内容为: </font><font color=darkgrey style='font-size:12px; letter-spacing:0px;'><br />" + pagecontentlist[i] + "</color> <br/> <br/>" );
  20. }
  21. yit(document.body, sk); // 再加亮下
  22. }
  23. }
  24. , "json");

jquery是js的库。提供一篇介绍比较清楚的文章, 你就可以很清楚了解到jquery可以为前台做什么:Jquery学习笔记

上面的

  1. $.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:

  1. <s:url id='url' action='Classify'>
  2. <s:param name="CateId" value="%{'N'}"></s:param>
  3. </s:url>
  4. <s:a href="%{url}">自然科学总论</s:a>
  5. <s:url id='url' action='Classify'>
  6. <s:param name="CateId" value="%{'O'}"></s:param>
  7. </s:url>
  8. <s:a href="%{url}">数理化</s:a>
  9. <s:url id='url' action='Classify'>
  10. <s:param name="CateId" value="%{'P'}"></s:param>
  11. </s:url>
  12. <s:a href="%{url}">天文、地球</s:a>

展示上的问题都克服了之后,再从性能的角度来分析lucene的使用。

最后再给一篇比较简明易懂的文章:struts2+jquery+json集成

鉴于我拙劣的表达,附上上面的几份参考资料:

Jquery学习笔记

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

Struts2拦截器的使用

struts2+jquery+json集成

  1. <package name="main" extends="struts-default">
  2. <global-results>
  3. <result name="search">/test.jsp</result>
  4. </global-results>
  5. <action name="DoSearch" class="action.searchAciton" method="searchResult">
  6. <result name="success">/search.jsp</result>
  7. <result name="error">/nobook.jsp</result>
  8. </action>
  9. </package>

最简单的是前台可以是一个form表单。这个表单可以是用html的标签写,也可以是用struts的标签写。表达对应一个action,并传回一个带参数的url。

前台的url通过 ActionName?var1=xx&var2=yy 的形式传给特定action如:

  1. /DoSearch?sk=物理&type=title

这里的ActionName会在struts.xml里匹配,找到对应的action.Java

传进去的参数,如sk和type,需要在action.java里以同一名称声明,并设置getter, setter函数。区别于servlet通过request.getParameterName()的后台读取前台参数方式,struts的getter和setter将完成这些步骤。

2. 前台如何读取struts内容?

第一种:struts标签传。

  1. <li>总共花费 <font color="red" ><s:text name="time"></s:text></font> ms, 找到 <font color="red" ><s:text name="count"></s:text></font>条记录</li>
  1. <s:iterator id="BookAttributes" value="booklist" >
  2. 作者:${BookAttributes.creator}   <br />
  3. 分类:${BookAttributes.CRC}  <br />
  4. ISBN:${BookAttributes.ISBN}  <br />
  5. 出版日期:${BookAttributes.date}  <br />
  6. <!--  do something-->
  7. </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值:

  1. <input id="js" 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声明导入包

  1. <%@page import="org.apache.struts2.ServletActionContext"%>

然后因为action只唯一在一个jsp里书写,所以

  1. request.getAttribute()

直接获得值。

iterator下,我需要得到两个list的遍历的时候,我就在iterator之前,先声明一个计数值

  1. <% int i = 0; %>
  2. <s:iterator id="BookAttributes" value="booklist" >
  3. <%
  4. i ++;
  5. %>
  6. </s:iterator>

这样就可以对action中任意多的list进行同时遍历,并且java代码来直接操作各种动作。

看个实例:

  1. <%
  2. // 通过循环变量i和request,从action读取list,用java处理成正确的url。struts标签没办法做双重循环,也取不了list内的类的某个变量
  3. List<BookAttributes> ba = (ArrayList<BookAttributes>)request.getAttribute("booklist");
  4. String cata1 = ba.get(i).getCRC().substring(0, 1);
  5. String cata2 = ba.get(i).getCRC().substring(0, 2);
  6. String cata3 = ba.get(i).getCRC().substring(0, 3);
  7. String url1 = "Classify.action?CateId=" + cata1;
  8. String url2 = "Classify.action?CateId=" + cata2;
  9. String url3 = "Classify.action?CateId=" + cata3;
  10. i ++;
  11. %>
  12. <span id=m_fl><a class="l" href=<%=url1%>>${BookAttributes.firstCat}</a>-><a class="l" href=<%=url2%>>${BookAttributes.secondCat}</a>-><a class="l" href=<%=url3%>>${BookAttributes.thirdCat}</a></span><br>

第三种:异步json取。

这种方法在下面叙述。

3. struts2如何实现异步交互?

struts配置里可以把action以json格式返回,不指定jsp页面。

  1. <package name="test" extends="json-default">
  2. <action name="ShowAddup" class="action.addupAction">
  3. <result type="json"></result>
  4. </action>
  5. <action name="ShowBaidu" class="action.baiduAction">
  6. <result type="json"></result>
  7. </action>
  8. </package>

同时,前台可以用Ajax或者jQuery封装过的Ajax来提交url,并且在回调函数的data内获得action里所有的标量

下面代码演示了getJSON方法传参并且通过DOM或者jquery等操作把回调函数内的data里的相应变量写到js的某些特定标签内。这里面对于js,jquery的灵活操作和使用就不介绍了,例子中可以看到一些处理方式。

  1. $.getJSON(
  2. url3 ,function(data,state){
  3. var pagelist = data.pagelist;
  4. var pagecontentlist = data.pagecontentlist;
  5. var num = pagecontentlist.length;
  6. $("#listbooks").hide();
  7. //$("#pagecontent").innerHTML = '';
  8. document.getElementById("pagecontent").innerHTML=" "; // 清空处理
  9. document.getElementById("pagecontent").style.marginLeft="35px";
  10. document.getElementById("pagecontent").style.marginRight="20px";
  11. for (var i = 0; i < num; i ++) {
  12. $("#pagecontent").append("<font color=blue style='font-size:13px;'><b>出现的书页在: " + pagelist[i].substring(0,7) + "页<b/></color>");
  13. $("#pagecontent").append("<br/>");
  14. if (pagecontentlist[i].length > 450) {
  15. pagecontentlist[i] = pagecontentlist[i].substring(0, 450);
  16. $("#pagecontent").append("<font color=Chocolate>该页的内容为: </font><font color=darkgrey style='font-size:12px; letter-spacing:0px;'><br />" + pagecontentlist[i] + "</color> " );
  17. $("#pagecontent").append("<font color=LightSkyBlue style='font-size:13px;'><b><u>more(阅读全文)...</u></b></font> <br/> <br/>");
  18. } else {
  19. $("#pagecontent").append("<font color=lightblue>该页的内容为: </font><font color=darkgrey style='font-size:12px; letter-spacing:0px;'><br />" + pagecontentlist[i] + "</color> <br/> <br/>" );
  20. }
  21. yit(document.body, sk); // 再加亮下
  22. }
  23. }
  24. , "json");

jquery是js的库。提供一篇介绍比较清楚的文章, 你就可以很清楚了解到jquery可以为前台做什么:Jquery学习笔记

上面的

  1. $.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:

  1. <s:url id='url' action='Classify'>
  2. <s:param name="CateId" value="%{'N'}"></s:param>
  3. </s:url>
  4. <s:a href="%{url}">自然科学总论</s:a>
  5. <s:url id='url' action='Classify'>
  6. <s:param name="CateId" value="%{'O'}"></s:param>
  7. </s:url>
  8. <s:a href="%{url}">数理化</s:a>
  9. <s:url id='url' action='Classify'>
  10. <s:param name="CateId" value="%{'P'}"></s:param>
  11. </s:url>
  12. <s:a href="%{url}">天文、地球</s:a>

展示上的问题都克服了之后,再从性能的角度来分析lucene的使用。

最后再给一篇比较简明易懂的文章:struts2+jquery+json集成

鉴于我拙劣的表达,附上上面的几份参考资料:

Jquery学习笔记

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

Struts2拦截器的使用

struts2+jquery+json集成

前台的url通过 ActionName?var1=xx&var2=yy 的形式传给特定action的更多相关文章

  1. mvc中多参数URL会很长,首次加载不传参数让url很短,路由规则实现方法[bubuko.com]

    如要实现列表中地址全路径“bubuko-11-2.html”,在首次进入时,使用短路径“bubuko.html”,只有再次href后才显示全路径“bubuko-11-2.html”,下面使用路由规则来 ...

  2. 如何用JS/HTML将时间戳转换为“xx天前”的形式【附源码,转

    如果我们有一份过去时间戳,如何使用JS/HTML将时间戳转换为"xx天前"的形式呢,以下是完整代码 <!DOCTYPE html> <html> <h ...

  3. 获取url中的参数并以对象的形式展示出来

    速记:获取url中的参数并以对象的形式展示出来 function getUrlData(){ let url=window.location.search;//url中?之后的部分 console.l ...

  4. 2.编写实现:有一个三角形类Triangle,成员变量有底边x和另一条边y,和两边的夹角a(0<a<180),a为静态成员,成员方法有两个:求面积s(无参数)和修改角度(参数为角度)。 编写实现: 构造函数为 Triangle(int xx,int yy,int aa) 参数分别为x,y,a赋值 在main方法中构造两个对象,求出其面积,然后使用修改角度的方法,修改两边的夹角,再求出面积值。(提示

    求高的方法 h=y*Math.sin(a) 按题目要求,需要我们做的分别是:1.改角度2.显示角度3.求面积并显示 代码用到:1.静态成员变量以修改角度2.数学函数 以下具体代码具体分析 import ...

  5. urlencode($url):把url转义,当字符串数据以url的形式传递给web服务器时,字符串中是不允许出现空格和特殊字符串的

    1.对url进行编码转义

  6. Caused by: org.apache.ibatis.builder.BuilderException: Parsing error was found in mapping #{}. Check syntax #{property|(expression), var1=value1, var2=value2, ...}

    解决办法:查看与该项目中的所有#{},应该是 #{}的中间没有写值

  7. Parsing error was found in mapping #{}. Check syntax #{property|(expression), var1=value1, var2=val错误

    xml中有一个语法错误,整个都错了, 虽然只调用了select查询的方法,但是update中也有语法错误

  8. 【java异常】Parsing error was found in mapping #{}. Check syntax #{property|(expression), var1=value1, var2=val

    在增删改查的过程中有一个#{ }没有填写

  9. Taro文件上传:Blob Url下载Blob对象本身并通过接口上传到服务器

    最近项目的文件上传遇到一个问题,就是Taro的chooseImage传给回调的是一个Blob对象,一般来说,上传控件都会导出Data Url,而Taro给了一个Blob Url,问题在于,我直接令im ...

随机推荐

  1. Docker Kubernetes Volume 网络数据卷

    Docker Kubernetes Volume 网络数据卷 由于支持网络数据卷众多 今天只拿nfs作为案例. 支持网络数据卷 nfs iscsi glusterfs awsElasticBlockS ...

  2. Python 简单soket例子

      简单的soket例子 Python 2.0 客户端服务端传输 1.可发字符串,可发字节 bys类型 Python 3.0 客户端服务端传输 1.只能发bys,比特流的类型. 2.bys类型只能接收 ...

  3. 最短路径之Bellman-Ford算法的队列优化及邻接表

    参考链接:https://blog.csdn.net/qq_40626497/article/details/81139344

  4. servlet登录界面进行用户名和密码验证

    一.建立LoginServlet项目并建立如下目录 二.在Login.html中编写登录界面代码 三.在css文件中新建login.css文件 四.在src文件中添加LoginServlet.java ...

  5. Windows下Python安装numpy+mkl,Scipy和statsmodels

    最近做时间序列分析需要用到Python中的statsmodels,但是安装过程中遇到很头疼的问题,Google.Stackover各种都没有找到合适的解决办法,而且貌似还有很多同学也在吐槽Window ...

  6. tp剩余未验证内容-7

    bash脚本中 的 set -e表示 exit immediately if a simple command returns a non-zero value.主要是为了防止错误被忽略.会被立即退出 ...

  7. mysql utf8mb4 设置

    [mysqld]collation-server=utf8mb4_general_ciinit-connect='SET NAMES utf8mb4'character-set-server=utf8 ...

  8. backbone点滴

    可以查看http://www.css88.com/doc/backbone/ backbone与angular http://www.infoq.com/cn/articles/backbone-vs ...

  9. IDEA-------破解方法

    ① 到这个地方下载 IntelliJ IDEA 注册码:http://idea.lanyus.com/  就是这个jar包:JetbrainsCrack-2.6.10-release-enc.jar ...

  10. mysql(5.5)安装后忘记密码

    查看mysql安装的路径