都市供求信息网(15)

代码贴士

获取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>

读书导航