代码贴士
获取request范围内allsublist属性存储的List集合对象,赋值给变量allsublist。
判断allsublist变量引用的List集合对象是否存在或大小是否为0。
遍历allsublist变量引用的List集合对象。
遍历当前从allsublist变量引用的List集合对象中遍历出的对象。
如果当前元素为第一个元素,执行if标签体中的内容,该标签体内的代码用来输出信息类别。
以超链接形式显示信息标题,该超链接请求的路径为Info/work/info_SingleShow.action,根据在Struts 2.0配置文件中的配置,将调用InfoAction类中的SingleShow()方法处理请求。
如果当前元素为最后一个元素,则执行if标签体中的内容,该标签体内的代码用来输出“更多”超链接。
该超链接请求的路径为Info/work/info_ListShow.action,根据在Struts 2.0配置文件中的配置,将调用InfoAction类中的ListShow ()方法处理请求。
在首页中列表显示免费信息的运行效果如图1.32所示。
2.列表显示某类别中所有信息的实现过程
当用户单击导航菜单中的类别时,将会列表显示该类别中的所有信息,其实现与首页付费信息显示技术是相同的。下面介绍列表显示某类别中所有信息的实现过程。
(1)创建处理用户请求的Action类:InfoAction。在该类中创建ListShow()方法来处理列表显示某类别中所有信息的请求。代码如下:
例程33 代码位置:光盘\TM\01\src\com\yxq\action\InfoAction.java
package com.yxq.action;
import java.util.List;
import com.yxq.actionSuper.InfoSuperAction;
import com.yxq.dao.OpDB;
import com.yxq.model.CreatePage;
public class InfoAction extends InfoSuperAction {
public String ListShow(){ //处理列表显示某类别中所有信息的请求
request.setAttribute("mainPage","/pages/show/listshow.jsp"); //设置在内容显示区中显示的页面
String infoType=request.getParameter("infoType"); //获取信息类别
Object[] params={infoType};
OpDB myOp=new OpDB(); //创建一个业务处理对象
/* 获取所有的付费信息 */
String sqlPayfor="SELECT * FROM tb_info WHERE (info_type = ?) AND (info_state='1') AND (info_payfor = '1') ORDER BY info_date DESC"; //查询某类别中所有付费信息的SQL语句
List onepayforlist=myOp.OpListShow(sqlPayfor, params); //获取所有付费信息
request.setAttribute("onepayforlist",onepayforlist); //保存onepayforlist对象
/* 获取当前页要显示的免费信息 */
String sqlFreeAll="SELECT * FROM tb_info WHERE (info_type = ?) AND (info_state='1') AND (info_payfor = '0') ORDER BY info_date DESC"; //查询某类别中所有免费信息的SQL语句
String sqlFreeSub=""; //查询某类别中某一页的SQL语句
int perR=3; //每页显示3条记录
String strCurrentP=request.getParameter("showpage"); //获取请求中传递的当前页码
String gowhich="Info/work/info_ListShow.action?infoType="+infoType; //设置分页超链接请求的资源
CreatePage createPage=myOp.OpCreatePage(sqlFreeAll, params,perR,strCurrentP,gowhich); //调用OpDB类中的OpCreatePage()方法计算出总记录数、总页数,并且设置当前页码,这些信息都封装到createPage对象中
int top1=createPage.getPerR(); //获取每页显示记录数
int currentP=createPage.getCurrentP(); //获取当前页码
if(currentP==1){ //设置显示第1页信息的SQL语句
sqlFreeSub="SELECT TOP "+top1+" * FROM tb_info WHERE (info_type = ?) AND (info_state = '1') AND (info_payfor = '0') ORDER BY info_date DESC";
}
else{ //设置显示除第1页外其他指定页信息的SQL
语句
int top2=(currentP-1)*top1;
sqlFreeSub="SELECT TOP "+top1+" * FROM tb_info i WHERE (info_type = ?) AND (info_state = '1') AND (info_payfor = '0') AND (info_date < (SELECT MIN(info_date) FROM (SELECT TOP "+top2+" (info_date) FROM tb_info WHERE (info_type = i.info_type) AND (info_state = '1') AND (info_payfor = '0') ORDER BY info_date DESC) AS mindate)) ORDER BY info_date DESC";
}
List onefreelist=myOp.OpListShow(sqlFreeSub, params); //获取当前页要显示的免费信息
request.setAttribute("onefreelist",onefreelist); //保存onefreelist对象
request.setAttribute("createPage", createPage); //保存封装了分页信息的JavaBean对象
return SUCCESS;
}
}
InfoAction类继承自定义类InfoSuperAction,InfoSuperAction类继承MySuperAction类(在1.7.4节将介绍InfoSuperAction类)。在InfoAction类中并没有实现execute()方法来处理请求,而是创建了ListShow()方法来处理列表显示某类别中所有信息的请求,这种改变调用默认方法的功能,与Struts之前版本中的org.apache.struts.actions.DispatchAction类实现的功能有些类似。改变Struts 2.0中这种默认方法的调用可通过两种方法实现:
通过<action>元素的method属性指定要调用的方法。
在请求Action时,在Action名字后加入“!xxx”,其中xxx表示要调用的方法名。
下面分别该两种方法进行介绍。
若存在一个Action类——LogXAction,该类中存在login()和logout方法()。代码如下:
package com.action;
import com.opensymphony.xwork2.ActionSupport;
public class LogXAction extends ActionSupport{
public String login(){
System.out.println("用户登录");
return SUCCESS;
}
public String logout(){
System.out.println("成功注销");
return SUCCESS;
}
}
在JSP页面中提供“登录”和“注销”两个超链接,当用户单击“登录”超链接时,调用LogXAction类,并执行login()方法;当单击“注销”超链接时,调用LogXAction类,并执行logout()方法。
先来介绍第一种方法的实现:通过struts.xml文件中<action>元素的method属性指定调用的方法。
在struts.xml文件中进行如下配置:
<struts>
<package name="logX" extends="struts-default">
<!-- 用户登录配置 -->
<action name="in" class="com.action.LogXAction" method="login">
<result>/login.jsp</result>
</action>
<!-- 用户注销配置 -->
<action name="out" class="com.action.LogXAction" method="logout">
<result>/logout.jsp</result>
</action>
</package>
</struts>
在JSP页面中实现“登录”与“注销”超链接的代码如下:
<a href="in.action">登录</a>
<a href="out.action">注销</a>
完成如上编码后,单击“登录”超链接,将在控制台中输出“用户登录”,单击“注销”超链接将输出“成功注销”。
在上面struts.xml文件的配置中,可以通过一个<action>元素来配置“登录”与“注销”两个请求。实现代码如下:
<package name="logX" extends="struts-default">
<action name="user_*" class="com.action.LogXAction" method="{1}">
<result>/{1}.jsp</result>
</action>
</package>
代码中<action>元素的name属性值为“user_*”,其中“*”表示可取任意值,其中的“{1}”占位符将被赋值为“*”部分的内容。
更改JSP页面中“登录”与“注销”超链接代码:
<a href="user_login.action">登录</a>
<a href="user_logout.action">注销</a>
在经过上述编码后,单击“登录”超链接将调用login()方法,单击“注销”超链接将调用logout()方法。
下面介绍第二种方法的实现:在请求Action时,在Action名字后加入“!xxx”。
首先在struts.xml配置文件中进行如下配置:
<package name="logX" extends="struts-default">
<action name="logInOut" class="com.action.LogXAction">
<result>/message.jsp</result>
</action>
</package>
更改JSP页面中“登录”与“注销”超链接代码:
<a href="logInOut!login.action">登录</a>
<a href="logInOut!logout.action">注销</a>
在经过上述编码后,单击“登录”超链接将调用login()方法,单击“注销”超链接将调用logout()方法。
(2)配置cityinfo.xml配置文件。
例程34 代码位置:光盘\TM\01\WEB-INF\classes\cityinfo.xml
<!-- 前台信息处理 -->
<action name="info_*" class="com.yxq.action.InfoAction" method="{1}">
<result>/view/IndexTemp.jsp</result>
<result name="input">/view/IndexTemp.jsp</result> <!-- 指定进行信息发布时,表单验证失败后返回的页面 -->
</action>
上述的配置,是针对单击导航菜单中的超链接所触发的请求的配置。在view目录下的top.jsp页面中实现的导航菜单的代码如下:
例程35 代码位置:光盘\TM\01\view\top.jsp
<s2:set name="types" value="#session.typeMap"/>
<s2:iterator status="typesStatus" value="types">
<td>
<a href="info_ListShow.action?infoType=<s2:property value='key'/>" style="color:white">
<s2:property value="value"/>
</a>
</td>
</s2:iterator>