1.1 拦截器的作用。
参考答案:
拦截器适合封装一些共通处理,便于重复利用.例如请求参数给Action属性,日志的记录,权限检查, 事务处理等.拦截器是通过配置方式调用,因此使用方法比较灵活,便于维护和扩展。
1.2 fileUpload拦截器原理。
参考答案:
该拦截器首先会调用commons-file-upload.jar组件将客户端上传的文件保存到服务器临时目录下,之后将临时目录下的文件对象给Action属性复制.当Action和Result调用完毕后,清除临时目录下的文件.因此在Action业务方法中,需要做文件复制,将临时文件转移到目标目录中。
1.3 Struts2完整工作流程。
参考答案:
a.客户发送一个Action请求,请求交给控制器
b.控制器创建一个ValueStack,将Action压入栈顶
c.控制器调用ActionInvocation组件执行请求处理
d.ActionInvocation组件调用请求相关的拦截器组件--前部分处理.
e.然后再调用Action组件业务方法
f.然后再调用Result组件处理方法
g.最后执行拦截器组件--后部分处理.
h.将响应信息输出,为客户端响应
2.1 阅读下面的代码,并在指定位置添加注释。
- <struts>
- <package name="day05" extends="struts-default">
- <interceptors>
- <!—此行代码的作用是( 注册SomeInterceptor拦截器 )-->
- <interceptorname="someInterceptor"
- class="com.tarena.interceptor.SomeInterceptor" />
- </interceptors>
- <actionname="some"
- class="com.tarena.action.SomeAction">
- <!—此行代码的作用是( 使用SomeInterceptor拦截器 )-->
- <interceptor-refname="someInterceptor"/>
- <result>/WEB-INF/jsp/ok.jsp</result>
- </action>
- </package>
- </struts>
<struts> <package name="day05" extends="struts-default"> <interceptors> <!—此行代码的作用是( 注册SomeInterceptor拦截器 )--> <interceptor name="someInterceptor" class="com.tarena.interceptor.SomeInterceptor" /> </interceptors> <action name="some" class="com.tarena.action.SomeAction"> <!—此行代码的作用是( 使用SomeInterceptor拦截器 )--> <interceptor-ref name="someInterceptor"/> <result>/WEB-INF/jsp/ok.jsp</result> </action> </package> </struts>
3 编程题(改代码,写代码)
3.1 NETCTOSS登录检查拦截器
在Day04“NETCTOSS资费更新”案例基础上,添加登录检查拦截器功能。当用户没有登录的时候,不能对资费信息进行修改和删除。
参考答案:
1.按照Day02的“NETCTOSS资费的分页显示”案例中,拷贝工程的方法,拷贝struts04_3创建struts05_2工程。
2.经过拷贝创建好的工程,没有登录的内容,所以要把登录的内容整合到struts05_2中。整合登录时需要将Day04的“基于stream Result生成验证码”(struts04_1)案例的内容整合到struts05_2中,最终项目工程结构如图-4,图-5所示。

图- 4

图- 5
整合步骤如下:
a.拷贝struts04_1中ImageAction.java和LoginAction.java到struts05_2的
com.tarena.netctoss.action包下。
b.在struts05_2工程中创建BaseAction.java,放置目录请参考图-4,内容如下:
- import java.util.Map;
- import org.apache.struts2.interceptor.RequestAware;
- import org.apache.struts2.interceptor.SessionAware;
- public classBaseAction implements RequestAware,SessionAware{
- protected Map<String,Object>request;
- protected Map<String, Object>session;
- public void setSession(Map<String, Object>session) {
- this.session = session;
- }
- public void setRequest(Map<String, Object>request) {
- this.request = request;
- }
- }
import java.util.Map; import org.apache.struts2.interceptor.RequestAware; import org.apache.struts2.interceptor.SessionAware; public class BaseAction implements RequestAware,SessionAware{ protected Map<String,Object> request; protected Map<String, Object> session; public void setSession(Map<String, Object> session) { this.session = session; } public void setRequest(Map<String, Object> request) { this.request = request; } }
c. 拷贝struts04_1中AdminInfoDAO.java拷贝到struts05_2的com.tarena.netctoss.dao下;拷贝struts04_1中AdminInfo.java拷贝到struts05_2的com.tarena.netctoss.pojo下;拷贝struts04_1中ImageUtil.java拷贝到struts05_2的com.tarena.netctoss.util下。
d.修改struts05_2的struts.xml,添加如下关于登录的配置:
- <package name="login" extends="struts-default">
- <!-- 登录处理 -->
- <actionname="toLogin">
- <resultname="success">/WEB-INF/login.jsp</result>
- </action>
- <actionname="login" class="com.tarena.netctoss.action.LoginAction">
- <resultname="success">/WEB-INF/main.jsp</result>
- <resultname="login">/WEB-INF/login.jsp</result>
- </action>
- <actionname="image" class="com.tarena.netctoss.action.ImageAction">
- <resulttype="stream">
- <paramname="inputName">imageStream</param>
- </result>
- </action>
- </package>
<package name="login" extends="struts-default"> <!-- 登录处理 --> <action name="toLogin"> <result name="success">/WEB-INF/login.jsp</result> </action> <action name="login" class="com.tarena.netctoss.action.LoginAction"> <result name="success">/WEB-INF/main.jsp</result> <result name="login">/WEB-INF/login.jsp</result> </action> <action name="image" class="com.tarena.netctoss.action.ImageAction"> <result type="stream"> <param name="inputName">imageStream</param> </result> </action> </package>
e. 拷贝struts04_1中的main.jsp和login.jsp到struts05_2的WEB-INF目录下。修改login.jsp的form的action,如图-6所示。

图- 6
修改main.jsp的连接,如图-7所示。

