struts2详解

1.搭建struts2运行环境:
    1.1找到所需要的jar包
        struts2-core-
        xwork-core-
        ognl-
        freemarker-
        commons-logging-
        commons-fileupload-
    1.2编写struts2的配置文件
        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE struts PUBLIC
                "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
                "http://struts.apache.org/dtds/struts-2.0.dtd">
        <struts>
            <package name="struts" namespace="/" extends="struts-default">
                <action name="*" class="*" method="*">
                    <result>*.jsp</result>
                </action>
                <!-- Add actions here -->
            </package>
        </struts>
    1.3在web.xml中加入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>
2.Action的名称搜索顺序:
    http://loaclhost:10086/test/a/b/c/helloworld.action
    一级一级想上找,要是找不到,就到默认命名空间中去找。
3.Action的各项默认值:
    <action name="hello"><result>/hello.jsp</result></action>
    默认class:ActionSupport
    默认method:execute
    默认result->name:SUCCESS
4.Struts2的转发类型:<result name="*" type="转发类型"></result>
    dispatcher(默认);转发:<result name="*" type="dispatcher">x.jsp</result>
    redirect:重定向:<result name="*" type="redirect">x.jsp</result>
    redirectAction:重定向到其他Action:
        (在同一个package内)
            <result name="*" type="redirectAction">*Action</result>
        (在不同的package中)
            <result name="*" type="redirectAction">
                <param name="actionName">*Action</param>
                <param name="namespace">/其他命名空间</param>
            </result>
    plainText:直接显示视图的源代码(例如要做一个技术网站,需要显示源代码)
        <result type="palinText">
            <param name="loaction">/*.jsp</param>
            <param name="charSet">UTF-8</param><!--指定文件读取的编码方式-->
        </result>
       
5.Struts中的全视图global-result
    (只能在同一个package中使用)
        <golbal-result>
            <result name="*">/*.jsp</result>
        </golbal-result>
    (让所有的package都能访问,让package继承golbal-result所在的base package)
        <package name="base" extends="struts-default">
            <golbal-result>
                <result name="*">/*.jsp</result>
            </golbal-result>
        </package>
6.为Struts中的属性注入值(参数不适合写到固定的类中)
    <action>
        <param name="属性名称">属性值</param>
        <result name="*">/*.jsp</result>
    </action>
7.修改访问Action的后缀名称(默认的是.action,修改访问常量)
    <constant name="struts.action.extension" value="do,action"/>
    修改为.do 或者.action 访问
    也可以定义在struts.properties配置文件中(struts.action.extension=do)
    还可以配置在struts-default.xml
                struts-plugin.xml
                struts.xml
                struts.properties
                web.xml
    中,加载顺序就是以上的顺序。
8.struts中常用的常量(需要上网查询了解)
    <constant name="struts.i18n.enconding" value="UTF-8">(指定默认编码集)
    <constant name="struts.action.extension" value=""/>(设置访问后缀)
    <constant name="struts.aerve.static.browserCache" value="true"/>(设置浏览器是否缓存)
    <constant name="struts.confinuration.xml.reload" value=""/>(设置动态加载,当配置文件改变时,是否需要重启服务器)   
    <constant name="struts.devMode" value="true"/>()
    <constant name="struts.ui.theme" value="simple"/>(设置显示主题)
    <constant name="struts.bojectFactory" value="spring"/>(指定Action创建的工程类,一般集成spring是需要用到)
    <constant name="struts.enable.dynamicMethodInvocation" value="true"/>(是否允许使用动态调运的方式访问Action)
9.struts2处理流程
    用户请求->StructPrepareAndExecuteFilter(判断请求是否属于Struts2的处理范围,例如以.action结尾)
            ->Interceptor(内置拦截器或自定义拦截器)
            ->Action(自己编写的处理Action类)
            ->Result(跳转结果)
            ->jsp/html(用户响应)
    为每一个用户请求创建一个新的action,所以它是线程安全的。
10.struts2分模块集成多个配置文件
    <struts>
        <include file="struts-one.xml"/>
        <include file="struts-two.xml"/>
    </struts>
    注意:package的name应该是唯一的。
11.struts2中动态方法的调用(两种方式,默认的都是执行execute)
    <constant name="struts.enable.dynamicMethodInvocation" value="false"/>表示不可以使用动态调用。
    方法一:使用感叹号(*Action!method.action)
    方法二:使用通配符(配置:<action name="abc_*" class="*" method="{1}"> 访问:abc_method.action)
12.struts2接受请求参数(不区分是get传送还是post传送)
    既可以接受简单类型的,也可以接受复合类型的
    需要提供属性的set方法去给Action中的属性设置值
    简单类型:直接写属性名称(id=123&name="gusi")
    复合类型:使用.符号(person.id=123&person.name="gusi")
    注意:内部实现是通过反射的机制,使用反射的newInstance()方法,所以复合对象需要提供默认构造器,不然会出错
          2.1.6版本中有中文乱码问题,需要使用字符集过滤器解决,2.1.8版本中不存在该问题。
13.struts2自定义类型转换器
    public class DateTypeConverter extends DefaultTypeConverter {
        @Override
        public Object convertValue(Map<String, Object> context, Object value,Class toType) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            try {
                if (toType == Date.class) {//当字符串向Date转换时
                    String[] params = (String[]) value;//得到要转换的String
                    return sdf.parse(params[0]);//将String类型转换为Date类型
                } else if (toType == String.class) {//当Date向字符串转换时
                    Date date = (Date) value;//得到要转换的date
                    return sdf.format(date);//将date类型转换为String类型
                }
            } catch (Exception e) {
                return null;
            }
            return null;
        }
    }
    局部:定义*Action-conversion.properties(birthday=package.type.conversion.DateTypeConverter)
    全局:定义xwork-conversion.properties(java.util.Date=package.type.conversion.DateTypeConverter)
14.struts2访问、添加 request session application对象
    方式一:(适合只使用放值,取值的情况下,操作简单)
        ActionContext ac = ActionContext.getContext();
        ac.put(key, value);//request范围放值(${requestScope.key})
        ac.getSession().put(key, value);//session范围放值(${sessionScope.key})
        ac.getApplication().put(key, value);//application范围放值(${applicationScope.key})
    方式二:(适合需要用到各个对象的其他应用的情况,操作稍微复杂一点)
        HttpServletRequest request = ServletActionContext.getRequest();;
        HttpServletResponse response= ServletActoinContext.getResponse();;
        HttpSession session = request.getSession();;
        ServletContext application= ServletContext.getServletContext();
        request.setAttribute(key, value);
        session.setAttribute(key, value);
        application.setAttribute(key, value);
    方式三:(使其实现指定的接口,有struts的框架运行时注入)
        public class FirstAction implements ServletRequestAware,ServletResponseAware,ServletContextAware{
            private HttpServletRequest request;
            private HttpServletResponse response;
            private ServletContext application;
        }
15.struts2 文件上传
    15.1.单文件上传
        step1.添加jar文件到lib目录中
            commons-fileUpload-
            commons-io-
        step2.将form表单的enctype设置为:"multipart/from-data"
            <from enctype="multipart/from-data" action="${pageContext.request.contextPath}/xxx.action" method="post">
                <input type="file" name="upload" />
            </from>
        step3.在Action中添加以下属性
            public class FileUploadAction {
                private File upload;
                private String uploadFileName;
                private String uploadContentType;
                //setter/getter方法
                public String upload() throws Exception{
                    String savePath = "保存路径,一般都是根据服务器获得的相对路径";
                    //根据保存路径,在保存路径下建立一个子文件,用来保存上传的文件
                    File file = new File(new File(savePath),"upload");
                    if(!file.exists()){
                        file.mkdirs();
                    }
                    FileUtils.copyFile(upload, file);
                    return "success";       
                }
               
            }
        修改上传文件的大小,需要修改配置文件struts.xml中的常量
            <constant name="struts.multipart.maxSize" value="1070196" />设置最大上传文件为10M左右。
        注意:一般可以用第三方的文件上传插件,既方便又好用。
    15.2.多文件上传
        step1.导包
        step2.设置表单
            <input type="file" name="upload" />
            <input type="file" name="upload" />
            上传文件的name要相同。
        step3.配置Action
            public class FileUploadAction {
                private File[] upload;//定义为数组类型或者List类型
                private String[] uploadFileName;
                private String[] uploadContentType;
                //setter/getter
                public String upload() throws Exception{
                    String savePath = "保存路径,一般都是根据服务器获得的相对路径";
                    //根据保存路径,在保存路径下建立一个子文件,用来保存上传的文件
                    File file = new File(new File(savePath),"upload");
                    if(!file.exists()){
                        file.mkdirs();
                    }
                    //遍历上传的所有文件,然后依次保存到对应的文件目录下
                    for(int i=0;i<upload.length;i++){
                        FileUtils.copyFile(upload[i], file);
                    }
                    return "success";       
                }
            }
16.strus2中自定义拦截器
    step1.定义自定义拦截器(注意需要实现Interceptor接口)
        public class MyInterceptor implements Interceptor {
            //注意实现接口。
            public void destroy() {
            }
            public void init() {
            }
            public String intercept(ActionInvocation invocation) throws Exception {
                //从session中获得一个值,然后判断该值是否为null,若为null那么就不执行拦截器的方法。
                Object obj = ActionContext.getContext().getSession().get("key");
                if(obj!=null){//代表可以执行Action的方法
                    String result = invocation.invoke();//执行Action中的指定方法,返回的其实就是Action中该方法的返回值
                    ActionContext.getContext().getSession().put("msg","成功" );
                    return result;
                }else{//代表不可以执行拦截器拦截到的Action的方法
                    ActionContext.getContext().getSession().put("msg", "失败");
                    return "error";
                }
            }
        }
    step2.配置struts.xml文件(注册拦截器)
        <package>
            <interceptors>
                <interceptor name="myInterceptor" class="com.dyy.interceptor.MyInterceptor"></interceptor>
                <interceptor-stack name="myInterceptorStack">
                    <interceptor-ref name="defaultStack" />
                    <interceptor-ref name="myInterceptor" />
                </interceptor-stack>
            </interceptors>
            <default-interceptor-ref name="myInterceptorStack"></default-interceptor-ref>//让整个包中的Action都应用该拦截器
            <golbal-rusults>
                <resutl name="error">/xxx.jsp</resutl>   
            </golbal-rusults>
            <actoin name="first" class="com.dyy.action.FirstAction">
                <interceptor-ref name="myInterceptorStack" />
                <interceptor-ref name="otherIntercetptor" />//在这里使用了以后,就不会应用这个包定义的默认拦截器
                <restul name="success">/xxx.jsp</resutl>
            </actoin>
        </package>
        此时,当访问Action的时候,会经过defaultStack和myInterceptor,然后根据拦截器的功能,返回不同的结果。
        还应该注意,上面每个标签放置的位置,放置的位置不对,有可能引起错误。
17.struts2中(手工编写代码的方式)对Action的方法进行输入校验
    17.1对所有方法进行校验
        step1.编写Action类(当访问Action中的方法的时候,就会执行validate方法)
            public class ValidateAction extends ActionSupport{
                //注意需要继承ActionSupport并且覆盖validate()方法
                private String error;    
                public String getError() {
                    return error;
                }
                public void setError(String error) {
                    this.error = error;
                }
                public String mehtod1(){
                    ActionContext.getContext().put("key", "value");
                    return "result";
                }
                public String method2(){
                    ActionContext.getContext().put("key", "value");
                    return "result";
                }
                @Override
                public void validate() {//会对所有方法都进行校验(method1 、method2)
                    if(条件一){
                        this.addFieldError(error, "错误情况一");//向错误域error中添加信息或者值
                    }
                    if(条件二){
                        this.addFieldError(error, "错误情况二");
                    }
                    //注意,在执行了addFileError以后,都会跳转到一个”input“视图下,
                    //所以需要配置一个input视图
                }
            }
        step2.配置xml文件(验证失败是,转发到input视图)
            <action name="validata" class="com.dyy.action.ValidataActoin">
                <result name="input">/xxx.jsp</result>//当错误发生时的视图结果
                <result name="result">/xxx.jsp</result>//当没有发生错误时的视图结果
            </action>
        step3.输出显示错误信息结果(使用struts标签)
            <%@ taglib uri="/struts-tags" prefix="s"%>//引入struts标签库
            <body>        <s:fielderror />//输入错误域的内容        </body>
    17.2对指定的方法进行输入校验
        通过使用validateXxx()方法只对xxx()方法进行输入校验
        public viod validataMethod1(){//只对method1()方法进行输入校验
            //内部内容和逻辑原理与之前相同
        }
        其他所有都和之前的相同。
18.struts2的Action输入校验的执行顺序和原理
    step1.对接受参数进行类型转换,然后赋值给Action中的各个数据域
    step2.如果在执行类型转换的过程中出现异常,系统会将异常信息保存到ActionContext中,
        conversionError拦截器会将异常信息添加到fieldError里,不管是否出现异常,都会进入第三步。
    step3.系统通过反射技术先调运action中validataXxx()方法,xxx为方法名称。
    step4.再调运action中的validate()方法
    step5.经过上面4步,系统中的fieldErrors存在错误信息,也就是存放错误信息的集合的size大于0,
        系统自动将请求转发至input视图,如果系统中存放错误信息集合没有值,系统将执行action的返回的视图。
        (进入input视图的情况有两种,第一种是在类型转换时候发生错误,会进入input视图(一定要注意这种情况),
        第二种是在进行校验的时候执行validate方法时候,发生错误,会进入input视图)
19.struts2中(xml配置文件的方式)对Action的方法进行输入校验
    19.1对所有方法进行校验
        step1.编写Action类,继承ActionSupport类
            和上面的类相同,也不需要任何validate方法,就是一个普通的Action类,继承ActionSupport类。
        step2.提供校验配置xml文件(文件名:ActionClassName-validation.xml)
             <!DOCTYPE validators PUBLIC
                    "-//OpenSymphony Group//XWork Validator 1.0.3//EN"
                    "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
            <validators>
                <field name="username">//要校验的属性域
                    <field-validator type="requiredstring">//系统提供的校验方法(不能为空)
                        <parma name="trim">true</param>//去掉field的前后空格
                        <message key="requiredstring"/>//校验失败是的错误提示信息
                    </field-validator>
                </field>
                <field name="mobile">
                    <field-validator type="requiredstring">
                        <message>手机号不能为空</message>
                    </field-validator>
                    <field-validator type="regex">
                        <param name="expression"><!CDATA[^1[358]\d{9}$]]></param>
                        <message>手机号格式不正确</message>
                    </field-validator>
                </field>
            </validators>
        step3.配置input视图
        注意:xml配置文件需要和Action类在同一个包下。xml的命名必须符合要求(*Action-validation.xml)。
    19.2对特定的方法进行校验
        步骤和上面一样,只是校验文件的命名不同(ActionClassName-ActionName-validation.xml);
        注意:ActionName是action配置文件中的全名(例如:user_add,user_update),不是user_*或者add;
        举例:PersonAction-user_add-validation.xml(对PersonAction类中的add方法进行校验)
              DepartmentAction-depart_update-validation.xml(对DepartmentAction类中的update方法进行校验);
        当*Action-validation.xml和*Action-*_*-validation.xml同是存在时,会合并两个文件中的校验规则,
        然后对所有Action的方法进行校验,特别注意MyActionj extends BaseAction中有继承关系的情况。
20.struts2中的校验器(在xwork-core.jar中的com.opensymphony.xwork2.validator.validators中的default.xml文件中定义的)
    required:必填校验器
        <field-validator type="required">
            <message>不能为空</message>
        <field-validator>
    requiredstring:必填字符串校验器
        <field-validator type="requiredstring">
            <message>不能为空</message>
        <field-validator>
    stringlength:字符长度校验器
        <field-validator type="stringlength">
            <param name="maxLength">10</param>
            <param name="minLength">2</param>
            <param name="trim">true</param>
            <message>长度应该在2到10之间</message>
        <field-validator>
    regex:正则表达式校验器
        <field-validator type="regex">
            <param name="expression">正则表达式</param>
            <message>不符可输入要求</message>
        <field-validator>
    int:整数校验器
        <field-validator type="int">
            <param name="min">1</param>
            <param name="max">100</param>
            <message>必须在1到100之间</message>
        <field-validator>
    double:双精度校验器
        <field-validator type="double">
            <param name="min">1.00</param>
            <param name="max">9.99</param>
            <message>必须在1.00到9.99之间</message>
        </field-validator>
    fieldexpression:ongl表达式校验器
    email:邮件校验器
        <field-validator type="email">
            <message>电子邮件地址无效</message>
        <field-validator>
    url    date conversion    visitor    expression
21.struts2国际化(全局范围资源文件)
    国际化文件的命名:
        baseName_language_country.properties
    不带参数的国际化输出:
        step1.编写两个配置文件
            gusi_zh_CN.properties(key=我喜欢IT) 
            gusi_en_US.properties(key=I lick IT)
        step2.配置struts.xml文件
            <contanst name="struts.custom.i18n.resources" value"gusi" />//value="baseName"
            <package>
                <action name="" class="" method="">视图结果</action>
            </package>
        step3.访问国际化信息
            在jsp页面中使用(使用struts标签text)
                <s:text name="key"/>
            在Action中使用(使用getText(key)方法)
                String value=this.getText("key");//该Action需要继承ActionSupport类
    带参数的国际化输出
        step1.编写两个配置文件
            gusi_zh_CN.properties(key={0}我喜欢IT{1})//参数用{编号}表示,从0开始
            gusi_en_US.properties(key={0}I like IT{1})
        step2.配置struts.xml
            同上
        step3.访问国际化信息
            在jsp页面中
                <s:text name="key">
                    <parma>参数0</parma>
                    <parma>参数1</parma>
                </s:text>
            在Action中
                String value=this.getText("key",new String[]{"参数0","参数1"});
    包范围资源文件:对整个package中的内容使用
        和全局的步骤一样,只是资源文件固定命名为package_language_country.properties
        注意:全局范围资源文件将properties文件放置在src目录下
              包范围资源文件将properties文件放置在对应的package目录下。
    Action范围资源文件:对特定的Action使用
        和全局的步骤一样,只是资源文件命名为ActionClassName_language_country.properties
        注意:搜索或者应用资源文件的顺序是从Action到package到global范围
    另一种方式,直接访问资源文件,不用按照特定的名称配置。(使用struts标签<s:i18n>)
        全局范围:(默认是全局范围)
            <s:i18n name="gusi">
                <s:text name="key">
                    <s:param>参数</s:param>
            </s:i18n>
        包范围:
            <s:i18n name="com/struts/action/package">//其他相同
        Action范围:
            <s:i18n name="com/struts/action/ActionClassName">//其他相同
22.struts2 和 OGNL 表达式

23.struts2的标签库使用
    1.property标签(用于输出指定值,和ognl表达式配合使用)
        <s:property value="#name" />
    2.iterator标签(用于对集合进行迭代,集合包括List,Set,Map)
        //s:iterator标签在迭代集合时:会把当前迭代的队形放在值栈的栈顶
        <s:iterator value="#lsit" status="st">
            <font color=<s:if test="#st.odd">red</s:if><s:else>blue</s:else>//根据奇偶属性,改变颜色的值
            <s:property />//如果没有value的值,那么会默认取栈顶的值
            </font>
        <s:iteratro>
        status:可选属性,是迭代式的IteratorStatus实例。
            int getCount();返回当前迭代了几个元素
            int getIndex();返回当前迭代的索引
            boolean isEven();返回当前被迭代的是不是偶数
            boolean isOdd();返回当前迭代的是不是奇数
            boolean isFirst();返回当前迭代的是不是第一个元素
            boolean isLast();返回当前迭代的是不是最后一个元素
    3.if/elseif/else标签
        <s:set name="age" value="21" />
        <s:if test="#age==23">23</s:if>
        <s:elseif test="#age==21">21</s:elseif>
        <s:else>都不等于</s:else>
    4.url标签()
        //生成路径:/struts/test/person_add.action?personId=23
        <s:url actoin="person_add" namespace="/test">
            <s:param name="personId" value="1" />//此处的value的值默认当ognl来处理
        </s:url>
        <s:url value="%{#ognl}" />//此处的value的值默认当做string来处理,用“%{}”可以将string当ognl处理
        //一般用在超链接标签,使用很方便
    5.form表单中的一些标签
        <s:from actoin="" namespace="" mehtod="post"></from>
        5.1.checkboxlist复选框标签
            //最好设置主题常量,就会放置struts2生成一些我们不需要的代码
                <constant name="struts.ui.theme" value="simple"></constant>
            //定义list集合的方法list="{'value1','vlaue2','vlaue3'}"
            //定义map集合的方法map="#{'key1':'value1','key2':'value2','key3':'value3'}"
            list集合:产生的<input>的value和显示的值相同,可以查看页面源代码。
                <s:checkboxlist name="list" list="{'java','c','c++','.net'}" value="{'java','.net'}"/>
            map集合:key作为<input>的value,value作为显示的结果。
                <s:checkboxlist name="map" list="#{'key1':'value1','key2':'value2','key3':'value2'}"
                listKey="key" listValue="value" value="{'key1',key2}"></s:checkboxlist>
            list集合中存放的是javaBean
                <s:checkboxlist name="benas" list="#request.Beans" listKey="beanId" listValue="benaValue" />
                //benaId 和benaValue 为Bean对象的属性。
        5.2.radio单选框
            <s:radio name="list" list="{'',''}" />
            <s:radio name="map" list="#{'':'','':''}" listkey="key" listValue="value" value="key1"/>
            <s:radio name="benas" list="#request.beans" listKey="attr1" listValue="attr2" />
        5.3.select下拉列表框
            <s:select name="list" list="{'key1','key2'}" value="key1"/>
            <s:select name="map" list="#{'':'','':''}" listkey="key" listValue="value" value="key1"/>
            <s:select name="benas" list="#request.beans" listKey="attr1" listValue="attr2" />
    6.其他标签
24.struts2中防止表单重复提交(<s:token>标签)
    step1.在要提交的表单中加入token标签
        <s:form action="first" namespace="/" method="post">
            输入:<s:textfield name="name"></s:textfield>
            //加入token标签,在提交时会给表单一个id,服务器接收时会对比传来的id和服务器端的id是否相同
            <s:token></s:token>
            <input type="submit" value="submit" />
        </s:form>
    step2.配置Action中的token拦截器
        <action name="" class="" method="">
            <interceptor-ref name="defaultStack"></interceptor>//系统默认的原始拦截器栈
            <interceptor-ref name="token"></interceptor-ref>//token拦截器
            <result name="invalid.token">/*.jsp</result>//当重复提交发生异常时的返回视图
            <result name="">/*.jsp</result>//正常情况下的返回视图
        </actoin>
   
   
   

猜你喜欢

转载自dyygusi.iteye.com/blog/2001292
今日推荐