首先介绍下Action处理请求参数 1,属性驱动 1)基本数据类型字段驱动 private String username; private String password; 然后提供字段的getter,setter方法 2)域对象字段驱动 将上述字段封装成对象 User user = new User(); //前端页面提供的属性要与对象字段要一致,user.name 然后提供对象的getter,setter方法 2,模型驱动 实现ModelDriven<User>接口 User user = new User(); @Override public User getModel() { return user; } ********************************************************************************************* 再讲讲常量的配置 Struts2常量的配置有3种方式 1,在struts.xml文件中使用<constant>元素配置常量 <constant>元素中两个必填的属性,name和value 2,在struts.properties文件中配置常量,该文件由自己创建 3,在web.xml文件filter中通过<init-param>元素配置常量 <init-param> <param-name></param-name> <param-value></param-value> </init-param> 配置文件的加载顺序 1,default.properties 2,struts.xml 3,struts.properties 4,web.xml 后加载文件会覆盖前面的文件 *********************************************************************************************** 任何action类继承了ActionSupport都要声明serialVersionUID private static final long serialVersionUID=1L; *********************************************************************************************** Action访问ServletAPI的三种方式 1,通过ActionContext类访问 ActionContext context = ActionContext.getContext(); context.put("name","王科一"); context.getApplication().put("name","王科一"); context.getSession().put("name","王科一"); 2,通过特定接口访问 通过ActionContext类可以访问ServletAPI,但是无法提供Servlet实例 实现以下接口,即可访问对应的实例 ServletRequestAware,实现该接口可以直接访问Web应用的HttpServletRequest实例 ServletResponseAware,实现该接口可以直接访问Web应用的HttpServletResponse实例 SessionAware,实现该接口可以直接访问Web应用的HttpSession实例 ServletContextAware,实现该接口可以直接访问Web应用的ServletContext实例 HttpServletRequest request; @override public void setServletRequest(HttpServletRequest request) { this.request=request; } 然后在execute()方法中使用request对象的方法了,request.setAttribute("name","王科一"); 最后使用EL表达式访问,${requestScope.name} 3,通过ServletActionContext访问 上述通过接口访问实例的方法,根本就没有使用Struts2,Struts2自身将上述操作整合后 通过ServletActionContext就可访问Servlet实例 ServletActionContext.getRequest().setAttribute("name","王科一"); ****************************************************************************************************** struts.xml中action的Result结果类型的配置 数据的传递由两种,一种是请求转发,一种是重定向,在struts2中action也有这两种方式 处理action之间的数据传递有两种,处理页面之间的数据传递有两种 action之间的:chain,redirectAction, type属性为chain时,被跳转的action中仍能获取上个页面的值,如request type属性为redirectAction时,则不能获取上个页面的值 页面之间的数据传递:dispatcher,redirect type属性为dispatcher时,用来转向页面,处理jsp,是默认的类型 type属性为redirect时,重定向页面,被跳转的页面丢失传递的信息 ***************************************************************************************************** 下面讲struts2的拦截器,开发者需要定义拦截器的实现类,并把他们配置在struts.xml中即可 拦截器的定义: <interceptor name="拦截器名字" class="拦截器实现类"> <param name="需要传入参数的名称">传入参数的值</param> </interceptor> 拦截器链/栈的定义: <interceptors> <interceptor name="interceptor1" class="interceptorClass"></interceptor> <interceptor name="interceptor2" class="interceptorClass"></interceptor> <interceptor-stack name="myStack"> <interceptor-ref name="interceptor1"></interceptor-ref> <interceptor-ref name="interceptor2"></interceptor-ref> </interceptor-stack> </interceptors> 默认拦截器是指在一个包下默认进行的拦截器,每个包只有一个默认拦截器,该拦截器对包下所有action都有效 默认拦截器的声明: <default-interceptor-ref name="myStack"></default-interceptor-ref> myStack必须是已有的拦截器链或者普通单个拦截器 struts2默认拦截器栈: <default-interceptor-ref name="defaultStack"/> struts2默认action类: <default-class-ref class="com.opensymphony.xwork2.ActionSupport" /> 自定义拦截器 实现自定义拦截器有两种方式 1,实现Interceptor接口 2,继承AbstractInterceptor类,并实现intercept方法,此方式常用 自定义拦截器的使用过程 1,用户自定义的拦截器类,必须实现Interceptor接口或继承AbstractInterceptor类 2,需要在struts.xml中定义自定义拦截器 3,在struts.xml中的action中使用拦截器 最后,在struts.xml中定义的拦截器要放在package最前面,即要放在action前面 ****************************************************************************************************** 今天讲讲Struts2标签库 struts2标签库的使用需要导入taglib指令 <%@taglib prefix="s" uri="/struts-tags" %> 下面挑几个常用的标签学习一下: 1,<s:iterator>,遍历标签 <s:iterator>标签属性: 属性 默认值 类型 描述 begin 0 Integer 迭代数组或集合的起始位置 end 数组或集合的长度大小 Integer 迭代数组或集合的结束位置 减1,假如step为负则为0 status false Boolean 迭代过程中的状态 step 1 Integer 指定每次迭代后索引增加的值 value 无 String 迭代的数组或集合对象 var 无 String 将生成的Iterator设置为page范围的属性 如果标签中指定了status属性,那么通过该属性可以获取迭代过程中的状态信息,如元素数,当前索引值等 通过status属性获取状态信息如下: 方法 说明 st.count 返回当前已经遍历的集合元素的个数 st.first 返回当前遍历元素是否为集合的第一个元素 st.last 返回当前遍历元素是否为集合的最后一个元素 st.index 返回遍历元素的当前索引值 st.even 返回当前遍历的元素的索引是否为偶数 st.odd 返回当前遍历的元素的索引是否为奇数 例子: <s:iterator value="#request.student2" status="st" > <tr> <td><s:property value="stu_id"/></td> <td><s:property value="stu_name"/></td> <td><s:property value="stu_sno"/></td> <td><s:property value="stu_department"/></td> <td><s:property value="stu_hometown"/></td> <td><s:property value="stu_mark"/></td> <td><s:property value="stu_email"/></td> <td><s:property value="stu_tel"/></td> <td><s:property value="stu_sex"/></td> <td><a href="update.jsp?stu_id=${st.count}">修改</a></td> </tr> </s:iterator> 其中,#使用了OGNL表达式,取request中的student2对象进行遍历 2,<s:file> <form action="" method="" enctype="multipart/form-data"> <s:file name="" label="" /> <s:submit value="上传"/> <s:reset value="重置"/> </form> *************************************************************************************************************** 下午来讲讲OGNL表达式 OGNL的操作实际上就是围绕着OGNL结构的三个要素而进行的,分别是表达式,根对象,上下文环境 表达式 表达式就是一个带有语法含义的字符串,这个字符串规定了操作的类型和操作的内容 根对象 OGNL的getValue()方法中的第二个参数就是Root对象,Root可以理解为OGNL的操作对象, 表达式规定了“”“"做什么",而Root对象则规定了”“"对谁操作" 例子”: 用java来导航访问 System.out.println("java方式-"+user.getGroup().getBranch().getBranchId()); 用OGNL表达式访问 System.out.println(“”"OGNL方式-"+(String)Ognl.getValue("group.branch.branchId"),user); 上下文环境 设置了Root对象,OGNL可以对Root对象进行取值或写值等操作,Root对象所在环境就是OGNL的上下文环境 上下文环境规定了OGNL的操作”“"在哪里进行",上下文环境Context是一个Map类型的对象,在表达式中访问Context中的对象 需要使用#号加上对象名称,即”“"#对象名称"的形式“” 例子: user.setUsername("王科一"); Map context = new HashMap(); context.put("u",user); System.out.println("获取context中数据结果为:"+(String)Ognl.getValue("#u.username",context,user)); 使用OGNL访问对象方法和静态方法 1,使用OGNL访问实例对象方法 语法: Ognl.getValue("方法名().方法名()",对象名); 例子: System.out.println("username = "+(String)Ognl.getValue("getUsername()",user)); System.out.println("groupName = "+(String)Ognl.getValue("getGroup().getName()",user)); 2,使用OGNL访问静态方法 首先需要开启访问类静态方法的支持 <constant name="struts.ognl.allowStaticAccess" value="true"/> Ognl表达式需要配合Struts2标签才可以使用 语法: <s:property value="@全类名@变量名"/> <s:property value="@全类名@方法名"/> 全类名就是类的绝对路径 ognl再补充 当我们从值栈中取值的时候需要使用ognl,如果是取list集合中的值时,需要在页面中遍历集合 例子 <s:iterator value="list" var="u"> //使用ognl表达式遍历 <s:property value="#u.name"/> </s:iterator> <c:forEach items="${list}" var="u"> //使用el表达式遍历 ${u.name} </c:forEach> 如果是map集合,则实例如下 <s:iterator value="map" var="u"> //使用ognl表达式遍历 <s:property value="#u.value.name"/> </s:iterator> <c:forEach items="${map}" var="u"> //使用el表达式遍历 ${u.value.name} </c:forEach> *************************************************************************************************************** 值栈 值栈就是OGNL表达式存取数据的地方,struts2为每个请求创建单独的值栈,值栈封装了一次请求所需要的所有数据 值栈可以作为一个数据中转站,用于在前台-后台之间传递数据,最经典的做法就是将Struts2标签与OGNL表达式结合 每个acton类的对象都拥有一个值栈对象,值栈的生命周期随着request的创建而创建,随着request的销毁而销毁 值栈的获取方式 1,在request中获取值栈 ValueStack valueStack = (ValueStack) ServletActionContext.getRequest().setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY); 2,在ActionContext中获取值栈 ValueStack valueStack = ActionContext.getContext().getValueStack(); 值栈的内部结构 ObjectStack(对象栈):是CompoundRoot类型,用Arraylist定义,Struts2把动作和相关对象压入ObjectStack中,push() ContextMap(Map栈):是OgnlContext类型,是个Map集合,Struts2把各种各样的映射关系(一些Map类型的对象)压入ContextMap中,set() 相关映射具体如下: parameters:该Map中包含当前请求的请求参数 request:该Map中包含当前request对象中的所有属性 session:该Map中包含当前session对象中的所有属性 application:该Map中包含当前application对象中的所有属性 attr:该Map按如下顺序来检索某个属性,request,session,application struts2引入值栈最主要的目的,就是在页面与action之间进行数据交换,采用以下两种方式交换数据时,struts2会将对象自动存储到valueStack中 属性驱动:每次请求访问action对象时,action中的属性对象会被自动压入ValueStack中 <s:property value="p3.name"/><br> <s:property value="p3.price"/> 模型驱动:action如果实现了ModelDriven接口,那么ModelDrivenInterceptor拦截器会生效,会将model对象压入到ValueStack中 对象存储到ValueStack中后,页面所需的数据可以直接从ValueStack中获取 <s:property value="model.name"/> <s:property value="model.price"/> 还可以使用el表达式访问值栈中的数据 ${model.name},${model.price} 取值的规则 从root栈中获取值栈中的值,即对象栈 <s:property value="表达式"/> 从context栈中获取值栈中的值,即Map栈 <s:property value="#表达式"/> 值栈再详解 1、取出ValueStack中第一个name属性的值 借助s:property标签来获取。 取值栈中的数据:直接写属性名称,获取的就是属性值。不需要使用#号。 OGNL表达式在获取值栈数据时,默认情况下都是从栈顶逐个对象往下寻找,寻找属性一致的,把属性值取出来。只要找到之后,就不再继续寻找。 OGNL表达式获取值栈中的数据,只能是根据属性名称获取属性值。 Name:<s:property value="name"/><br/> Age:<s:property value="age"/> 2,获取指定位置属性值 使用的OGNL表达式是:[x].name x指的是值栈中对象的索引位置。 Name1:<s:property value="[0].name"/><br/> Name2:<s:property value="[1].name"/><br/> 3,当我们使用s:property标签时,没有使用value属性,获取的是栈顶对象。 当我们不操作值栈时,默认的栈顶对象是:当前执行的动作类 <s:property/> 4,OGNL表达式在OGNL上下文中查找数据时涉及的方法 不管是在Map中找,还是在值栈中找,对应的方法只有一个。 ValueStack的对象中的findValue(String expr)方法。参数的含义:是一个OGNL表达式 ActionContext context = ActionContext.getContext(); ValueStack vs = context.getValueStack(); Object o1 = vs.findValue("name"); out.println("name is "+o1); Object o2 = vs.findValue("[1].name"); out.println("name1 is "+o2); Object o3 = vs.findValue("#session.sessionMap3"); out.println(o3); Object o4 = vs.findValue("#application.applicationAttr"); out.println(o4); push和set方法 ValueStack对象使用push()方法和set方法将数据对象放入栈顶 ****************************************************************************************************************** struts2的文件上传和下载 要使用struts2进行文件上传,首先要将form表单的enctype属性值设置为multipart/form-date,文件上传还需要<s:file>标签 要放在<s:form>标签中 <form action="" method="" enctype="multipart/form-data"> <s:file name="" label="" /> <s:submit value="上传"/> <s:reset value="重置"/> </form> 除了要对表单form进行设置,其action类的编写也有相应的规定 private File xxx; //用户上传的文件,xxx要与<s:file>标签的name属性值要一致 private String xxxFileName; //上传文件的文件名 private String xxxContentType; //上传文件的类型 最后需要在struts.xml中加入文件过滤器拦截fileUpload,其本身已经在struts-default中已经配置好了,使用时需要增加一些参数 <action name="fileUpload" class="top.kubino1.fileUpload.FileAction"> <result name="success">/success.jsp</result> <interceptor-ref name="defaultStack"> <!-- 限制文件上传最大值为4M--> <param name="fileUpload.maximumSize">4194304</param> <param name="fileUpload.allowedExtensions">.txt,.doc,.jpg</param> <param name="fileUpload.allowedTypes">text/plain,image/jpeg</param> </interceptor-ref> </action> 文件的下载 struts.xml中增加action的配置,其代码如下: <action name="download" class="top.kubino1.fileUpload.DownLoad"> <result name="success" type="stream"> <!--文件类型--> <param name="contentType">${contentType}</param> <!--指定文件名--> <param name="contentDisposition">//这里是分号 attachment;filename=${fileName} </param> <!--输入流--> <param name="inputName">downFile</param> </result> </action> action类中代码如下: private String fileName; public String getFileName() { return fileName; } public void setFileName(String fileName) { try { fileName = new String(fileName.getBytes("iso8859-1"),"utf-8"); } catch (UnsupportedEncodingException e) { System.out.println("编码转换异常"+e); } this.fileName=fileName; } public InputStream getDownFile() { return ServletActionContext.getServletContext().getResourceAsStream("/upload/"+fileName); } @Override public String execute() throws Exception { return ActionSupport.SUCCESS; } 只需要在字段fileName的setter方法中进行字符的转换 jsp页面的代码如下: <a href="download.action?fileName=英语.txt" download="英语.txt">下载英语资料</a> download属性则要求浏览器直接下载文件,而不是在浏览器中打开,其值表示下载的文件名跟传参的值没有关系 ****************************************************************************************************************** struts2的类型转换器 Struts2在接收表单提交过来的参数时,但表单提交过来的数据统统是字符串,意味着Struts2默认给我们提供了各种类型转换 在实际开发中,往往还需要自定义类型转化,来完成实际的功能或者补充默认转换所不能实现的需求 局部类型转换器 1,定义一个DefaultTypeConverter,并重写public Object convertValue(Object value,Class toType)方法 实例 public class DateConverter extends DefaultTypeConverter { private DateFormat[] formats = new SimpleDateFormat[]{ new SimpleDateFormat("yyyy-MM-dd"), new SimpleDateFormat("yyyy/MM/dd"), new SimpleDateFormat("yyyy.MM.dd"), new SimpleDateFormat("yyyy_MM_dd"), }; @Override public Object convertValue(Object value, Class toType) { System.out.println("经过类型转换器"); String date = ((String[])value)[0]; for (int i =0;i<formats.length;i++) { try { return formats[i].parse(date); } catch (ParseException e) { continue; } } return null; } } 注意,value是个字符串数组 2,转换器配置方法有两种:一、局部配置 二、全局配置 一、局部配置文件 LoginAction-conversion.properties birthday=top.kubino1.conversion.DateConverter 二、全局配置文件 xwork-conversion.properties java.util.Date=top.kubino1.conversion.DateConverter 注意:以上使用ModelDriven接口传递参数,只能配置全局自定义类型转换,不能配置局部类型转换 当使用属性传递的两种方式传递数据时,自定义全局和局部类型转化都可以使用 ******************************************************************************************************************
struts2笔记
最新推荐文章于 2022-05-04 13:20:01 发布