Hello Struts2
Struts2 概述
Struts2 是一个用来开发 MVC 应用程序的框架. 它提供了 Web 应用程序开发过程中的一些常见问题的解决方案: 对来自用户的输入数据进行合法性验证; 统一的布局; 可扩展性; 国际化;本地化; 支持 Ajax; 表单的重复提交; 文件的上传下载; …..
下载 Struts2
打开浏览器输入 http://struts.apache.org/ 点击 “struts-2.3.x-all.zip” 下载.
Struts2 的 Hello World
搭建 Struts2 的环境:
加入 jar 包: 复制 struts\apps\struts2-blank\WEB-INF\lib 下的所有 jar 包到当前 web 应用的 lib 目录下.
在 web.xml 文件中配置 struts2: 复制 struts\apps\struts2-blank1\WEB-INF\web.xml 文件中的过滤器的配置到当前 web 应用的 web.xml 文件中
在web 应用的 classpath 下添加 struts2 的配置文件 struts.xml: 复制 struts1\apps\struts2-blank\WEB-INF\classes 下的 struts.xml 文件到当前 web 应用的 src 目录下.
添加 DTD 约束
struts-2.3.4-all\struts-2.3.4\src\core\src\main\resources
struts.xml 文件示例:
<struts> <!-- package: 包. struts2 使用 package 来组织模块. name 属性: 必须. 用于其它的包应用当前包. extends: 当前包继承哪个包, 继承的, 即可以继承其中的所有的配置. 通常情况下继承 struts-default struts-default 这个包在 struts-default.xml 文件中定义. namespace 可选, 如果它没有给出, 则以 / 为默认值. 若 namespace 有一个非默认值, 则要想调用这个包里的Action, 就必须把这个属性所定义的命名空间添加到有关的 URI 字符串里 http://localhost:8080/contextPath/namespace/actionName.action --> <package name="helloWorld" extends="struts-default"> <!-- 配置一个 action: 一个 struts2 的请求就是一个 action name: 对应一个 struts2 的请求的名字(或对一个 servletPath, 但去除 / 和扩展名), 不包含扩展名 class 的默认值为: com.opensymphony.xwork2.ActionSupport method 的默认值为: execute result: 结果. --> <action name="product-input" class="com.opensymphony.xwork2.ActionSupport" method="execute"> <!-- result: 结果. 表示 action 方法执行后可能返回的一个结果. 所以一个 action 节点可能会有多个 result 子节点. 多个 result 子节点使用 name 来区分 name: 标识一个 result. 和 action 方法的返回值对应. 默认值为 success type: 表示结果的类型. 默认值为 dispatcher(转发到结果.) --> <result name="success" type="dispatcher">/WEB-INF/pages/input.jsp</result> </action> <action name="product-save" class="com.atguigu.struts2.helloworld.Product" method="save"> <result name="details">/WEB-INF/pages/details.jsp</result> </action> </package> </struts>
action VS Action 类
1). action: 代表一个 Struts2 的请求.
2). Action 类: 能够处理 Struts2 请求的类.
> 属性的名字必须遵守与 JavaBeans 属性名相同的命名规则. 属性的类型可以是任意类型. 从字符串到非字符串(基本数据库类型)之间的数据转换可以自动发生
> 必须有一个不带参的构造器: 通过反射创建实例
> 至少有一个供 struts 在执行这个 action 时调用的方法
> 同一个 Action 类可以包含多个 action 方法.
> Struts2 会为每一个 HTTP 请求创建一个新的 Action 实例, 即 Action 不是单例的, 是线程安全的.
访问 web 资源
在 Action 中, 可以通过以下方式访问 web 的 HttpSession, HttpServletRequest, HttpServletResponse 等资源
I. 和 Servlet API 解耦的方式: 只能访问有限的 Servlet API 对象, 且只能访问其有限的方法(读取请求参数, 读写域对象的属性, 使 session 失效...).
> 使用 ActionContext
1 //0. 获取 ActionContext 对象 2 //ActionContext 是 Action 的上下文对象. 可以从中获取到当往 Action 需要的一切信息 3 ActionContext actionContext = ActionContext.getContext(); 4 5 //1. 获取 application 对应的 Map, 并向其中添加一个属性 6 //通过调用 ActionContext 对象的 getApplication() 方法来获取 application 对象的 Map 对象 7 Map<String, Object> applicationMap = actionContext.getApplication(); 8 //设置属性 9 applicationMap.put("applicationKey", "applicationValue"); 10 11 //获取属性 12 Object date = applicationMap.get("date"); 13 System.out.println("date: " + date); 14 15 //2. session 16 Map<String, Object> sessionMap = actionContext.getSession(); 17 18 //3. request* 19 //ActionContext 中并没有提供 getRequest 方法来获取 request 对应的 Map 20 //需要手工调用 get() 方法, 传入 request 字符串来获取. 21 Map<String, Object> requestMap = (Map<String, Object>) actionContext.get("request"); 22 requestMap.put("requestKey", "requestValue"); 23 24 //4. 获取请求参数对应的 Map, 并获取指定的参数值. 25 //键: 请求参数的名字, 值: 请求参数的值对应的字符串数组 26 //注意: 1. getParameters 的返回值为在 Map<String, Object>, 而不是 Map<String, String[]> 27 // 2. parameters 这个 Map 只能读, 不能写入数据, 如果写入, 但不出错, 但也不起作用! 28 Map<String, Object> parameters = actionContext.getParameters(); 29 System.out.println(((String[])parameters.get("name"))[0]);
> 实现 XxxAware 接口。Struts2 框架在运行时向 Action 实例注入 parameters, request, session 和 application 对应的 Map 对象:
1 public class TestAwareAction implements ApplicationAware, SessionAware, RequestAware, 2 ParameterAware{ 3 4 public String execute(){ 5 //1. 向 application 中加入一个属性: applicationKey2 - applicationValue2 6 application.put("applicationKey2", "applicationValue2"); 7 //2. 从 application 中读取一个属性 date, 并打印. 8 System.out.println(application.get("date")); 9 return "success"; 10 } 11 12 private Map<String, Object> application; 13 14 @Override 15 public void setApplication(Map<String, Object> application) { 16 this.application = application; 17 } 18 19 @Override 20 public void setParameters(Map<String, String[]> parameters) { 21 } 22 23 @Override 24 public void setRequest(Map<String, Object> request) { 25 } 26 27 @Override 28 public void setSession(Map<String, Object> session) { 29 } 30 }
> 选用的建议: 若一个 Action 类中有多个 action 方法, 且多个方法都需要使用域对象的 Map 或 parameters, 则建议使用Aware 接口的方式
> session 对应的 Map 实际上是 SessionMap 类型的! 强转后若调用其 invalidate() 方法, 可以使其 session 失效!
II. 和 Servlet API 耦合的方式: 可以访问更多的 Servlet API 对象, 且可以调用其原生的方法.
> 使用 ServletActionContext
> 实现 ServletXxxAware 接口.
通过实现 ServletRequestAware, ServletContextAware 等接口的方式
ActionSupport
1). ActionSupport 是默认的 Action 类: 若某个 action 节点没有配置 class 属性, 则 ActionSupport 即为待执行的 Action 类. 而 execute 方法即为要默认执行的 action 方法
2). 在手工完成字段验证, 显示错误消息, 国际化等情况下, 推荐继承 ActionSupport.
关于 Struts2 请求的扩展名问题
1). org.apache.struts2 包下的 default.properties 中配置了 Struts2 应用个的一些常量
2). struts.action.extension 定义了当前 Struts2 应用可以接受的请求的扩展名.
3). 可以在 struts.xml 文件中以常量配置的方式修改 default.properties 所配置的常量.
<constant name="struts.action.extension" value="action,do,"></constant>