struts2介绍 Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新MVC框架 核心功能 action可以是普通类(POJO) 一次请求对应一个action实例 (请求一次,创建一个action对象) struts不依赖于servlet api 封装请求参数 整合了OGNL(Object Graph NavigationLanguage)对象图形导航语言。比EL表达式更强大 将值传递给视图时,使用"ValueStack"技术。--值栈 类型转换 数据校验 基于Spring AOP思想的拦截器机制,更易扩展 struts资源 struts-2.3.14-all.zip struts目录结构 apps : 应用(demo例子),例如:struts2-blank.war docs : 帮助文档 lib :struts需要的所有jar src : 源码 helloword搭建 1 创建web项目 2 导入最少jar包(/struts/struts-2.3.14) 位置:/apps/struts2-blank.war/WEB-INF/lib 所有jar 注意: 将war扩展名改成zip,进行解压 不要使用 /lib 中的内容 jar介绍 struts2-core-2.3.14.jar 核心jar xwork-core-2.3.14.jar 依赖jar,使用webwork的 ognl-3.0.6.jar 对象图导航语言 freemarker-2.3.19.jar struts2的ui标签模板 commons-lang3-3.1.jar 对java.lang包的增强 commons-fileupload-1.2.2.jar文件上传组件 commons-io-2.0.1.jar 文件上传依赖jar asm-3.3.jar 提供了对字节码操作的功能 asm-commons-3.3.jar 提供了基于事件的表现形式 asm-tree-3.3.jar 提供了基于对象的表现形式 javassist-3.11.0.GA.jar 代码生成工具,用于在运行时扩展java类 3 编写实现类Action public String execute(){ System.out.println("hello action execute 执行..."); return "success"; } 4 编写核心配置文件 名称:struts.xml 位置:src 内容: <?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> <package name="day01" namespace="/primer" extends="struts-default" > <action name="helloAction" class="Action全限定名" method="execute"> <result name="success">/a_hello/demo.jsp</result> </action> </package> </struts> 5 配置struts提供的过滤器web.xml 过滤器类名:StrutsPrepareAndExecuteFilter <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> 启动服务器,访问 http://localhost:8080/项目/primer/helloAction struts执行流程 服务器软件启动时执行过滤器的init方法,加载struts.xml 当每次请求时 执行过滤器的service方法,生成Action类的代理对象,去执行拦截器,然后执行Action中的指定方法, 并返回结果,然后生成模板(jsp),然后返回拦截器,返回过滤器,最后响应给浏览器 struts配置文件 1 default.properties (默认设置配置文件) 位置:struts2-core-2.3.14.jar/org/apache/struts2/default.properties 2 struts-default.xml (stures核心配置文件) 位置:struts2-core-2.3.14.jar/struts-default.xml 内容:struts2编写拦截器,默认拦截器栈等 3 struts-plugin.xml (插件配置文件) 位置:插件jar中 4 struts.xml (程序核心配置文件) 5 web.xml (web配置文件,可以设置初始化参数覆盖struts默认配置) 注意:如果多个文件配置了同一个struts2 常量,则后一个文件中配置的常量值会覆盖前面文件配置的常量值 struts常量 struts框架用于给整个框架配置的固定key struts常量默认配置文件:default.properties 用法: 1.src/struts.xml配置 <constant name="键" value="值"></constant> 2.src/struts.properties,在struts.xml文件之后被加载 键=值 3.web.xml配置过滤器时,配置初始化参数 <init-param> <param-name>键</param-name> <param-value>值</param-value> </init-param> 常见常量 1 struts.i18n.encoding ,用于设置编码 例如:struts.i18n.encoding=UTF-8 2 struts.action.extension 配置struts action的扩展名,多个扩展名之间使用,分割 例如:struts.action.extension=action,, 访问:http://localhost:8080/struts_day01/helloAction 没有扩展名 访问:http://localhost:8080/struts_day01/helloAction.action 指定了扩展名 3 struts.devMode 是否开启开发模式 例如:struts.devMode = true 开启,默认值为false,建议开发时开启 作用 struts.i18n.reload = true ,自动加载国际化资源文件 struts.configuration.xml.reload = true , xml配置文件添加或修改后将自动加载 4 struts.ui.theme struts标签的主题(布局风格) 例如:struts.ui.theme=xhtml ,默认值。其他取值:simple 简单风格,没有任何样式 5 struts.objectFactory 三大框架整合使用 例如:struts.objectFactory = spring ,使用spring创建对象 其它 struts.serve.static.browserCache 设置浏览器是否缓存静态内容,默认为ture,开发阶段建议关闭 struts.multipart.maxSize 上传文件的最大长度,单位字节 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> <!-- 开启开发模式,xml配置文件将自动加载 --> <constant name="struts.devMode" value="true"></constant> <!-- 标签样式为基本样式 --> <constant name="struts.ui.theme" value="simple"></constant> <package name="defaultPackage" namespace="/" extends="struts-default"> <action name="oneAction_*" class="action.OneAction" method="{1}"> <result name="success">/success.jsp</result> </action> </package> </struts> package标签 <package> struts用于管理所有的action name : 给当前的包进行一个唯一的命名,用于提供给其他包继承。 namespace : 给当前的包给一个统一访问的根路径。默认值,/ extends : 确定需要继承的包。 常用 : struts提供默认实现,固定值:struts-default 位置:struts-default.xml文件中 源码:<package name="struts-default" abstract="true"> <action> : 用于配置action类 name : 给当前类进行命名。在当前package内部不能重复。 class : action实现类全限定类名。默认类,ActionSupport method : action类中执行的方法名称。默认值 execute 访问路径:package.namespace + "/" + action.name <result> : 用于配置结果 name : action方法返回值 ,默认值 success type :从acton到jsp方法方式。 常用值(struts-default.xml,<package name="struts-default" abstract="true"><result-types><result-type>) dispatcher,请求转发到jsp页面,默认值 redirect , 重定向到jsp页面 <result name="success" type="redirect">/success.jsp</result> redirectAction ,重定向到指定的action stream ,向浏览器发送流,如图片 重定向到action示例 <result name="success" type="redirectAction"> <param name="namespace">/</param> <param name="actionName">twoAction</param> </result> 或 <result name="success" type="redirectAction">twoAction</result> 注意:下面的写法只能重定向到同一个namespace下的action,不加/ <result name="input">比较特殊,可以配置错误页面,当封装数据发生错误时,返回值为input 通配符 星号* 使用位置: struts.xml配置文件中,<action>的name属性中 作用: 在其他的配置项中可以通过{n}方式获得匹配的内容,n表示星号的位置,从1开始 例如 <action name="*_*_*" class="" method="" 访问url: http:..../part1_part2_part3 ,使用{1}获得part1内容 ; {2} part2 {3} part3 注意:{0} 匹配整个 URI 建议:<action name="userAction_*" method="{1}" ,访问时 userAction_add 或 userAction_delete 感叹号! 使用位置: 在访问action的url中 作用: 可以用!号代替一个符号(只能是符号,且只能是一个) 例: http://localhost:8080/client/UserAction!add include标签 可以将多个struts配置文件整合到一起 <include file=""></include> 编写action POJO 普通类 可以选择 实现接口 Action 提供5个java常量(字段) public static final String SUCCESS = "success"; 表示访问成功 public static final String NONE = "none"; 没有结果集result,没有返回页面。Ajax public static final String ERROR = "error"; 服务器出现错误 public static final String INPUT = "input"; 浏览器发送用户输入的数据有误 public static final String LOGIN = "login"; 没有权限,需要登录 默认方法 public String execute() throws Exception; 可以选择 继承类 ActionSupport 提供默认实现:验证、提示、国际化等 方法结构 public String 名称自定义(){return ...} ,非静态 action访问servlet api 间接的访问servlet三个作用域,相当于只能执行xxxAttribute方法. 工具类ActionContext,action的上下文(action管理者) api 获得对象:ActionContext.getContext() 放置request作用域:actionContext.put(key,value) (其实不是request作用域,而是直接添加到值栈的content中) 放置session作用域:actionContext.getSession().put(key,value) 放置application作用域:actionContext.getApplication().put(key,value) 直接访问servlet api ,获得servlet对象 工具类ServletActionContext,action中servlet的上下文 获取servlet对象 HttpServletRequest request = ServletActionContext.getRequest(); HttpSession session = request.getSession(); ServletContext application = ServletActionContext.getServletContext(); HttpServletResponse response = ServletActionContext.getResponse(); 封装数据 第一种,使用struts提供的ModelDriven机制,将数据封装到指定javabean (推荐) 步骤: 1 实现接口,并提供javabean泛型信息 implements ModelDriven<User> 2 创建成员变量javabean实例,new User() 3 实现方法:getModel,返回javabean实例 拦截器中调用getModel方法获得javabean实例,然后进行数据填充 第二种,将数据封装到action的属性 步骤:给action添加属性(必须提供setter方法) struts会通过setter方法自动填充数据 第三种,将数据封装到action的javabean属性的属性中 步骤: 给action添加属性,javabean对象(可以不new,必须提供给setter和getter方法) 在页面表单元素的name使用ognl表达式直接为javabean中的属性赋值,如user.username,为action的user属性中的username属性赋值 执行流程 页面 文本框name分别为 user.username 和 user.password 则struts倒着填充,先填充user.password, 首先调用user的getter方法 如果对象存在,调用password属性setter方法进行赋值 如果对象不存在,或user的getter方法不存在,将创建User对象,并执行setter方法赋值 填充user.username和上面相同 类型转换 默认实现 字符串 --> 基本类型或包装类型 字符串 --> 时间类型(格式:yyyy-MM-dd , yyyy-MM-dd HH:mm:ss) 字符串 --> 数组 | 集合(将复选框的值封装到数组或集合中) 自定义实现--类型转换器 实现接口:TypeConverter,建议继承默认实现类:DefaultTypeConverter 复写方法:convertValue(java.lang.Object value, java.lang.Class toType) 浏览器 --> 服务器 (提交 String[]-->Date) value ,浏览器提交的内容,String[] 通过request.getParameterValues("birthday")得到的 toType , 需要转换的类型 java.util.Date 服务器 --> 浏览器 (struts标签 回显 Date-->String) value , 标签回显时需要提供的数据 ,java.util.Date toType, 浏览器需要的数据(字符串进行显示) , java.lang.String 注册转换器-添加配置文件 注册全局转换器,当前web项目都可以使用(对所有封装数据方式有效) 文件名称:xwork-conversion.properties 文件位置:src 文件内容:需要转换的类型全限定类名=实现类全限定类名 例如:java.util.Date = util.MyDateConverter 局部转换器,只对当前action有效。 文件名称:Action类名-conversion.properties 文件位置:与action同包 文件内容:action属性=实现类全限定类名 注意:只能使用action属性封装数据的方式,向javaBean封装数据时失效 自定义日期转换器示例 页面 <s:form namespace="/" action="oneAction" method="post"> <s:textfield name="birthday" label="生日"></s:textfield> <s:submit value="提交"></s:submit> </s:form> action.UserAction 提供一个birthday属性,并提供getter和setter方法 转换器实现类 public class MyDateConverter extends DefaultTypeConverter { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");//日期格式化工厂 @SuppressWarnings("rawtypes") public Object convertValue(Object value, Class toType) { try { //浏览器 --> 服务器,String[] --> Date if(java.util.Date.class == toType){ String[] values = (String[]) value; String birthday = values[0]; //2014/5/15 java.util.Date date = dateFormat.parse(birthday); return date; } //服务器 --> 浏览器,Date --> String if(String.class == toType){ java.util.Date date = (Date) value; String birthday = dateFormat.format(date); return birthday; } return null; } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(); } } } 注册转换器(二选一) 全局:src/xwork-conversion.properties java.util.Date=util.MyDateConverter 局部:src/action/UserAction-conversion.properties birthday=util.MyDateConverter 数据校验 将浏览器已经封装到javabean中的数据进行合理校验。 校验方式 手动方法 校验action全部方法 必须实现接口Validateable,实现validate方法 validate方法会在所有方法执行之前执行 ActionSupport类已实现此接口 校验action单个方法 添加方法,方法名为validate+验证方法名称,例 add --> validateAdd 验证方法将在方法执行之前先执行 注意: 先执行单个校验,再执行全部校验。 在action中使用:this.addFieldError("username", "此处错误"); 添加错误信息,使目标方法不能继续执行(全局校验方法还会执行) 手动验证时需要自己编写java代码进行验证 xml配置方法 添加xml配置文件即可,xml文件位置:action类同包 校验action全部方法: 文件名称:action类名-validation.xml 校验action单个方法: 文件名称:action类名-action配置name-validation.xml action配置name 是<action>标签中的name属性的值 例:userAction_add --> UserAction-userAction_add-validation.xml 如果使用了通配符,如userAction_*,则按实际请求的路径写 xml文件 约束DTD位置:xwork-core-*.jar/xwork-validator-1.0.3.dtd 基本内容: <!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"> <validators> <!-- 要验证的字段 --> <field name=""> <!-- 验证器 --> <field-validator type=""> <!-- 验证器参数,没有就不写--> <param name="">值</param> <!-- 不符合要求显示的消息提示 --> <message></message> </field-validator> </field> </validators> 注意:在<message>中可以使用${param的name}引用上面指定<param>的值 struts提供验证器 <field-validator type=""> type的值 所有验证器位置:xwork-core-*.jar/最后一个包 /com/opensymphony/xwork2/validator/validators/default.xml 常用验证器 required, requiredstring, int, date, expression, fieldexpression, email, url, stringlength, regex 验证器的参数看源码setter方法 校验文件示例 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"> <validators> <!-- 用户名 --> <field name="username"> <!-- 必填 --> <field-validator type="requiredstring"> <message>用户名不能为空</message> </field-validator> <!-- 长度 --> <field-validator type="stringlength"> <param name="minLength">3</param> <param name="maxLength">12</param> <message>用户名长度应为${minLength}-${maxLength}位</message> </field-validator> </field> <!-- 密码 --> <field name="password"> <!-- 必填 --> <field-validator type="requiredstring"> <message>密码不能为空</message> </field-validator> <!-- 长度 --> <field-validator type="stringlength"> <param name="minLength">6</param> <param name="maxLength">12</param> <message>密码长度应为${minLength}-${maxLength}位</message> </field-validator> </field> <!-- 确认密码 --> <field name="repassword"> <!-- 必填 --> <field-validator type="requiredstring"> <message>确认密码不能为空</message> </field-validator> <!-- 匹配 --> <field-validator type="fieldexpression"> <param name="expression">repassword==password</param> <message>密码与确认密码不一致</message> </field-validator> </field> <!-- 年龄 --> <field name="age"> <!-- 必填 --> <field-validator type="required"> <message>年龄不能为空</message> </field-validator> <!-- 范围 --> <field-validator type="int"> <param name="min">3</param> <param name="max">100</param> <message>请输入正确的年龄</message> </field-validator> </field> <!-- 生日 --> <field name="birthday"> <!-- 必填 --> <field-validator type="required"> <message>生日不能为空</message> </field-validator> <!-- 范围 --> <field-validator type="date"> <param name="min">1930-01-01</param> <param name="max">2010-01-01</param> <message>请输入正确的生日</message> </field-validator> </field> <!-- 邮箱 --> <field name="email"> <!-- 必填 --> <field-validator type="requiredstring"> <message>邮箱不能为空</message> </field-validator> <!-- 格式 --> <field-validator type="email"> <message>邮箱格式不正确</message> </field-validator> </field> <!-- 电话 --> <field name="tel"> <!-- 必填 --> <field-validator type="requiredstring"> <message>电话不能为空</message> </field-validator> <!-- 格式 --> <field-validator type="regex"> <param name="regexExpression">((\d{11})|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})|(\d{4}|\d{3})-(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1})|(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1}))$)</param> <message>电话格式不正确</message> </field-validator> </field> </validators> 校验执行步骤:先进行数据封装-->执行xml配置的数据校验-->执行单个方法校验手动方法-->执行全部方法校验手动方法 拦截器 拦截器栈:struts将多个拦截器组合成一个整体,存在先后顺序。 默认拦截器:defaultStack 拦截器,必须实现Interceptor接口,与过滤器filter相似。 interceptor 拦截器:struts特有的功能,依赖于struts框架。放行:invocation.invoke(); filter 过滤器:java web 提供过滤器程序。放行:chain.doFilter(); 默认拦截器执行顺序(了解) modelDriven 获得javabean,将javabean压入到root栈顶,等待数据填充 fileUpload 如果有则获取上传文件 params 数据填充,将数据依次填充到root栈的对象的属性中 conversionError 校验封装数据时是否存在转换异常 validation 校验 workflow 检测是否有错误,有错误返回"input",没错误则放行 自定义拦截器 编写实现类 实现Interceptor接口,重写intercept方法 放行:invocation.invoke(); 获得请求的action类对象:invocation.getAction(); 添加错误信息:invocation.getAction().addFieldError("username", "此处错误"); 返回值会去struts.xml中寻找匹配结果 注册拦截器栈 位置:<package>中,<action>之前 <interceptors> <!-- 注册拦截器 --> <interceptor name="拦截器名称" class="拦截器实现类"></interceptor> <!-- 注册拦截器栈 --> <interceptor-stack name="拦截器栈名称"> <!--默认拦截器栈--> <interceptor-ref name="defaultStack"></interceptor-ref> <!--追加自己的拦截器--> <interceptor-ref name="拦截器名称"></interceptor-ref> </interceptor-stack> </interceptors> 使用拦截器栈 仅在指定action中使用 位置:<action>中 内容:<interceptor-ref name="拦截器栈名称"></interceptor-ref> 一个包内所有action使用 位置:<package>中,<action>之前,<interceptors>之后 内容:<default-interceptor-ref name="拦截器栈名称"></default-interceptor-ref> i18n 国际化资源文件:baseName[_语言_国家|地区].properties 例如:message_zh_CN.properties struest默认国际化配置文件 位置: struts-core.jar /org/apache/struts2/struts-messages.properties xwork-core.jar /com/opensymphony/xwork2/xwork-messages.properties 全局字段错误提示消息(不建议修改) xwork-messages.properties中 xword.default.invalid.fieldvalue=Invalid field value for field "{0}". 上面只是字段错误提示消息,其它错误提示消息在默认配置文件其它位置查找 自定义资源文件 位置 action同包,对指定action有效 文件名:action类名.properties , baseName是action类名 action父包,所有的子包都有效 文件名:package.properties , baseName是"package"固定串,不是包名 全局配置 位置任意,名称任意 需要在struts.xml配置常量 struts.custom.i18n.resources=baseName,baseName2 -->多个资源文件使用逗号分隔 message,cn/itcast/message 即<constant name="struts.custom.i18n.resources" value="baseName|包/baseName"></constant> 内容 invalid.fieldvalue.字段名称=提示信息 名称=值 //以invalid.fieldvalue开头的键,为字段错误提示消息,当字段输入错误时,自动提示 //其它错误消息固定key在struest默认国际化配置文件中查找 使用 可由ActionSupport类中的getText(key)获得value 可使用sturts的国际化标签在页面显示 以invalid.fieldvalue开头的键,为字段错误提示消息,当字段输入错误时,自动提示 sturts的国际化标签 <s:i18n name="cn/itcast/msg"> --> 加载指定位置的国际化资源文件,msg为文件名,不加后缀 <s:text name="studentInfo"> --> 获得指定key的value <s:param>四儿</s:param> --> 给第一个位置设置值,用于填充获得内容的{n}位置 </s:text> </s:i18n> 文件上传 回顾 浏览器 <form method="post" enctype="multipart/form-data"> <input type="file" name="imageName"/> <input type="submit" /> 服务器 1 手动解析,request.getInputStream() ,获得请求体所有内容 2 commons fileupload,第三方 3 servlet 3.0 Part对象,使用注解 4 struts提供上传支持 struts文件上传 必须提供三个属性setter方法获得所有内容 File image; //记录文件内容,image为表单提交时file控件name的值 String imageFileName; //记录文件名称,image同上,FileName为固定字符串 String imageContentType;//记录文件类型,image同上,ContentType为固定字符串 多文件上传,将以上三个属性的类型变为数组或集合即可.注意:多文件上传表单中多个file控件的name应一致 文件拷贝:FileUtils.copyFile(File srcFile,File destFile); --commons-io.jar中的工具类,struts2自带 方法完成后struts会自动将原来的文件删除 struts文件上传常量 struts.multipart.parser=jakarta ,确定struts解析文件上传方法,apache commons fileupload struts.multipart.maxSize=2097152 ,默认大小,2M ,注意不能写 1024*1024*2 扩展名限制 在struts.xml的<action>中添加 <interceptor-ref name="defaultStack"> <param name="fileUpload.allowedExtensions">.jpg,.png</param> </interceptor-ref> 上面设置的是允许的扩展名,不符合会返回input 上面是给某个拦截器设置参数的方式,fileUpload为拦截器名称,allowedExtensions为属性名称 文件上传action示例 public class UserAction extends ActionSupport { private File image; //表单名称为image private String imageFileName; private String imageContentType; public void setImage(File image) { this.image = image; } public void setImageFileName(String imageFileName) { this.imageFileName = imageFileName; } public void setImageContentType(String imageContentType) { this.imageContentType = imageContentType; } public String upload(){ try { String dir = "/uploadFile";//文件存放路径 dir = ServletActionContext.getServletContext().getRealPath(dir); File destFile = new File(dir,imageFileName); FileUtils.copyFile(image, destFile);//原来的文件自动删除 } catch (Exception e) { System.out.println("文件拷贝失败"); } return SUCCESS; } } 文件下载 回顾 将文件资源流发送到浏览器,response.getOutputStream() 设置响应头:content-disposition = attachement;filename=1.jpg 发送流 步骤 1.在action中 添加一个InputStream属性,并提供get方法,将要发送的数据放到属性中 添加一个String属性fileName,并提供get方法,将文件名称放到属性中(名称不是固定的,是和下面对应的) 2.在struts.xml中配置result <result name="success" type="stream"> <param name="inputName">属性名称</param> <param name="contentDisposition>attachment;filename=${fileName}</param> </result> 说明 inputName设置action的流属性名称 contentDisposition设置响应头,说明文件时需要下载的 ${fileName}表示在action类中获取fileName属性的值,所以在action中要提供fileName属性 可选操作:<param name="contentType>${contentType}</param> contentType设置文件类型,需要在action中提供属性,一般赋值方法:contentType=ServletActionContext.getServletContext().getMimeType(fileName); 文件名称中文乱码问题还是fileName = new String(fileName.getBytes("gbk"),"iso8859-1"); 如果用户取消下载会抛异常,可使用插件解决struts2-sunspoter-stream-1.0.zip ognl表达式 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,比EL更强大的表达式语言(开源项目) Struts2框架使用OGNL作为默认的表达式语言。 在JSP中执行OGNL表达式需要struts标签,<s:property>将ognl表达式的结果发送到浏览器 ,等价于<c:out/> 优势 支持对象方法调用 支持类静态的方法调用和常量访问 支持赋值操作和表达式串联 ,user.username 访问OGNL上下文(OGNL context)和ActionContext; 操作集合对象。 可以直接new一个对象 语法 对象方法调用 <s:property value="'abc'.length()"/> <s:property value="page"/> //会访问action中的属性,调用getPage方法(如果存在的话) 类静态的方法调用和常量访问 表达式的格式: @[全限定类名]@[方法名 | 常量名] <s:property value="@java.lang.Math@PI"/> <s:property value="@java.lang.Math@PI"/> 默认情况静态方法不能执行,需要设置struts常量 struts.ognl.allowStaticMethodAccess=false 支持赋值操作和表达式串联 <s:property value="#page.data[0].birthday"/><br> <s:property value="#page.data[0].birthday='2000-1-1'"/><br> 访问OGNL上下文(OGNL context)和ActionContext; 操作集合对象。 可以直接new一个对象 特殊符号 # : 通过key获得context值,可以用于创建对象 创建List:{'元素1','元素2','元素3'} 创建Map:#{'key1':'value1','key2':'value2'} % : 在struts标签中确定语法 %{ognl表达式}:表示里面的内容必须按照ognl表达式去执行 %{'字符串'}:表示里面的内容为普通字符串 $ : 在配置文件struts.xml 和 国际化资源文件*.properties 使用${ognl表达式},从值栈中获取内容。 ValueStack 值栈:struts用于传递数据的对象。 一个action对应一个值栈,贯穿整个action生命周期。在action创建之后就有一个值栈,一次请求对应一个action和一个值栈。请求结束,action销毁,值栈也销毁。 struts将值栈对象放置到servlet 的request域中 值栈实际上是一个接口,在Struts2中利用ognl时,实际上使用的是实现了该接口的OgnlValueStack类.所以,struts2的值栈对象其实是OgnlValueStack类的一个实例 获得值栈 1 通过Action上下文:ActionContext.getContext().getValueStack() 2 通过指定的属性名称获得:ServletActionContext.getRequest().getAttribute("struts.valueStack"); 值栈结构 root和context是OgnlValueStack实例的两个属性 root : 类型为CompoundRoot,extends ArrayList 底层是List。称为:对象栈,只能存放对象,对象不能添加名称。 提供了压栈和出栈的操作(方法),模拟栈结构. struts2默认将当前action实例放入到栈顶 context:类型为Map<String,Object> ,可以给保存数据添加名称,通过名称获得指定对象。 struts规定了若干固定key,可以间接对servlet不同的域进行操作 application ,application作用域内容。Map<属性名称,属性值> session,session作用域内容。Map<属性名称,属性值> request,request作用域内容。Map<属性名称,属性值> attr,依次的page/request/session/application作用域的所有值。Map<属性名称,属性值> parameters,请求参数 ,Map<name,values> root操作 root就是平常所说的值栈 ValueStack vs = ActionContext.getContext().getValueStack(); 存放数据 push(Object obj) //压栈,将对象压入到栈顶 set(key,value) //将key-value存入栈顶的Map中(栈顶如果不是Map,则先创建,再将Map压入栈顶) 获得数据 <s:property value="名称" /> //通过指定属性获得第一个值,匹配root对象栈中对象的属性或Map的key. <s:property value="top" /> //获得栈顶的数据 <s:property value="[2]" /> //从第三个开始,将之后的所有内容组成一个新的栈,并输出 <s:property value="[2].top"> //获得新栈的第一个值 context操作 context是一个Map,可以间接对servlet不同域进行操作 ActionContext.getContext()可以获得ActionContext对象 ActionContext对象的put和getSession等方法其实是向context中添加和获得数据 存放数据 ActionContext.getContext().put(key,value) ,直接添加到context对象中,不会存到request域中,不过用request可以取到(进行了方法增强) ActionContext.getContext().getSession().put(key,value) , 添加到context对象固定key为session对应的Map中,会存到session作用域中 ActionContext.getContext().getApplication().put(key,value) 添加到context对象固定key为application对应的Map中,会存到application作用域中 获得数据 通过 #key获得数据, <s:property value="#session.person.personName"/> 获取数据的特殊方法 <s:property value="gf"/> 底层使用findValue(gf) 先从root对象栈中获取内容 如果没有,再从content获取 <s:property value="#request.gf"/> <br/> request被struts使用装饰者默认进行修改(方法增强) request实现类 org.apache.struts2.dispatcher.StrutsRequestWrapper ,<%=request.getClass() %> struts对request的getAttribute方法进行增强 先从servlet 的request作用域获得数据 如果没有,再从值栈获得,执行findValue 先从root对象栈中获取内容 如果没有,再从content获取 使用标签查看值栈 <s:debug/> 因为request.getAttribute方法被增强,可以获取到值栈中的值,所以el表达式也可以获取值栈中的值 struts标签 好处 : 回显,自动提示错误消息(在每个表单元素上方添加<s:fielderror>标签),url自带JSESSIONID,布局 引入标签库 : <%@ taglib uri="/struts-tags" prefix="s" %> 常用标签 <s:property> 获取值栈中的数据 value 表达式 default 默认值,当表达式的值为空时,会显示默认值 escapeHtml 是否进行html转义 <s:set> 将数据放置到作用域 <s:url> namespace action的namespace action action的name var 变量名 流程控制标签 <s:iterator> 遍历 value 要遍历的数据 var 将当前压入栈顶 begin 开始值 end 结束值 status 将遍历信息存储在context中,可用属性count,index等 如 #status值.index 注意:每次循环开始默认将集合中的每一个对象压入到栈顶,下一次循环弹出.使用var,可同时在context中起名存储 <s:if><s:elseif><s:else> test 条件 表单标签 在表单标签中class和style属性用cssClass和cssStyle属性指定 在表单标签中使用theme属性修改标签模板,则包含的标签都会使用统一的模板,如theme="simple" <s:fielderror> 显示用户输入的错误提示 <s:actionerror> 显示action的错误提示 <s:form> 表单 namespace struts.xml中<package>的namespace action struts.xml中<action>的name enctype 和普通form相同 method 和普通form相同 <s:submit> 提交按钮 value 显示文本 <s:textfield> 文本框 name 同原来的name label 前面的文本,simple风格无效 <s:password> 密码框 showPassword 显示value属性,默认为false,不显示 <s:hidden> 隐藏域 <s:date> 格式化显示时间 name 要显示的属性 format 格式 表单标签2 <s:checkboxlist> 复选框列表 name 必须 list 取值为list集合或map集合,使用ognl表达式 如果取值为list,则value和显示的数据一致 如果取值为map,则value为map的key,显示的数据为map的value value 默认选中,通常要使用%{值} <s:radio> 单选框列表 使用方法同<s:checkboxlist> <s:select> 下拉列表 使用方法同<s:checkboxlist> headerKey 默认头的value headerValue 默认头的显示文本 listKey value为集合中的javaBean的哪个属性 listValue 显示的数据为集合中的javaBean的哪个属性 示例 <s:select list="#{'1':'小班','2','大班'}" name="edu" headerKey="" headerValue="--请选择--"> </s:select> 或 <s:select list="#request.sexList" name="sexID" listKey="ddlCode" listValue="ddlName" headerKey="" headerValue="请选择"> </s:select> 注意 在<s:if>标签的test属性中,注意test="a==1"和test="a=='1'",两者有截然不同的效果 在<s:set>的value属性中,将变量赋值为1:value="%{'1'}",不能为value="1" token(struts令牌机制) 回顾:一次性验证码原理 token机制,防止表单重复提交。 (验证码防止表单重复提交已经解决方案) 1.服务器缓存一份数据,浏览器也要缓存相同一份数据 2 浏览器提交数据,自动获得服务器缓存的数据 比较,并删除服务器缓存数据 相同,正常请求 不相同,重复提交 使用token 1 在表单中添加一个标签<s:token/> (会生成一个随机数,保存到session,同时在页面生成一个隐藏域,记录值) 2 在struts.xml中配置,添加struts的token拦截器 (拦截器做的事:获取隐藏域的value与session对比,并删除session的数据) 例: 注册新拦截器栈 在<package>标签中添加 <interceptors> <interceptor-stack name="tokenStack"> <interceptor-ref name="defaultStack"></interceptor-ref> <interceptor-ref name="token"></interceptor-ref> </interceptor-stack> </interceptors> 使用新拦截器栈 在<action>标签中添加 <interceptor-ref name="tokenStack"></interceptor-ref> 配置token错误处理页 <result name="invalid.token>/form.jsp</result> 在错误处理页可以使用<s:actionerror>标签 显示错误提示
struts
最新推荐文章于 2022-04-24 13:50:01 发布