1、Struts1 是一个优秀的框架,但是还是具有很多不好的地方,如 Action 和 ActionForm 严重倚赖系统框架中的 API。如 ActionForm 必须继承 ActionForm,Action 控制器继承 Action,测试麻烦。 Struts2 是基于 webwork 发展而来,并非 struts1使用 MyEclipse8.5 版本,可自动添加依赖 struts2 的系统库Struts2 原理:说明:Struts2 没使用 Servlet 作为核心控制器,而是换做一个 Filter 过滤器来进行,其类是org.apache.struts2.dispatcher.ng.filt
2、er.StrutsPrepareAndExecuteFilter过滤器所拦截的请求是/*(当然根据版本的不同,过滤器类也不同,如 Org.apache.Struts2.dispatcher.FilterDispatcher)如果请求中带有.action 或.do,则转入 Struts2 框架处理。配置文件:Web.xml 中:struts2Org.apache.Struts2.dispatcher.FilterDispatcherorg.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilterconfigstruts-d
3、efault.xml,struts-plugin.xml,/struts.xmlstruts2/*Struts.xml/index.jsp/fail.jsp配置文件说明:1、 package 中的 name 为了区分不同的包2、 extends 是继承的包名3、 namespace 是提交时区分的地址,如 namespace=”user”,则提交时需要加入 action=”/user/xxx.action”控制其中的代码,其中数据直接封装和页面表单元素名称对应。如果是对象,则页面表单元素名称写法为 对象.属性名LoginAction 代码:public class LoginAction ex
4、tends ActionSupport/ 封装用户请求参数的uidprivate String uid;private String pwd;public String getUid() return uid;public void setUid(String uid) this.uid = uid;public String getPwd() return pwd;public void setPwd(String pwd) this.pwd = pwd;private String shops;public String getShops() return shops;public voi
5、d setShops(String shops) this.shops = shops;/ 这里直接返回字符串,和xml配置文件中的键值对应public String execute() throws Exception UserInfo userInfo = UserService.newInstance().login(this.uid, this.pwd);if (userInfo != null) /将用户放入session中ActionContext.getContext().getSession().put(“currUser“,u);String shops = ShopServ
6、ice.newInstance().getShopNames();this.setShops(shops);/以下是说明/当action 设置了某个属性后,struts2将会将这些属性全部封装在一个Struts.valueStack的请求属性中。为了在JSP中输出商品信息,可以通过如下代码获取:/获得ValueStack 它类似于一个Map结构 这是JSP中代码/ValueStack vs = (ValueStack)request.getAttribute(“Struts.valueStack”);/String shops = (String)vs.findValue(“shops”);/
7、并非通过Action中的属性名关联,而是通过getter和setter 方法return “cheng“;/这里可以返回系统常量Return this.SUCCESS;return “bai“;/获得requestActionContext actx = ActionContext.getContext();/获得 requestMap req = (Map)actx.get(“request“);HttpServletRequest request = ServletActionContext.getRequest();HttpSession session = ServletActionC
8、ontext.getRequest().getSession();ServletContext ctx = ServletActionContext.getServletContext();/ Map session = (Map)actx.getSession();/ Map application = (Map)actx.getApplication();流程:1、 页面提交请求:action=” Login.action”2、 系统拦截.action 后缀,找到对应的 actionName,找到对应的 Action 处理3、 Action 中可自动获取页面表单的数据,并采用 execut
9、e 方法处理4、 处理完毕后返回字符串,由字符串自动对应了 Struts.xml 中配置的 result 处理/index.jsp1、配置常量:在 Struts.xml 或者 Struts.properties 中更改为.do 来处理请求或者:#将 struts2 业务逻辑控制器 Action 默认访问扩展名*.action 修改为*.doStruts.action.extension = do解决中文乱码问题:修改为 GBK 时,相当于调用 HttpServletRequest 的 setCharacterEncoding 方法2、设置 Struts2 默认主题,解决页面布局混乱配置 Str
10、uts 包配置在 Struts2 中配置包时,必须继承自 Struts-default 包,否则出错Namespace 为命名空间配置那么页面提交时必须加入:测试Action 中的操作1、 获取 Request 对象ActionContext ctx = ActionContext.getContext();Map request = (Map)ctx.get(“request“);2、 获取 sessionActionContext ctx = ActionContext.getContext();Map session = (Map)ctx.getSession();3、 获取 Servl
11、etContext 对象ActionContext ctx = ActionContext.getContext();Map application = (Map)ctx.getApplication();其他获取方式:ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST)ActionContext.getContext().get(ServletActionContext.HTTP_RESPONSE)ActionContext.getContext().get(ServletActionContext.HTTP_CO
12、NTEXT)技巧:一般为了方便处理,会建立 Action 父类。BaseActionPublic class BaseAction/获取 RequestPublic Map getRequest()Return (Map)ActionContext.getContext().get(“request”);/获取 session/获取 ServletContext/获取 ResponsePublic HttpServletResponse getResponse()HttpServletResponse response = ServletActionContext.getResponse();
13、Response.setContentType(“text/html;charset=gbk”);Response.setCharacterEncoding(“gbk”);Return response;-关于公用同一个 Action-方法一:提交代码如下:function submitInfo(type)var form = document.regForm;form.action = myReg!+type+.action;form.submit();对应的 Action 代码如下:public class RegAction extends BaseAction /定义注册方法publi
14、c String reg() throws Exception/获取输出对象PrintWriter out = this.getResponse().getWriter();out.println(“正在执行注册方法.“);return null;public String check() throws ExceptionPrintWriter out = this.getResponse().getWriter();out.println(“正在执行检查方法“);return null;方法二:使用通配符配置,struts.xml 中这里的1是占位符,对应前面 name 后面的*号,那么提交
15、时需要按照指定格式进行:form.action = user_reg.action;form.action = user_check.action;Struts 提供了一个 ValueStack 值栈,所有提交请求的数据先放入值栈中,然后再由值栈中放入对象或者属性中。-BaseAction-所有的 Action 中获取 request、response 很麻烦,于是可以开发一个 BaseAction,如下:package com.scce.action;import com.opensymphony.xwork2.ActionContext;import java.util.*;import
16、javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.struts2.ServletActionContext;public class BaseAction /获得 request 对象public Map getRequest()return (Map)ActionContext.getContext().get(“request“);/获得 Session 对象public Map getSession()return (Map)Actio
17、nContext.getContext().getSession();/获得 ServletContext 对象public Map getApplication()return (Map)ActionContext.getContext().getApplication();/获得 Response 对象public HttpServletResponse getResponse()HttpServletResponse response = ServletActionContext.getResponse();/设置相应头response.setContentType(“text/html
18、;charset=gbk“);response.setCharacterEncoding(“gbk“);return response;-Action 公用在 Struts1 中,默认方法为 execute,Struts2 中同样也是,这样问题来了,每个操作写个Action 吗? struts1 中是通过 Action 类继承 DispatchAction,然后通过在表单或者超链接后传递一个配置的参数用于和方法对应。那么 Struts 中简单了,Action 中写的方法,如checkLogin() ,如 addUser,deleteUser 等等,则页面提交如下:用这种格式去区分方法 2:使用
19、通配符,如下:http:/localhost:8080/struts6l/user_check.action为了规范 Action 类,Struts2 提供了一个 Action 接口 public interface Actionpublic static final java.lang.String SUCCESS = “success“; public static final java.lang.String NONE = “none“; public static final java.lang.String ERROR = “error“; public static final j
20、ava.lang.String INPUT = “input“; public static final java.lang.String LOGIN = “login“; /定义处理用户请求的 execute 方法public abstract java.lang.String execute() throws Exception; public class LoginAction implements Action . . . public String execute() throws Exceptionif(“scott“.equals(this.uid) return this.ER
21、ROR;-Action 中的验证功能:ActionSupport 是一个工具类,它已经实现了 Action 借口,还实现了 Validatable 接口,用于进行验证功能。通过重写该方法可以在校验表单输入出错时,将错误添加至 ActionSupport类的 fieldErrors 域中,然后通过 Struts2 的标签输出错误提示。Action 可以继承 ActionSupport 类,重写 Validate()方法,如下:Public class LoginAction extends ActionSupportPrivate String uid;Private String pwd;Pu
22、blic String execute() throws ExceptionPublic void validate()If(uid.equals(“”)This.addFieldError(“uid”,”用户名不能为空”);Else if(pwd.equals(“”)This.addFieldError(“pwd”,”密码不能为空”);注:validate 在 execute 方法之前执行页面上使用自动显示错误信息指向跳转还是重定向:/index.jsp/fail.jsp-拦截器-拦截器类必须实现借口:InterceptorVoid destroy();/执行一次Void init();/执
23、行一次String intercept(ActionInvocation invocation) throws Exception;该方法是用户需要实现的拦截器动作,返回一个 result 配置字符串作为逻辑视图,该方法的 ActionOnvocation 参数包含被拦截的 Action 的引用,可以通过调用该参数的 Invoke 方法,将控制权转给拦截器或者 Action 的 execute 方法一般通过继承 AbstractInterceptor 类实现,如下:一、重写 intercept 拦截器拦截方法public class MyInterceptor extends Abstract
24、Interceptor / 定义拦截器属性,指定被拦截的Action休眠的时间private int sleep;public int getSleep() return sleep;public void setSleep(int sleep) this.sleep = sleep;public String intercept(ActionInvocation invocation) throws Exception System.out.println(“开始执行Action的时间:“ + (new Date().toLocaleString();/获得当前的 Action(这里只是举例
25、看看就行 )/LoginAction ac = (LoginAction)invocation.getAction();/ 获得被拦截的 ActionContext对象ActionContext ctx = invocation.getInvocationContext();/ 取得 sessionHttpSession session = (HttpSession) ctx.getSession();/ 获得权限String role = (String) session.getAttribute(“role“);/ 获得 requestMap request = (Map) ctx.get
26、(“request“);if (role = null) / 说明未登录request.put(“msg“, “您还没有登录,请先登录! 登录“);return “error“; else / 已登录/ System.out.println(“已登录“);/ 拦截Action 执行的方法名String method = invocation.getProxy().getMethod().toLowerCase();if (!“admin“.equals(role) return “error“;/ 若权限通过,则直接将请求交给对应的控制器return invocation.invoke();二
27、、配置拦截器:struts.xml 文件中:/login.jsp/index.jsp/fail.jsp2000/cheng.jsp/bai.jsp注意:Struts2 中存在默认的拦截器,只有当 Action 中未显示指定拦截器时,该 Action 所在的包的默认拦截器才会对它生效,一旦指定了拦截器,则默认拦截器实效。配置如下:/配置为当前包的默认拦截器-查看 struts 源代码跟踪设置 -右键 struts2 的 jar 包,属性,找到 struts 的源代码,进行跟踪设置-关于在 myeclipse 中的 xml 文件中不出提示的问题-原因在于 xml 前面的 dtd 或者 xsd 文件Window-Profeences-XML-XMLcatalog-Add 增加定义文档的 dtd 文件(struts libary.struts2-core2.16.struts-2.0.dtd 文件)-Namespace 说明-Namespace 决定了 action 的访问路径,默认为” ,可以接收所有路径的 actionNamespace 可以写为/,或者/xxx,或/xxx/yyy,对应的 action 访问路径为/index.action,/xxx/index.action 或/xxx/yyy/index.actionNamespace 最好也用模块来进行命名