框架:就是半成品,框架已经完成一些通用功能。只需要实现与业务有关功能
版本:struts-2.3.15.3-all
M:模型
V:视图
C:控制器(之前使用的是Servlet)
*Servlet可以作为控制器,Filter也可以作为控制器,而且功能比Servlet要强大,强大在Filter能根据条件决定是否放行
Struts1和WebWork技术基础合并的全新框架
WebWork为核心,采用拦截器机制(使得业务逻辑控制器与ServletAPI脱离)
Action: 可以是同POJO(Plain Old Java Objects) //既普通类 JavaBean为特殊类
线程:Action一个请求对应一个实例,无线程安全问题 //对比Servlet为单例,有线程安全问题
Servlet依赖:可以访问ServletAPI,但不再依赖,实现TDD(测试驱动开发)
封装请求参数/整合OGNL(比EL更强大的表达式)/数据校验
绑定值到视图:ValueStack值栈
基于Spring AOP思想的拦截器,易于扩展
apps:应用程序(案例)
docs:帮助文档
lib:jar包
src:源码
apps / struts2-blank.war 最简环境
apps / struts2-showcase.war常见案例
war 只要放在 tomcat/webapps/ 将自动解压,并可以访问
导入jar包→Action类(请求处理类)→核心配置文件:struts.xml(src下既WEB-INF/classes下)→web.xml配置过滤器→测试
配置代码
struts.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <!-- 解决表单提交乱码 --> <constant name="struts.i18n.encoding" value="GBK"></constant> <!-- 配置Action访问后缀 --> <constant name="struts.action.extension" value="do"></constant> <!-- 打开开发者模式 1.重新加载i18n配置 2.重新加载struts.xml配置 3.提供更多的错误提示. --> <constant name="struts.devMode" value="false"></constant> <!-- http://localhost:8080/struts2-mini/HelloAction.action http://localhost:8080/struts2-mini/aaa/HelloAction.action name:单纯的给包起一个名字,不要与其他包名重复 namespace: 为action访问加上一层或多层路径 extends: 继承一个其他包,目的是引入其他包的配置 abstract: 声明包是抽象的.意思就是让别的包来继承,声明为抽象的包中不能含有Action配置 --> <package name="hello" namespace="/aaa" extends="struts-default" abstract="true/false" > <!-- name: 为我们的action类加上一个标识,在访问时填入name名称.就可以找到action class: action完整类名 method:处理的方法 --> <action name="HelloAction" class="cn.itcast.action.HelloAction" method="execute" > <!-- name:返回结果的标识,用于找到结果路径 type: 可以决定跳转到结果的方式=> 转发,重定向..... --> <result name="success" type="dispatcher" >/index.jsp</result> </action> </package> <!-- 包含:将外部的配置文件引入到主配置文件中 --> <include file="struts-constant.xml"></include> <include file="struts-dynamic.xml"></include> <include file="struts-namespace.xml"></include> <include file="struts-action.xml"></include> <include file="struts-servlet.xml"></include> </struts>
<!-- 重要: 配置struts2的核心过滤器 --> <!-- 注意: 配置struts2过滤器要放置到其他过滤器后面.保证其他过滤器可以执行 --> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
1.default.properties :用于配置struts 常量。例如:编码
2.struts-default.xml :struts提供的默认核心配置文件,struts大部分功能都在此配置文件中
3.struts-plugin.xml : struts插件核心配置文件,struts整合其他框架或工具
*以上三个文件,用户自己不进行修改
4.struts.xml :用户自定义核心配置文件,可以配置所有内同包括常量
5.struts.properties : 用于自定义struts常量配置文件。一般不使用
6.web.xml :也可以配置struts常量(通过初始化参数)一般不用
注意:如果配置常量,所有的配置文件存在优先级,编号越大优先级越高。
1.用于配置项目编码
struts.i18n.encoding=UTF-8
2.struts整合spring需要配置,默认注释掉了
struts.objectFactory = spring
3.struts默认使用文件上传解析工具:apache-commons-fileupload
struts.multipart.parser=jakarta
3.1临时文件保存位置
struts.multipart.saveDir=
3.2上传文件最大大小,默认值:2M,单位字节
struts.multipart.maxSize
4.用于设置action请求路径扩展名。默认:action或空。多个值使用逗号分隔
struts.action.extension=action,,
例如:/hello/userAction 或 /hello/userAction.action
5.确定是否使用动态方法调用。默认关闭的。
struts.enable.DynamicMethodInvocation =false
6. 设置开发模式,默认关闭。如果设置true:将提供更多提示信息,自动加载文件。
struts.devMode = false
6.1自动重新加载国际化资源文件。
struts.i18n.reload= true
6.2自动冲洗加载xml配置文件。例如:struts.xml。但不会自动加载action类。
struts.configuration.xml.reload= true
7. 设置struts标签主题,默认值:xhtml。取值:simple。
struts.ui.theme=xhtml
开发中常用simple。xhtml存在默认布局,开发中布局使用美工提供页面,布局自定义。
1.<constant> 用于配置struts常量的
name:struts提供固定常量名称。此名称从 default.properties文件获得
value:常量值
例如:<constantname="struts.devMode" value="true"></constant>
2.<package> struts用于管理所有action类
name:给当前包进行唯一命名,必填项。用于其他包继承的。
例如:struts-default.xml/<packagename="struts-default" abstract="true">
将struts已经完成的功能,作为一个包存在。名称是固定值struts-default。
namespace:action访问路径前缀。
例如:"/"
"/hello"
"/a/b/c"
""
extends:用于继承其他包的。
例如:<packageextends="struts-default"> 当前action继承struts已经完成功能。
abstract:是否抽象,如果设置为true,表示没有具体action实现功能。(了解)
2.1 <action> 用于配置action类(请求处理类)
name:action名称,用于在请求路径进行访问
class:action类全限定类名
method:用于确定action类中需要执行的方法,默认值:execute
2.2 <result> 用于配置结果集
name:用于确定action类中,方法的返回值
text:标签体用于设置jsp路径
type:结果集类型
dispatcher:请求转发,从一个action到jsp页面,默认值。
redirect:重定向到jsp页面
redirectAction:重定向到另一个action
stream:以流的方法发送浏览器,用于文件下载。
chain:链,在一次请求中,从一个action到另一个action
2.3 <result-types> 用于配置结果集类型的,一般不用,但需要看的懂。
2.4 <interceptors> 用于配置拦截器
<interceptor>用于注册拦截器的
<interceptor-stack>拦截器栈,将已经注册的拦截器组合在一起,形成一个栈。
例如:<interceptor-stackname="defaultStack"> 声明一个拦截器栈,名称是:defaultStack
2.5 <default-interceptor-ref>用于确定当前默认拦截器的
例如:<default-interceptor-refname="defaultStack"/> 将“defaultStack”拦截器栈,声明默认拦截器栈
2.6 <default-action-ref> 如果访问的action不存在,默认执行的aciton。
例如:/a/b/c/d/oneAction 此aciton没有配置,默认情况返回action找不到
如果配置<default-action-ref> 如果存在404时,不显示action找不到,而是指定action
2.7 <default-class-ref > 用于配置 默认action实现类
例如:<default-class-refclass="com.opensymphony.xwork2.ActionSupport" />
如果编写配置文件时没有声明class属性,及<action name="">将执行ActionSupport类。
3 <include> 将多个struts配置文件组合成一个。
struts.xml入口配置文件,大家共用的。用于存放通用模块。
<includefile="struts-user.xml" />
<includefile="struts-book.xml" />
提供子配置文件
struts-user.xml
struts-book.xml
http://localhost:8080/struts_day01/primer/a/b/c/Demo02Action
将从struts.xml 获得action,首先将匹配 package.namespace =/primer/a/b/c
如果没有匹配上,向上查询,package.namespace= /primer/a/b
如果没有匹配上,向上查询,package.namespace= /primer/a
如果没有匹配上,向上查询,package.namespace= /primer
如果没有匹配上,向上查询,package.namespace= / 【】
<packagenamespace="/">
如果没有匹配上,向上查询,package.namespace=
注意:默认情况动态方法调用关闭的,必须通过struts常量进行配置
<constantname="struts.enable.DynamicMethodInvocation"value="true"></constant>
格式: action名称!方法名称.action
例如:bookAction!add.action
<ahref="${pageContext.request.contextPath}/bookAction!add.action">动态方法调用--add</a>
<action name="userAction">, action.name可以使用通配符星号(*),在action.class、aciton.method、result.name 处可以使用{n}方式匹配星号。
例如:
案例1:userAction_* 将可以通过{1}方法获得第一个星号匹配到内容。
请求路径 /userAction_add , <action method="{1}"> {1} 匹配的内容是add,将执行add方法
案例2:userAction_*_* {1} 匹配ID一个星;{2}匹配第二星
请求路径 /userAction_add_success <action name="userAction_*_*"method="{1}"><resutl name="{2}">
{1}匹配add方法,{2}匹配返回值的名称success
例:3:*_*_* 将采用多个分别描述不同的内容,一次{1}{2}{3}获得
请求路径 /UserAction_add_success
<actionname="*_*_*" class="cn.itcast.action.{1}" method="{2}">
<resultname="{3}">/pages/{3}.jsp
实现方式:3种
public static final String SUCCESS = "success"; public static final String NONE = "none"; public static final String ERROR = "error"; public static final String INPUT = "input"; public static final String LOGIN = "login"; public String execute() throws Exception;
success :表示成功了。
none:没有返回值。相当方法void。没有返回值表示没有result,常用与ajax操作。使用response发送数据。
error:服务器异常。
input:表示用户输入错误。
login:表示需要权限。
支持功能:数据校验,错误提示、国际化等,常用。
方法
public String execute() throws Exception;
1必须是public
2建议又返回值,类型必须String
3方法名称自定义
4没有参数
5需要throw Exception
6非静态的
注意:可以没有返回值,一般情况都有,可以使用return "none" 表示没有返回。
publicvoid add() throw Exception{
}
如果不手动配置Action 默认Action如下配置:表示如果没有配置class属性,将执行那个action
<default-class-refclass="com.opensymphony.xwork2.ActionSupport" />
action.method : 默认值,execute
在ActionSupport提供的execute方法,返回值success
result.name : 默认值,success
如果不配置结果的type属性,默认type属性如下配置:表示type默认转发 dispatcher
<result-type name="dispatcher"class="org.apache.struts2.dispatcher.ServletDispatcherResult"default="true"/>
不使用曾经学习过的servlet知识,可以去操作三个作用域
ActionContext 工具类,action上下文对象
获得实例:ActionContext ac=ActionContext.getContext();
api:
ac.put(key,value), 相当于操作request作用域。request.setAttribute("key",value)
ac.getSession().put(key,value),相当于操作session作用域。session.setAttribute("key",value)
ac.getApplication().put(key,value),相当于操作application作用域。servletContext.setAtt...
ac.getParameters(),返回参数Map
ServletActionContext 工具类,获得需要servlet对象
//1 获得request对象 HttpServletRequest request =ServletActionContext.getRequest(); //2 获得response对象 HttpServletResponse response =ServletActionContext.getResponse(); //3获得servletContext对象 ServletContext servletContext =ServletActionContext.getServletContext(); //4 获得session HttpSession session = request.getSession();
实现原理:Struts2的拦截器。servletConfig做的
需要实现指定的接口,此接口都提供setter,struts在执行action方法之前,将调用setter方法进行赋值。
ServletRequestAware获得HttpServletRequest对象
ServletResponseAware 获得HttpServletResponse对象
ServletContextAware获得ServletContext对象
代码示例
public class Demo5Action3 extends ActionSupport implements ServletRequestAware , ServletResponseAware ,ServletContextAware{ private HttpServletRequest request; private HttpServletResponse response; private ServletContext servletContext; private HttpSession session; @Override public void setServletRequest(HttpServletRequest request) { this.session = request.getSession(); this.request = request; } @Override public void setServletResponse(HttpServletResponse response) { this.response = response; } @Override public void setServletContext(ServletContext context) { this.servletContext = context; }
dispatcher : 默认值,请求转发。一般请求转到jsp页面。
redirect:重定向,一般指重定向到jsp页面。
redirectAction:重定向到action。不能共享request作用的数据。
stream : 下载时使用。
chain :链,从一个aciton,可以到另一个action,且能共享request作用域的数据。
代码示例
<!-- 案例 :结果集类型,重定向jsp --> <action name="demo6Action" class="cn.itcast.f_demo.Demo6Action"> <result type="redirect">/f_demo/type.jsp</result> </action> <!-- 案例 6.2 :结果集类型,重定向action --> <action name="demo6Action2" class="cn.itcast.f_demo.Demo6Action2"> <result type="redirectAction">demo6Action3</result> </action> <action name="demo6Action3" class="cn.itcast.f_demo.Demo6Action3"> <!-- 请求转发 ,默认值--> <result type="dispatcher">/f_demo/type.jsp</result> </action>
能注入哪些参数:找结果类型对应类的源码中的setter方法即可
<package name="p2" extends="struts-default" namespace="/p2"> <action name="demo4"> <result name="success" type="dispatcher"> <!-- param设置参数:调用dispatcher对应的类的setLocation("/success.jsp") --> <param name="location">/success.jsp</param> </result> </action> </package>标签体内直接写路径是上述代码的简写形式
应用:
转发的目标动作不在同一个包下,而且包有着不同的namespace
代码
<package name="p1" extends="struts-default"> <action name="demo3" class="com.itheima.action.Demo3Action"> <!-- 一个动作转向另外一个动作 --> <result name="success" type="chain"> <param name="namespace">/p2</param> <param name="actionName">demo4</param> </result> </action>
//输出随机验证码图片 //原来怎么输出现在也怎么输出 public class CaptchaResult extends StrutsResultSupport { private int width = 120; private int height = 20; public void setWidth(int width) { this.width = width; } public void setHeight(int height) { this.height = height; } protected void doExecute(String finalLocation, ActionInvocation invocation) throws Exception { ValidateCode code = new ValidateCode(width, height, 4, 9); HttpServletResponse response = ServletActionContext.getResponse(); code.write(response.getOutputStream()); } }
<package name="default" extends="struts-default" abstract="true"> <result-types> <result-type name="captcha" class="com.itheima.results.CaptchaResult"></result-type> </result-types> <global-results> <!-- 全局逻辑视图:所有动作没有name=success的局部视图,到全局视图找--> <result name="success">/success.jsp</result> <result name="error">/error.jsp</result> </global-results> </package>
c、在动作中使用自定义的结果类型
<package name="p1" extends="default"> <action name="captcha"> <result name="success" type="captcha"> <param name="width">120</param> <param name="height">25</param> </result> </action> <action name="action1"></action> </package> <package name="p2" extends="default"> <action name="action2"></action> </package>