struts笔记
struts2介绍
Struts2是Apache发行的MVC开源框架。注意:它只是表现层web(MVC)框架。
Struts1也是apache开发的一套mvc的开源框架。在2005年之前非常流行。
弊端:Struts1的核心控制器就是一个Servlet。随着使用者的增多,弊端开始出现。
在long long ago,有一个设计超前的框架XWork,后来推出了XWork1和WebWork2。
Struts2就是apache和OpenSymphony组织合并开发出来。
里面包含了WebWork2的核心及Struts的一些特性和功能。除此之外,和Struts1没有任何关系了。
struts环境搭建
下载struts2的jar包:下载struts2 的 2.3.33版本
- 创建web项目
- 导入所需要的jar包(可以在example的struts2-blank.war中的lib下找)
- Struts核心jar包
- struts2-core-2.3.33.jar
- xwork-core-2.3.33.jar
- OGNL表达式
- ognl-3.0.19.jar
- 开源日志 log for java
- log4j-core-2.3.jar
- log4j-api-2.3.jar
- 基于子类的动态代理
- asm-3.3.jar
- 提供其于对象的表现形式
- asm-3.3.jar
- 提供基于事件的表现形式
- asm-commons-3.3.jar
- 文件上传所需要的包
- commons-fileupload-1.3.2.jar
- asm-commons-3.3.jar
- 页面 模板框架
- freemarker-2.3.22.jar
- 对于字节码的支持,jBoss的一个子项目
- javassist-3.11.0.GA.jar
- 对java.lang的扩展
- commons-lang3-3.2.jar
- 在src下创建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>
</struts>
- 在web.xml中配置核心过滤器(配置的目的是用于拦截请求,由Struts的规则去处理请求,而不是用以前的servlet去处理)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<!-- struts过滤器拦截请求的规则 -->
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
- Action配置
- 写一个HelloAction的类,需要写个sayHello方法
在WebContent中添加一个success.jsp页面
部署项目,启动tomcat,访问路径测试
struts默认是处理.action的请求,或者不带action也可以,其它后缀的都不会拦截,会放行,如jsp
Struts2的执行流程
- tomcat启动
- 实例化并初始化过滤器
- 加载struts.xml配置文件
- 客户端发送请求
- 请求到达过滤器
- 截取请求的动作名称,并从struts中找
- 找到后,实例化动作类
- 调用对应的动作方法,方法有返回值
- 根据返回值,找到name取值对应的结果视图
- 返回结果视图
struts2的配置文件加载顺序
struts有很多配置文件
当应用被tomcat加载的时候,struts2的配置文件就已经被加载过了。
- 加载顺序
配置文件名 | 所在位置 | 说明 |
---|---|---|
default.properties | struts2-core-2.3.15.3.jar\org\apache\struts2 | 不能修改 |
struts-default.xml | struts2-core-2.3.15.3.jar | 不能修改 |
strtuts-plugin.xml | 在struts2提供的插件jar包中 | 不能修改 |
struts.xml | 应用中 | 可以修改 |
struts.properties | 应用中 | 可以修改 |
web.xml | 应用中 | 可以修改,可以给过滤器配置参数 |
default.properties的一些默认配置:
- struts.i18n.encoding=UTF-8:国际化
- struts.action.extension=action:默认访问扩展后缀,可以是action,也可以没有后续
- struts.devMode = false:是否是开发模式。开发模式:改了配置文件,不需要重启。输出更多的错误信息。开发阶段建议为true。
struts-default中默认的拦截器分组
struts-defualts中主要的内容:结果类型、拦截器分组,默认使用的接替器分组
修改struts的访问后缀
- 在struts.xml的配置文件中添加:
<constant name="struts.action.extension" value="do"></constant>
- 在src下创建struts.properties,添加
struts.action.extension=htm
,这个会覆盖struts.xml的配置 - 在web.xml中配置:
配置struts的开发模式
struts配置文件的主要元素
package元素
在struts2的配置文件中引入了面向对象思想,使用了分包管理。易于管理动作类。便于模块化开发动作类。
属性:
- name
- 包的名称。必须写。且必须唯一。
- extends
- 一般情况下需要继承struts-default包,但不是必须的。
- 不过如果不继承的话,将无法使用struts2提供的核心功能。
- struts-default.xml中定义着struts-default这个包。
- 而struts-default.xml是在我们的struts.xml加载之前加载。
- abstract
- 把包声明为抽象包,抽象包就是用来被继承的。
- 只要是没有 元素的包,就可以声明为抽象包。
- namespace
- 名称空间。【访问路径=名称空间+动作名称】
namespace的默认取值是一个"",
注意:默认值不是/,写自定义的namespace时需要加/
访问路径为http://localhost:8080/day01_struts2_demo03/user/hello.action
注意:需要在访问action前添加红色命令空间
如果访问http://localhost:8080/day01_struts2_demo03/a/b/user/hello.action 是访问不了
但是如果是访问http://localhost:8080/day01_struts2_demo03/user/a/b/hello.action 是可以访问的
action元素
action元素解释
配置动作,处理请求路径
属性:
- name:动作名称
- class:动作类全名
- method:动作类中的方法名称。默认是
public String execute()
方法的要求:
- public的
- 返回值必须是String
- 没有参数
动作类的写法:
- 直接在写个Action类,不需要继承任何类,然后在struts.xml中配置
访问路径: http://localhost:8080/day01_struts2_demo05/user/login
- 写个Action类实现Action接口,然后实现excute方法
如果没有配置Method,默认执行Action的excute方法
访问路径:http://localhost:8080/day01_struts2_demo05/user/login2
Action接口中,有一些静态常量,如下图:
常量变量名 | 对应的值 | 说明 |
---|---|---|
SUCCESS | success | 动作方法执行一切OK |
ERROR | error | 动作方法执行时遇到了异常 |
INPUT | input | 回显 |
LOGIN | login | 一般转向登陆页面 |
NONE | none | 不转向任何的视图 |
- 写个Action类继承ActionSuport类【推荐使用这种方式】
ActionSupport是实现Action接口的类
访问路径:http://localhost:8080/day01_struts2_demo05/user/login3
默认的动作类:
在struts-default.xml中定义了默认动作类和方法
就是com.opensymphony.xwork2.ActionSupport 这个类
案例:
struts.xml:可以在Action中不配置 class 和method,会由默认的动作类来处理,ActionSupport的excute方法返回的就是success
访问路径: http://localhost:8080/day01_struts2_demo05/user/defaultAction
修改默认的动作类
action的通配符写法
多个通配符的写法:
优先级:绝对匹配优先。使用通配符的按照在配置文件中的先后顺序进行匹配的。
动态方法调用
访问路径:
http://localhost:8080/day01_struts2_demo06/student!addStudent.action
http://localhost:8080/day01_struts2_demo06/student!deleteStudent.action
result元素
result元素功能
作用:为动作指定结果视图
属性:
- name:逻辑视图的名称,对应着动作方法的返回值。默认是success
- type:结果类型,值得就是用什么方式跳转到定义的页面。默认是dispatcher转发
retult中type的取值:
- type的默认取值时dispatcher
- type属性的取值在struts-default.xml中定义着
redirect重定向:
chain 转发到同一个名称空间的动作
redirectAction 重定向到同一名称空间的动作
chain 转发到不同一个名称空间的动作
redirectAction重定向到不同一个名称空间的动作
result元素中param子元素
- 在转发或者重定向到不同包下的动作时,都用到了result元素的子元素param。
- param元素的作用:依赖注入(Dependence Injection)思想
- 我们通过struts-default.xml中的resultTypes元素中配置可以看出,每个结果类型视图其实都是靠一个类来实现的。
- 而param元素就是将配置的参数,注入到该类中。
- 调用的是对应类的setter方法进行注入的。
自定义结果类型
- 其实结果类型就是一个类,这些类都实现com.opensymphony.xwork2.Result接口。
- 或者继承自该接口的实现类org.apache.struts2.dispatcher.StrutsResultSupport。
- 这些类都有一个doExecute方法,用于执行结果视图。【查看源码各种结果类型的类结构】
- struts的内部实现就是Servlet
自己写一个结果视图:
优化自定义结果类型:
全局视图和局部视图
第一步:写一个包,名为myDefault,里面写全局的配置
第二点:其它包继承myDefault包,如图
动作类中访问Servlet的api
- 获取servlet api:
- 第一种:通过ServletActionContext获取 【推荐使用】
- 第二种:通过注入方式:先让Action实现两个接口ServletRequestAware,ServletResponseAware
第二种注入方式原理是因为struts有个拦截器
来实现的
查看ServletConfigIntercepto的源码
多个struts配置文件
多个struts配置文件的用途是为了模块开发和减少开发中的冲突
Action接收请求参数的方式
通过以前的Servlet来获取
通过Action的属性的set方法注入
struts会通过表单字段的名称,调用set方法,比如username字段会调用setUsername
通过Action的属性的set模型的形式注入
User.java模型:提供属性的get/set方法
UserAction.java
把参数封装到一个User模型中,然后Action提供模型的get/set方法
补充:讲解下面set/get方法打印顺序的原因
先获取user对象,如果没有,创建一User对象注入进去
通Action模型驱动封装参数
参数注入的原理
参数会自动注入是因为有两个拦截器在工作
查看struts-default.xml源码可以看到下面两个拦截器
修改包下的拦截器:
静态参数注入【少用】
struts可以通过action中静态注入参数,然后在Action提交属性注入
这种是静态流入,参数写死
用户注册案例
表现层web
第一步:在mysql中添加一个struts2_day3数据库,把db.sql的表创建下(数据库需要utf-8编码的,才可以存储中文)
第二步:将资料中db文件夹的jar导入到项目工程中(这里的数据源使用DBCP:DataBase Connection Pool 是apache公司实现的一个开源的数据源。)
第三步:将资料中db文件夹的dbcpconfig.properties导入src项目下
第四步:将DBCPUtil.java写好的导入在项目中
第五步:写webcontent中写个注册页面
第六步:写个UserAction,使用模型驱动来接收参数
第七步:配置struts.xml
持久层dao和service层
UserAction 的register方法修改
struts自定义参数类型转换
前面的多个爱好请求参数,struts框架会自动进行字符串的拼接,如拼接成【泡妞, 写代码, 买房子】,是以逗号+空格类型来拼接的
struts也会把字符串转换成Date类型
但是如果提交的是错误的日期,就会报错
struts有很多类型转换器
struts的字符串类型转换是由一个类com.opensymphony.xwork2.conversion.impl.StringConverter类来完成的
日期类型转换是由com.opensymphony.xwork2.conversion.impl.DateConverter来完成
源码分析得出,如果要自己写一个类型转换
- 可以实现DefaultTypeConverter抽象类
- 我们一般也可以用它的子类StrutsTypeConverter来实现
自定义日期类型转换步骤:
- 写一个类继承StrutsTypeConverter,并实现抽象方法
- 实现两个抽象方法的逻辑
- 配置局部类型转换器,在模型pojo的包下配置【模型名字-conversion.properties】的一个文件,内容如下
- 测试自定义日期是否生效
- 配置全部类型转换器
struts2的错误回显
前提:将前面用户注册案例的时间转化时,抛出运行时异常
注册时,将日期写错格式,会得到下面的一个结果,result input表示需要一个回显页面,也就是发生异常时的显示页面
在struts.xmp中配置回显页面
在register.jsp中添加struts的标签
回显效果
struts的form表单标签
struts的from标签提供了和原始html表单几乎一至的属性
属性:
- action:请求地址。直接写动作名称,不用写contextPath
- method: 请求方式,默认是post请求,可以不用写
- enctype:静音编码的MIME类型
案例:将前面的用户注册案例改成struts的表单标签来显示
strtus的错误处理和中文显示
struts标签如果有字段错误,会回显信息
设置回显信息为红色
添加个s:head标签即可
效果:
设置回显信息中文化
struts的表单数据验证方式
服务端Action验证
有两种方法:
效果:
xml声明式验证
全局声明方式
在action包中声明UserAction-validation.xml文件
这种方式配置是全局配置,所有action的方法都会拦截验证
如果其它方法不想验证,可配置@SkipValidation注解
dtd约束可以在xwork-core的jar包中找
struts默认有很多种验证器类型,声明在default.xml中(注意default.xml的位置)
演示密码不能大于6的配置
局部声明方式
在action包中声明UserAction-register-validation.xml文件
声明方式 【Action类名-方法名-validation.xml】
xml内容与上面的一样
验证器案例综合
Add.Jsp页面
student模型
public class Student {
private String username;//不能为空,去空字符串
private int age;//18~100
private String email;//正确邮箱格式
private String password;//3~8
private String repassword;//与密码一至
private int score;//必须是自然数
private String url;//必须是一个路径
private String gender;//性别,只有男和女
Action
Struts.xml
StudentAction-add-validation.xml
<validators>
<!--
1. private String username;//不能为空,去空字符串
requiredstring 比 required 好一点,会自动去除空格
-->
<validator type="requiredstring">
<param name="fieldName">username</param>
<message>用户名不能为空</message>
</validator>
<!--2.private int age;//18~100
1.表单的类型,会根据模型的属性类型去校验
-->
<validator type="int">
<param name="fieldName">age</param>
<param name="min">18</param>
<param name="max">100</param>
<message>年龄必须在18~100</message>
</validator>
<!-- 3.private String email;//正确邮箱格式-->
<validator type="requiredstring">
<param name="fieldName">email</param>
<message>邮箱不能为空</message>
</validator>
<validator type="email">
<param name="fieldName">email</param>
<message>邮箱格式不正确</message>
</validator>
<!--4. private String password;//3~8 -->
<validator type="requiredstring">
<param name="fieldName">password</param>
<message>密码不能为空</message>
</validator>
<validator type="stringlength">
<param name="fieldName">password</param>
<param name="minLength">3</param>
<param name="maxLength">8</param>
<message>密码长度为3~8</message>
</validator>
<!-- 5.private String repassword;//与密码一至 -->
<validator type="expression">
<param name="expression">
<![CDATA[ password == repassword]]>
</param>
<message>密码不一至</message>
</validator>
<!-- 6.private int score;//必须是自然数
regex :正则
-->
<!-- <validator type="regex">
<param name="fieldName">score</param>
<param name="regexExpression">\d+</param>
<message>分数必须要数字</message>
</validator> -->
<!-- private String url;//必须是一个路径 http:// -->
<validator type="url">
<param name="fieldName">url</param>
<message>URL格式不合法,以 http://开头</message>
</validator>
<!-- private String gender;//性别必填,只有男和女 -->
<validator type="required">
<param name="fieldName">gender</param>
<message>性别必选</message>
</validator>
</validators>
struts2的国际化
什么是国际化
软件的国际化:软件开发时,要使它能同时应对世界不同地区和国家的访问,并针对不同地区和国家的访问,提供相应的、符合来访者阅读习惯的页面或数据
国际化使用场景
苹果英文网:https://www.apple.com/
苹果中文网:https://www.apple.com/cn
苹果香港网:https://www.apple.com/hk
苹果日本网https://www.apple.com/jp/
固定文本的国际化
例如:消息提示,错误提示和菜单,导航栏等等固定文本
使用步骤
创建一个消息资源包
一个资源包由多个文件组成,这些文件名都有命名规范:主要文件名_语言代码_国家代码.properties。
语言代码和国家代码:有iso规定的
当文件只有主要文件名.properties时,表明它是默认资源包。浏览器会根据不同的语言环境找对应语言环境的资源包
当没有时,找默认的。
每个资源包的内容都由相同的key和对应语言环境的value组成。
比如:
message_zh_CN.properties
message_zh_HK.properties
message_en_US.properties
读取资源包中的内容
Java提供ResourceBundle类可以读取资源包的国际化配置文件
JSP中使用国际化
使用jstl标签来国际化
JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能。
JSTL支持通用的、结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签。
除了这些,它还提供了一个框架来使用集成JSTL的自定义标签。
首先需要在项目中导入两个jar包
struts2提供的国际化
前面的国际化与struts无关
第一步:配置资源包
配置全局的资源包
在struts.xml中配置
配置包范围的资源包
资源包名称命名规范:package_语言代码_国家代码.properties(固定的)。以此种命名方式的资源包能被该包及其子包中的动作类访问。
优先级:高于全局消息资源包
局部消息资源包
资源包名称命名规范:动作类名称_语言代码_国家代码.properties。以此种命名方式的资源包,只为动作类服务。
优先级最高(就近原则)。
注:Struts2中资源包的搜索顺序
第二步:读取资源包内容
jsp读取资源包内容
使用struts的标签s:text获取国际化内容
Action读取资源包内容
使用ActionSupport的getText方法,可以读取到资源包的内容
也就是说这个Action一定要继承ActionSupport
这种在实际开发中几乎不用
自由指定读取资源包
在jsp页面可以使用s:i18n标签指向读取的国际资源包文件
Strust2的拦截器
拦截器的重要性
Struts2中的很多功能都是由拦截器完成的。比如:servletConfig,staticParam,params,modelDriven等等。
Struts默认的拦截器配置在struts-default.xml文件中
拦截器是AOP编程思想的一种应用形式。
拦截器的执行时机
拦截器的部分类结构
简单拦截器入门
单个拦截器
第一步
创建个拦截器,继承Abastract方法,实现intercept方法
第二步
在struts.xml中配置拦截器,拦截器需要配置后才可使用
Demo1.jsp 的内容随便写
多个拦截器
invocation.invoke方法返回的就是视图
拦截器的应用场景【登录】
首先准备四个login.jsp,main.jsp, studentList.jsp, teacherList.jsp 页面
当登录成功后,跳转到main.jsp,main.jsp的内容可以跳转到学生和老师列表
UserAction
登录验证拦截器
拦截器配置
如果没有登录,直接访问http://localhost:8080/day03_struts2_demo04/teacherList.action会回到登录页面
案例中的问题
问题:由于我们写了自己的拦截器,默认的拦截器不起作用了。
举个简单的例子,就是不可以接收请求参数
解决办法
a、把默认拦截器加到配置
b、抽取一个拦截器的分组
c、修改默认的拦截器
上面的配置坏处是每一个Action都配置拦截器,我们修改默认的拦截器配置,就可以简便我们的代码
d、过滤不需要登录验证的方法
修改的默认的拦截器后,所有的Action方法都会被拦截,而登录方法是不需要拦截的
解决需要通过AbstractInterceptor类的子类入手,通过查看发现,该类还有一个子类是抽象的,可以通过MthodFilter过滤方法,如图:
解决步骤:
修改拦截器的继承结构
修改struts.xml文件,注册过滤方法
上面遗留的问题:我们在声明时配置了哪些方法需要拦截,哪些方法不需要拦截。但是在没有写动作类和动作方法之前,不确定方法名叫什么。
解决办法:我们需要在使用拦截器的时候给它注入参数。
Struts2的文件上传
Struts也提供了内置标签用于文件上传 ,我们称为文件选择域
与html的标签是一样用的
文件上传的必要前提条件
表单必须是post方法
enctype类型必须为multipart/form-data
简单文件上传
第一步:jsp和action的代码
Action接收到的File对象是一个临时文件,后面需要保存到另外一个路径去
第二步:struts.xml的配置
文件上传的配置
第一:配置文件上传的大小
默认情况下,struts的文件上传只允许在2M内
如果上传一个大于2M的文件,系统会报错,而且必要一个input回显结果
修改struts.xml文件
修改jsp文件
文件上传失败结果
修改文件上传大小限制
思路在struts.xml中改变default.properties文件中的常量。
第二:限制文件上传的类型
思路:通过拦截器设置文件上传的扩展名或者MIME类型
扩展名的错误提示
MIME的错误提示
第三:文件上传错误的中文提示
默认的错误提示信息是在
struts2-core.jar\org.apache.struts2\struts-message.properties中
解决办法:用国际化消息资源包,把对应的key取值改为中文即可。
常用的key值
步骤:
第一步:在src目录创建一个fileuploadmessage.properties文件
第二步:在struts.xml配置国际化
多文件上传
多文件上传,在Action代码中,只需要把接收的文件字段设置为数组即可
文件下载
其实就是一种结果类型(Stream)
测试下载路径
http://localhost:8080/day03_struts2_demo05/download
动态设置下载的文件名
struts的OGNL
OGNL简介
OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,
它是一个单独的开源项目。 Struts2框架使用OGNL作为默认的表达式语言。
OGNL是struts2整合的一个开源项目,所以在struts2中,要想使用OGNL表达式,必须使用Struts2标签库
OGNL相当 于EL表示式,从作用域取数据
OGNL的简单使用
s:property类型于JSP的表达式,把value的值直接输出到页面
jsp表达式:【 】
value的值就是一个OGNL表达式,它不是一个字符串
如果想把value的值当字符串输出,加单引号即可
OGNL的功能
访问对象方法
比如字符串的length方法
访问静态属性
访问静态方法
默认OGNL是禁止静态方法访问的,在default.properties中有个struts.ognl.allowStaticMethodAccess=false,
如想使用,需要在struts.xml文件中配置允许访问静态方法
封装list数据
封装Map数据
struts.xml中写OGNL
前面的文件下载就是一个OGNL表达式
修改
contextMap
动作类的生命周期
明确:
动作类是多例的,每次动作访问,动作类都会实例化。所以是线程安全的。
与Struts1的区别是,struts1的动作类是单例的。
请求数据的存放
问题:
每次请求时,都会产生一些请求数据,这些数据存放到哪里去了?
明确:
在每次动作执行前,核心控制器StrutsPrepareAndExecuteFilter都会创建一个ActionContext和ValueStack对象。且每次动作访问都会创建。
这两个对象存储了整个动作访问期间用到的数据。
并且把数据绑定到了线程局部变量(ThreadLocal)上了。所以是线程安全的。
contextMap 存储数据
Struts2的官方文档对contextMap的说明
注意:
除了value stack之外,全是map,而contextMap也是一个map。
其实就是Map中又封装的Map。(很像dbutils中KeyedHandler封装数据的结构,只是封装数据的结构)
使用s:debug查看contextMap的数据
测试存储数据
contextMap中的数据操作
存数据
利用ActionContext存数据
利用ValueStack存数据
掌握三种获取ValueStack的方法
取数据
用Struts2的标签(OGNL表达式)在JSP上(用的最多)
使用s:property取数据
取contextMap中的数据,需使用#
取contextMap里面ValueStack中对象的属性:直接写属性名
如果遇有对象属性重名,可以通过OGNL表达式,选择查找的起始位置
特殊说明:当s:property不给定value属性时,默认取栈顶对象。
valueStack的其它方法
setValue方法
set方法
掌握压栈的顺序问题
findValue方法
在jsp页面上的调用的都是findValue方法
Struts中对EL取值顺序的改变
默认情况下EL查找顺序
表达式取值必须是servlet四大作用域 由小到大排列为
pageContext【page】 > request > session > servletContext【application】
案例
在Struts中EL表达式的查找顺序的改变
OGNL表达式:
page –> request -> valueStack(根中)-> contextMap -> session -> application
案例
源码分析
内容补充【了解】
Struts标签与OGNL的配合使用
iterator标签
效果:
OGNL投影(了解)
使用过滤条件投影
使用指定属性投影
回顾Struts2中#,$,%符号的使用(重要)
#
a、取contextMap中key时使用,例如
b、OGNL中创建Map对象时使用,例如:
$
a、在JSP中使用EL表达式时使用,例如${name}
b、在xml配置文件中,编写OGNL表达式时使用,例如文件下载时,文件名编码。
struts.xml——>${@java.net.URLEncoder.encode(filename)}
%
在struts2中,有些标签的value属性取值就是一个OGNL表达式,例如
还有一部分标签,value属性的取值就是普通字 符串,例如 ,
如果想把一个普通的字符串强制看成时OGNL,就需要使用%{}把字符串套起来。
例如 。
当然在 也可以使用,但不会这么用。
Struts的其它标签
s:set标签
value:存入map中的值,是一个OGNL表达式
var:存在map中的key
scope:存储的范围application session request page和action
不写scope,默认是action,它是在contextMap中和request中各存一份
s:action标签
s:if标签,s:elseif标签 s:else标签
相当于jstl中的c:choose c:wher c:otherwise
s:url和s:a标签
问题:参数是有一个和中文码未解决
表单小案例
目标
掌握checkboxlist的使用
掌握模型驱动的原理
掌握struts主题的设置
效果:
代码:
模型驱动原理
struts的ModelDrivenInterceptor 这个拦截器来完成的了模型驱动的工作
这个可以从struts-defualt.xml找到这个拦截器
ModelDrivenInterceptor.java源码分析
内部娄模型数据压栈了
struts2中默认主题
默认主题的名称是XHTML,都是在struts的默认属性文件中定义着:default.properties
更改默认的主题方式
第一:在标签内加theme属性
第二:配置全局的theme
防止表单重复提交(拦截器)【面试题】
表单重复提交原理图
1、Servelt的表单重复提交的一种解决方案
session存验证码
比如在登录时,可以通过验证码存在session中来解决【画图】
2、Struts的表单重复提交解决方案
a、使用重定向
b、使用<s:token/>
生成令牌配合token拦截器
此种解决方式不太符合逻辑,它是产生了错误之后再告知用户,应该一直停留在当前界面
c、使用 生成令牌配合tokensession拦截器
