Struts2综合笔记

来源:互联网 发布:php游戏礼包源码 编辑:程序博客网 时间:2024/05/16 18:17
strust2导包commons-beautils           [beanutils工具包]commons-filupload.ajr       [文件上传]commons-io.jar  commons-lang         [struts2对java.lang.*类的支持]freemarker.jar        [视图显示技术]javassit              [struts2对字节码运算的支持]ognl.jar             [struts2对ognl表达式的支持]       struts2-core.jar       [ struts2的核心包 ]      xwork-core.jar   [webwork框架的支持,struts2的前身就是webwork(对webwork的封装)]Struts2配置:  即在WebRoot\WEB-INF\web.xml配置全局过滤器StrutsPrepareAndExecuteFilter<!--  配置启动strut2的全局过滤器 --><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>struts2框架简介strurs2是基于MVC开发模型的web层框架。struts1也是MVC开发模式的框架。struts2并不是struts1的升级版。struts2是基于webwork的升级版。struts2=webwork+sturts1struts-default.xml文件解析默认包,包名叫struts-default(我们自己写的package必须继承这个默认包,只有继承了这个默认包才可以使用该默认包下的功能)<package name="struts-default" abstract="true">跳转类型result-type 申明,目前共10种 :Dispatcher,Chain,Freemarker,Httpheader,Redirect,redirectAction,Stream,Velocity,Xslt,plaintext,拦截器(Interceptor)拦截器(Intercptor)和 过滤器(Filter)过滤器: 可以过滤任何类型的请求(html、servlet、jsp)和响应。加入通用的代码逻辑。拦截器: 是sturts2的特有功能。只能过滤Action!!在执行Action的时候加入通用的代码。默认拦截器栈:<interceptor-stack name="defaultStack">    默认包当前使用的拦截器:<default-interceptor-ref name="defaultStack"/>我们写的包(package)就是继承struts-default默认包的,那么就继承了默认拦截器栈的所有拦截器struts.xml文件详解:(package),用于管理Action,一般可以按模块划分包:<?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="user" extends="struts-default" namespace="/" abstract="false"><action name="login1" class="com.example.test.LoginAction"><result name="success" type="redirectAction">book</result></action><action name="login2" class="com.example.test.LoginAction" method="login2"><result name="login" type="dispatcher">/login2.jsp</result></action></package></struts>package: 代表一个包。管理action配置。在用一个包下面不能有同名的action。package的属性:name: 包名.在一个项目中不能出现同名的包。extends:  继承。我们开发的包就必须继承struts-default包。namespace:  名称空间。区分不同的包的访问路径。默认值  “/”     abstract: 是否抽象。是抽象包,不能含有action.抽象包中用来定义拦截器,公共视图,不做具体的业务。action配置:  name:  action的名称。用于访问该Action的路径 ,不能重复  class:  Action业务对象的类名。一定是全名(包名+类名)  method: 执行的业务方法。不写默认值 executeresult配置:name: 处理方法的返回值          type: 跳转的类型struts2的Action实现三种使用方式第一种方式,不实现Action接口public class UserAction2 {public String login()throws Exception{System.out.println("UserAction2.login()");return "success";}}第二种方式:实现Action接口/**  1)定义了默认的execute方法的标准 *   2)提供了项目中常用的视图标记 */public class UserAction implements Action {public String login() throws Exception {System.out.println("执行了UserAction的login方法");return SUCCESS;}public String execute() throws Exception {return null;}}第三种方式: 继承ActionSupport类(推荐使用) /* *  1)提供了常用的视图标记 * 2)提供了数据校验功能 */public class UserAction3 extends ActionSupport{public String login()throws Exception{System.out.println("UserAction3.login()");return SUCCESS;}}路径通配符:可以只配置一个action来匹配多个要执行的方法一个模块(Action对象)使用一个action配置<action name="user_*" class="com.example.UserAction" method="{1}"><result name="{1}">/{1}.jsp</result></action>* (星号) :表示路径的通配符,在配置文件中会自动替换成匹配成功的请求路径中对应的字符串   {1}:表示获取第一个通配符的实际内容,下面以{1}匹配的内容为方法名,jsp文件名  多个模块使用一个action配置如果*_*匹配User_login.  则第一个*代表模:User,第二个*代表方法:login. /{1}/{2}.jsp表示 /User/login.jsp <action name="*_*" class="com.example.{1}Action" method="{2}"><result name="{2}">/{1}/{2}.jsp</result> </action>strus2的常量配置指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法 和freemarker 、velocity的输出     <constant name="struts.i18n.encoding" value="UTF-8"/>    自定义后缀:    <constant name="struts.action.extension" value="do"/>    设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭     <constant name="struts.serve.static.browserCache" value="false"/>    当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开     <constant name="struts.configuration.xml.reload" value="true"/>    开发模式下使用,这样可以打印出更详细的错误信息     <constant name="struts.devMode" value="true" />    默认的视图主题     <constant name="struts.ui.theme" value="simple" />    与spring集成时,指定由spring负责action对象的创建     <constant name="struts.objectFactory" value="spring" />    该属性设置Struts 2是否支持动态方法调用,默认值是true。使可以通过!method访问action的方法    <constant name="struts.enable.DynamicMethodInvocation" value="false"/>     上传文件的大小限制 <constant name="struts.multipart.maxSize" value=“10701096"/>全局视图配置全局视图作用: 当该包下的所有action都使用到的一些视图就是可以放到全局视图配置中   当action中也有相同名称的视图,那么action的局部视图会覆盖全局视图。全局视图配置: 把该包下的所有action共用的视图都机集中在这里写  <global-results><result name="success">/login.jsp</result> </global-results>action的默认配置:name: 必填项class: 可选项.默认配置:  ActionSupport类   该类继承自struts-default (<default-class-ref class="com.opensymphony.xwork2.ActionSupport" />)method: 可选。默认执行excute()    result:    name: 可选。默认配置: success    type: 可选。默认配置: dispatcher全部使用默认配置的action的作用 :专门用于转发到WEB-INF下的页面 <action name="login"><result>/WEB-INF/jsp/login.jsp</result></action>Action的属性注入:把Action对象中需要把一些经常改变的参数提取到配置文件中Action属性注入的步骤1)在Action类中声明一个成员变量,用于接收xml配置文件传入内容2)在Action类提供一个该变量的setter方法,该方法接收了xml配置的内容private String savePath;//成员变量public void setSavePath(String savePath) {//提供属性的setter方法,用于外部的action的参数进行注入this.savePath = savePath;}在对应的struts.xml文件中,找到对应的action对象的配置,然后在action中使用<action name="upload" class="com.example.test" method="upload"><param name="savePath">e:/images/</param><result>/login.jsp</result></action>sruts2的数据共享的三种方式第一种方式ServletActionContext类ServletActionContext.getRequest():获取Request对象:request.setAttribute("key", value)ServletActionContext.getRequest().getSession() :获取Session对象:session.setAttribute("key", value)ServletActionContext.getServletContext() :获取ServletContext对象servletContext.setAttribute("key", value)该方式依赖servlet的api,耦合比较高第二种方式ActionContext类:ActionContext actionContext = ActionContext.getContext();actionContext .getContextMap():获取操作request域对象数据的map集合actionContext .getSession():获取操作session域对象数据的map集合actionContext .getApplication():获取操作context域对象数据的map集合不依赖servlet的api,耦合性低actionContext对象在Action对象被Struts2创建后,才被框架创建第三种方式RequestAware,SessionAware,ApplicationAware 接口不依赖servlet的api可以在Action对象的所有方法中共享Map集合sruts2请求参数数据的封装1.直接赋值给简单数据类型public class UserAction extends ActionSupport{//参数赋值(注入方式)private String name; //变量名要和jsp页面的name值一一对应private String password;private String gender;private String[] hobit;//参数通过这个set方法注入到Action中public void setName(String name) {this.name = name;}public void setPassword(String password) {this.password = password;}public void setGender(String gender) {this.gender = gender;}public void setHobit(String[] hobit) {this.hobit = hobit;}2.赋值给一个javabean对象<form action="${pageContext.request.contextPath }/data/user_register.action" method="post">    用户名: <input type="text" name="user.name"/><br/>    密码: <input type="password" name="user.password"/><br/>    性别: <input type="radio" name="user.gender" value="男"/>男     <input type="radio" name="user.gender" value="女"/>女<br/>    爱好:    <input type="checkbox" name="user.hobit" value="篮球"/>篮球    <input type="checkbox" name="user.hobit" value="足球"/>足球    <input type="checkbox" name="user.hobit" value="羽毛球"/>羽毛球<br/>    <input type="submit" value="注册"/></form>public class UserAction2 extends ActionSupport{private User user; //使用一个javabean对象接收,变量名要和jsp页面的name一一对应public User getUser() {return user;}public void setUser(User user) {this.user = user;}3.赋值给javabean对象还可以通过ModelDriven请求参数的封装通过struts2的ParametersInterceptor拦截器进行赋值.action执行的时候会先执行validate方法对参数进行一些列的验证,如果他发现当前对象包含fieldError信息,就会直接给你跳转到input视图自定义类型转换作用: 默认情况下,页面的日期类型只能接收 yyyy-MM-dd类型,如果要转换yyyy/MM/dd这种类型,则需要使用自定义类型转换器进行转换。strut2提供了自定义类型转换器的基类: StrutsTypeConverter创建配转换数据类型需要的置文件:UserAction-conversion.properties_bak(action类名-)  文件中写入:user.birth=com.example.test.MyDateConverter(全类名)public class MyDateConverter extends StrutsTypeConverter{SimpleDateFormat  sdf1 = new SimpleDateFormat("yyyy/MM/dd");/** 从页面的数据到服务器的类型转换 * 参数一: context: 值栈上下文对象 * 参数二: values:  从页面传递过来的参数值 * 参数三: toClass: 转换到的类型。String->java.util.Date*/@Overridepublic Object convertFromString(Map context, String[] values, Class toClass) {//写相关逻辑代码}/** 从服务器到页面的类型转换*/@Overridepublic String convertToString(Map context, Object o) {return null;}}绑定自定义转换器的方式:方式一: 局部绑定(只能绑定一个Action)1)建立一个 Action的文件名-conversion.properties2)一定和绑定的Action放在同一个目录下。方式二: 全局绑定(绑定整个项目多个Action)1)建立一个xwork-conversion.properties  写入:java.util.Date=com.example.MyDateConverter(转换累的类全名)2)该文件一定放在src目录下。文件上传和下载文件上传三个条件: Form中有input  并且input的type属性为filepost提交enctype="multipart/form-data"在Action中接收文件内容File attach;   (attach是file表单的name属性值 必须对应)String attachContentType;  文件类型(固定写法)String attachFileName;   文件名称(固定写法)<!-- 修改默认文件最大上传大小值 --><constant name="struts.multipart.maxSize" value="100000000"></constant>修改允许上传的文件类型和文件后缀<action name="upload" class="com.example.UploadAction" ><!-- 往FileUploadInterceptor拦截器的属性注入值(调用setter方法) --> <interceptor-ref name="defaultStack"> <!-- 改变当前文件上传拦截器的允许文件类型 --> <param name="fileUpload.allowedTypes">image/jpeg,image/jpg</param> <!-- 允许的文件后缀 --> <param name="fileUpload.allowedExtensions">jpg,jpeg,gif</param> <!-- 如果以上配置都写了,那么取他们的交集  --> </interceptor-ref><param name="savePath">e:/images/</param><result>/login.jsp</result><result name="input">/error.jsp</result></action>下载主要配置:<action name="down_*" class="com.example.DownAction" method="{1}"><param name="serverPath">e:/images/</param><result name="list">/listFile.jsp</result><result name="down" type="stream"> <param name="contentType">application/octet-stream</param> //字节流   <param name="inputName">inputStream</param> //action类中要提供对应的方法   <param name="contentDisposition">attachment;filename=${name}</param>//告知下载文件名    <param name="bufferSize">1024</param>//文件缓存大小</result></action>拦截器:拦截器类似于过滤器的功能,过滤器可以过滤项目的任何请求(servlet/jsp/html/img),拦截器只能拦截Action请求。定义拦截器interceptor的三种方式 :1.实现Interceptor接口 实现必须的三个方法           init() :拦截器初始化  服务器启动时候就初始化所有需要的拦截器           intercept(ActionInvocation invocation): action访问的时候执行 如果不放行直接返回,就跳到结果页面      destroy():销毁服务器停止的时候销毁2.继承AbstractInterceptor 类,已经实现了init和destroy方法3.继承MethodFilterInterceor  :可以指定不需要拦截的方法申明和使用拦截器:<package name="inter" extends="struts-default" namespace="/inter">    <!-- 申明拦截器:拦截器在此申明后,在web服务器启动的时候就会被初始化 -->    <interceptors>    <interceptor name="inter1" class="com.example.MyInterceptor1"></interceptor>    </interceptors>    <action name="user_*" class="com.example.UserAction" method="{1}">    <!-- 申明该action使用该拦截器:使用后,访问该action的请求,会先经过拦截器 -->    <interceptor-ref name="inter1"></interceptor-ref>    <result>/index.jsp</result>    </action> </package>拦截器生命周期: 1.启动服务器时候,申明在配置文件的拦截器,被初始化,调用init方法 2.执行该拦截器的intercepot方法拦截。在action目标方法 invocation.invoke()执行前后,写相应的业务逻辑。     4.当服务器停止时,拦截器对象才被销毁拦截器作用范围:1.局部使用:在action内部使用,只作用于该action<action name="user_*" class="com.example.UserAction" method="{1}">    <!-- 使用拦截器 -->    <interceptor-ref name="inter1"></interceptor-ref>     <result>/index.jsp</result></action>2.全局使用: 当package内,action外使用 作用于package内的所有action<package name="inter" extends="struts-default" namespace="/inter">    <!-- 申明拦截器 -->    <interceptors>    <interceptor name="inter1" class="com.example.MyInterceptor1"></interceptor>    </interceptors>    <!-- 使用截器 -->    <default-interceptor-ref name="inter1"></default-interceptor-ref></package>拦截器栈:包含多个已经申明的拦截器。拦截器和拦截器栈都在interceptors标签内申明<interceptors>    <interceptor name="inter1" class="com.example.MyInterceptor1"></interceptor>    <interceptor name="inter2" class="com.exampler.MyInterceptor2"></interceptor>    <!-- 定义栏截器栈 -->    <interceptor-stack name="interStack">    <interceptor-ref name="inter1"></interceptor-ref>    <interceptor-ref name="inter2"></interceptor-ref>    </interceptor-stack></interceptors>拦截器栈中拦截器的执行顺序:先配置先初始化1.创建拦截器inter1对象,调用init方法2.创建拦截器inter2对象,调用init方法3.执行inter1的interceptor方法前面代码4.执行inter2的interceptor方法前面代码5.Action的业务方法6.执行inter2的interceptor方法后面代码7.执行inter1的interceptor方法前面代码注意:当我们的包下引用了自定义拦截器栈,则会把默认包下的default-stack拦截器给覆盖掉      为了不覆盖默认拦截器,所以自定义的拦截器栈要加入Struts2默认的拦截器栈:<interceptor-stack name="myStack">    <interceptor-ref name="defaultStack"></interceptor-ref><!-- 引入了默认的全部拦截器 -->    <interceptor-ref name="interStack"></interceptor-ref><!-- 引入自定义的2个拦截器 --></interceptor-stack>struts2的主要初始化流程:1.创建StrutsPrepareAndExcuteFilter对象,执行init方法2.加载default.properties配置文件 3.加载struts-default.xml  struts-plug.xml struts.xml配置文件4.初始化Struts默认配置的拦截器和自定义的拦截器,调用init方法struts2的处理请求的主要流程:如果请求目标是action ,Struts2框架拦截器才会处理,WebRoot下的静态资源是不会经过拦截器的。1.依次执行对目标action起作用的拦截器的 intercept(ActionInvocation invocation)方法2.调用actionInvocation .invocation()方法放行3.创建目标action对象,调用目标方法,目标方法返回配置文件result需要的字符串标记,4.根据目标方法返回的标记,跳到下一个action或者直接返回给浏览器result视图值栈 OGNL(Object Graphic Navigation Languag的缩写,它是一个开源项目。 Struts2框架使用OGNL作为默认的表达式语言。在struts2项目中导入ognl.jar包来实现支持ognl表达式。ognl表达式和EL表达式:EL表达式: 获取域对象的数据。 不能存放数据,不能调用方法Ognl表达式: 获取域对象的数据。  可以存放数据,可以调用方法。OGNL的优势:1.支持对象方法调用,如xxx.doSomeSpecial(); 2.支持类静态的方法调用和值访问,表达式的格式:    @[类全名(包括包路径)]@[方法名 |  值名],例如:    @java.lang.String@format('foo %s', 'bar')或@tutorial.MyConstant@APP_NAME; 3.支持赋值操作和表达式串联,如price=100, discount=0.8,             calculatePrice(),这个表达式会返回80; 4.访问OGNL上下文(OGNL context)和ActionContext; 5.操作集合对象。Ognl表达式核心OgnlContext对象从OgnlContext对象取出根对象数据(ognlContext .setRoot(object)保存的数据),不需要#号从OgnlContext对象取出非根对象数据(ognlContext .put(key, object)保存的数据),需要#号struts2的值栈(ValueStack)对象(对OgnContext对象的封装)ValueStack接口,的实现类OgnlValueStackValueStack的数据存储结构:分为List栈(根栈)和Map栈(非根栈)1)List栈主要存储Action对象和Provider代理对象,自定义对象2)Map栈主要存放各个域存放的数据和用户的参数信息   域对象的List中的取值语法:域对象.对象变量名.对象变量名...,域对象可以省略   域对象的Map中的取值语法:#域对象.map的key,域对象可以省略jsp页面获取值栈(ValueStack)List中和Map中的数据数据:1. <%@ taglib uri="/struts-tags" prefix="s"%>   //申明使用Struts标签 并且以s为前缀使用2.<s:property value="user.name"/> - <s:property value="user.age"/> //取出valueStack 中的List保存的数据  3.<s:property value="#request.request_data"/>  //根据map的key取出request域中map储存的数据  4. <s:property value="#request_data"/><br/>   //从request域的map中取数据可以省略request5.<s:property value="#session.session_data"/>  //根据map的key取出session域中map储存的数据6.<s:property value="#application.application_data"/> //根据map的key取出application域中map储存的数据  7.<s:property value="#attr.session_data"/> // #attr.key 从request域,session域,application域的map中依次一查找  8.<s:property value="#parameters.name"/>  //获取客户端传过来的name参数的值迭代域对象中map储存的List<s:iterator value="#request.userList" var="user">        <s:property value="#user.name"/> </s:iterator>迭代域对象中map储存的map<s:iterator value="#request.userMap" var="entry">    <s:property value="#entry.key"/>    <s:property value="#entry.value.name"/></s:iterator>在action中的成员变量 如果提供了该成员变量的getter方法,该成员变量在获取时会自动被加入到valueStack中使用s:property 获取ValueStack中的数据。 所有以变量名+点的方式获取数据,要在在action和对象中提供相应的get方法文字国际化国际化的资源文件命名规则:包名_语言简写_国家简称.properties中国: message_zh_CN.propertiesjava美国: message_en_US.properties英国:  message_en_GB.properties不同国家的资源包命名:中国: message_zh_CN.properties美国:  message_en_US.properties英国:  message_en_GB.properties在struts.xml文件中指定国际化资源包的加载路径:<constant name="struts.custom.i18n.resources" value="resources.message"></constant>在jsp页面上使用: <s:text name="user"/> //其中user就是key值,所有同一字符串不同语言的key值是相同的,value不同struts2数据验证拦截器:<interceptor name="validation" class="com.opensymphony.xwork2.validator.ValidationInterceptor"/>1.代码验证Action类被访问的方法被访问前数据是否合法01.Action类继承ActionSupport(以实现Validatable接口)02.Action类覆盖validate方法(覆盖该方法会对所有访问的action方法生效)03.在struts.xml文件中对应的action配置加上input视图,接收错误信息04.验证Action类的指定方法规则(不覆盖validate):validate+需要验证的方法名称: 例如:验证register()方法,则需要在该action类下面创建validateRegister()方法验证代码:01.验证时候如果出现错误信息则:super.addFieldError("user.name", "用户名不能为空!");02.验证完后Struts2框架会查看错误信息集合,如果有数据则直接转发到input视图,不再执行目标方法     03.在input指定的jsp页面,用<s:fielderror fieldName="user.name"></s:fielderror>获取自己定义的错误信息2.xml配置文件验证Action类被访问的方法被访问前数据是否合法01.在Action类文件的同一目录下,编写一个xml文件02.名称:Action类文件名-validation.xml(对所有被访问的方法生效)03.名称:Action文件名-访问方法路径-validation.xml例如: UserAction类的register方法: urld的访问路径是user_register  文件名为:UserAction-user_register-validation.xml    Struts2定义的action配置文件约束类型验证器的路径是:/com/opensymphony/xwork2/validator/validators/default.xmlStruts2标签库: 1.流程控制标签 2.数据标签 3.UI标签struts2表单标签:<!-- theme:指定表单的主题,xhtml:默认simple:没有主题 --><s:form action="Demo3Action" namespace="/" theme="xhtml" ><s:textfield name="name" label="用户名"  ></s:textfield><s:password name="password" label="密码" ></s:password><s:radio list="{'男','女'}" name="gender" label="性别" ></s:radio><s:radio list="#{1:'男',0:'女'}" name="gender" label="性别" ></s:radio><s:checkboxlist list="#{2:'抽烟',1:'喝酒',0:'烫头'}" name="habits" label="爱好" ></s:checkboxlist><s:select list="#{2:'大专',1:'本科',0:'硕士'}" headerKey="" headerValue="---请选择---" name="edu" label="学历" ></s:select><s:file name="photo" label="近照" ></s:file><s:textarea name="desc" label="个人简介" ></s:textarea><s:submit value="提交" ></s:submit></s:form>默认情况下,struts2不支持防止重复提交的1.在struts.xml文件中打开功能:<interceptors><interceptor-stack name="myStack"><interceptor-ref name="defaultStack"></interceptor-ref><interceptor-ref name="token"></interceptor-ref></interceptor-stack></interceptors>2.jsp页面指定一个标签:<s:token></s:token>   

原创粉丝点击