图- 7
f.测试登录功能是否成功;测试资费的列表显示,修改,删除是否成功(测试过程略)
3.创建LoginInterceptor.java拦截器,拦截器的作用是:从session去key为“user”的value,如果取到的value是null,说明该用户没有登录,返回到登录页面。
- public classLoginInterceptor extends AbstractInterceptor {
- @Override
- public Stringintercept(ActionInvocationinvocation) throws Exception {
- Map<String,Object>session = invocation.getInvocationContext().getSession();
- if(session.get("user") == null){
- //定位到登陆界面
- return "login";
- }
- return invocation.invoke();
- }
- }
public class LoginInterceptor extends AbstractInterceptor { @Override public String intercept(ActionInvocation invocation) throws Exception { Map<String,Object> session = invocation.getInvocationContext().getSession(); if(session.get("user") == null){ //定位到登陆界面 return "login"; } return invocation.invoke(); } }
4.修改struts.xml,注册LoginInterceptor,并应用到资费的修改和删除上。
- <?xmlversion="1.0" encoding="UTF-8"?>
- <!DOCTYPE struts PUBLIC
- "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
- "http://struts.apache.org/dtds/struts-2.1.dtd">
- <struts>
- <package name="fee" extends="json-default" namespace="/fee">
- <interceptors>
- <interceptorname="checkLogin" class="com.tarena.netctoss.interceptor.LoginInterceptor"></interceptor>
- <interceptor-stackname="checkLoginStack">
- <interceptor-refname="checkLogin"/>
- <interceptor-refname="defaultStack"/>
- </interceptor-stack>
- </interceptors>
- <global-results>
- <resultname="login" type="redirectAction">
- <paramname="actionName">toLogin</param>
- <paramname="namespace">/</param>
- </result>
- </global-results>
- <!-- 资费处理 -->
- <actionname="feeList"
- class="com.tarena.netctoss.action.fee.FeeListAction">
- <paramname="pageSize">3</param>
- <resultname="success">/WEB-INF/fee/fee_list.jsp</result>
- </action>
- <actionname="feeDelete"
- class="com.tarena.netctoss.action.fee.FeeDeleteAction">
- <interceptor-refname="checkLoginStack"/>
- <resultname="success" type="redirectAction">feeList</result>
- </action>
- <actionname="toAdd">
- <result>/WEB-INF/fee/fee_add.jsp</result>
- </action>
- <actionname="validName"
- class="com.tarena.netctoss.action.fee.ValidNameAction">
- <resulttype="json">
- <paramname="root">ok</param>
- </result>
- </action>
- <actionname="fee_*" class="com.tarena.netctoss.action.fee.FeeUpdateAction" method="{1}">
- <interceptor-refname="checkLoginStack"/>
- <resultname="success">/WEB-INF/fee/fee_modi.jsp</result>
- </action>
- </package>
- <package name="login" extends="struts-default">
- <!-- 登录处理 -->
- <actionname="toLogin">
- <resultname="success">/WEB-INF/login.jsp</result>
- </action>
- <actionname="login"
- class="com.tarena.netctoss.action.LoginAction">
- <resultname="success">/WEB-INF/main.jsp</result>
- <resultname="login">/WEB-INF/login.jsp</result>
- </action>
- <actionname="image"
- class="com.tarena.netctoss.action.ImageAction">
- <resulttype="stream">
- <paramname="inputName">imageStream</param>
- </result>
- </action>
- </package>
- </struts>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts> <package name="fee" extends="json-default" namespace="/fee"> <interceptors> <interceptor name="checkLogin" class="com.tarena.netctoss.interceptor.LoginInterceptor"></interceptor> <interceptor-stack name="checkLoginStack"> <interceptor-ref name="checkLogin"/> <interceptor-ref name="defaultStack"/> </interceptor-stack> </interceptors> <global-results> <result name="login" type="redirectAction"> <param name="actionName">toLogin</param> <param name="namespace">/</param> </result> </global-results> <!-- 资费处理 --> <action name="feeList" class="com.tarena.netctoss.action.fee.FeeListAction"> <param name="pageSize">3</param> <result name="success">/WEB-INF/fee/fee_list.jsp</result> </action> <action name="feeDelete" class="com.tarena.netctoss.action.fee.FeeDeleteAction"> <interceptor-ref name="checkLoginStack"/> <result name="success" type="redirectAction">feeList</result> </action> <action name="toAdd"> <result>/WEB-INF/fee/fee_add.jsp</result> </action> <action name="validName" class="com.tarena.netctoss.action.fee.ValidNameAction"> <result type="json"> <param name="root">ok</param> </result> </action> <action name="fee_*" class="com.tarena.netctoss.action.fee.FeeUpdateAction" method="{1}"> <interceptor-ref name="checkLoginStack"/> <result name="success">/WEB-INF/fee/fee_modi.jsp</result> </action> </package> <package name="login" extends="struts-default"> <!-- 登录处理 --> <action name="toLogin"> <result name="success">/WEB-INF/login.jsp</result> </action> <action name="login" class="com.tarena.netctoss.action.LoginAction"> <result name="success">/WEB-INF/main.jsp</result> <result name="login">/WEB-INF/login.jsp</result> </action> <action name="image" class="com.tarena.netctoss.action.ImageAction"> <result type="stream"> <param name="inputName">imageStream</param> </result> </action> </package> </struts>
5. 测试,访问http://localhost:8080/struts05_2/fee/feeList.action,如图-8所示。

图- 8
点击“修改”,返回到登录页面,如图-9所示。

图- 9
输入正确的用户名和密码,点击登录,进入main.jsp,如图-10所示。

图- 10
点击资费管理进入列表页,再次点击修改,进入修改页面,如图-11所示。

图- 11
删除的拦截过程和修改类似,请学员自己测试。