zoukankan      html  css  js  c++  java
  • Struts2框架基本使用

    时间:2017-1-6 16:53

    修改struts.xml配置文件不需要重启服务器。


    Struts2框架

        一、
            *   介绍Struts2
            *   关于Struts2配置(关于Action配置)
            *   关于Struts2结果类型
        二、
            *   Struts2处理请求参数
            *   Struts2的类型转换(了解)
            *   Struts2的校验
        三、
            *   Struts2的国际化
            *   Struts2的拦截器
            *   Struts2文件上传与下载
            *   Struts2中ognl与valuestack
        四、
            *   ognl与valuestack
            *   Struts2中的防止表单重复提交
            *   Struts2中的Ajax插件
        五、
            *   练习(增删改查)


    ——什么是Struts2 

    1、Struts2是一个非常优秀的MVC框架,基于Model2设计模型,只能在JavaWeb项目中应用。

    2、由传统Struts1和WebWork两个经典框架发展而来。

    3、Struts2核心功能
        *   允许POJO(Plain Old Java Object)对象作为Action。
        *   Action的excute方法不再与Servlet API耦合,更容易测试。
        *   支持更多视图技术(JSP、FreeMarker、Velocity)。
        *   基于Spring AOP思想的拦截器机制,更易扩展。
        *   更强大、更易用的输入校验功能。
        *   整合Ajax支持

    4、Struts2核心:WebWork
        WebWork核心是XWork,XWork提供了很多核心功能:前端拦截器(Interceptor),运行时表单属性验证,类型转换,强大的表达式语言,(OGNL - the Object Graph Navigation Language),IoC(Inversion of Control 反转控制)容器等。

    ——Struts2的下载和安装

    1、到http://struts.apache.org/download.cgi 去下载Struts2最新版本。

    2、Struts2目录结构
        *   apps:该文件包含了基于Struts2的示例应用。
        *   docs:该文件夹下包含了Struts2相关文档,包括Struts2快速入门、Struts2的文档以及API等文档。
        *   lib:该文件夹下包含了Struts2框架和核心类库,以及Struts2第三方插件类库
        *   src:该文件夹下包含了Struts框架的全部源代码。
            >   core:Struts2的源代码
            >   xwork-core:xwork的源代码

    3、开发时没必要将lib目录下的jar文件全部复制到项目中。
        可以到:struts-2.3.15.1appsstruts2-blankWEB-INFlib目录下找到必要jar包。

    ——Struts2之HelloWorld

    Struts2的Web项目尽量使用JavaEE5.0版本,因为Struts2是基于配置文件进行开发的。

    1、导入jar包
        struts-2.3.15.1appsstruts2-blankWEB-INFlib目录下找到必要jar包即可。

    2、创建index.jsp、hello.jsp页面

    3、对Struts2框架进行配置
        1)web.xml文件中配置前端控制器(核心控制器),其实就是一个Filter,目的是使Struts2框架生效。
            该过滤器的init()方法加载了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)创建一个struts.xml配置文件,这个是Struts2框架的配置文件,目的是使Struts2的流程可以执行。
            名称:struts.xml
            位置:src文件夹下(classes文件夹下)

     

    4、创建一个HelloAction类
        要求:在HelloAction类中创建一个返回值是String类型的无参方法。

        public String hello(){
            return "hello";
        }


    5、在struts.xml文件中配置HelloAction

    <struts>
        <package name="default" namespace="/" extends="struts-default">
            <action name="hello" class="com.wyc.action.HelloAction" method="hello">
                <result name="hello">/hello.jsp</result>
            </action>
        </package>
    </struts>


    6、在index.jsp中添加链接,进行测试:
        <a href="${pageContext.request.contextPath }/hello" >第一次使用Struts2</a>

        在地址栏中输入:http://localhost/struts2_day01/index.jsp,访问超链接,就可以看到HelloAction类中的hello方法执行了,并且跳转到了hello.jsp页面。

    7、流程分析:

    图片

    8、手写代码实现Struts2功能
        1)创建一个Filter:StrutsFilter
        2)在web.xml文件中配置StrutsFilter
        3)在StrutsFilter中拦截操作,并访问Action中的方法,跳转到hello.jsp页面。

    =============================================================================
    示例代码:

    struts.xml文件:

    <struts>
        <action name="hello" class="com.wyc.action.HelloAction" method="hello">
            <result name="hello">/hello.jsp</result>
            <result name="hello2">/hello2.jsp</result>
        </action>
    </struts>


    ----------------------------------------------------------------------------------------------------------------------------

    StrutsFilter:

    package com.wyc.web.filter;
     
    import java.io.File;
    import java.io.IOException;
    import java.lang.reflect.Method;
     
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
     
    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
     
    public class StrutsFilter implements Filter {
     
        public void destroy() {
     
        }
     
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
            // 1、强转
            HttpServletRequest request = (HttpServletRequest)req;
            HttpServletResponse response = (HttpServletResponse)resp;
     
            /*
             * 2.1、得到请求资源路径
             */
            // 得到请求路径
            // uri:/Struts_day01_1/hello
            String uri = request.getRequestURI();

            // 得到项目名
            // contextPath:/Struts_day01_1
            String contextPath = request.getContextPath();
     
     
            // hello
            String path = uri.substring(contextPath.length()+1); 
     
     
            /*
             * 使用path去struts.xml文件中查找某一<action name=path>
             */
            SAXReader reader = new SAXReader();
            try {
                Document doc = reader.read(new File(this.getClass().getClassLoader().getResource("struts.xml").getPath()));
     
                Element action = (Element) doc.selectSingleNode("//action[@name='" + path + "']"); // "//action['hello']"
     
                if(action != null){
                    // 得到action元素的class属性和method属性
                    String className = action.attributeValue("class");
                    String methodName = action.attributeValue("method");
     
     
                    // 通过反射得到Class对象,然后得到Method对象
                    Class c = Class.forName(className);
                    Method method = c.getDeclaredMethod(methodName);
     
     
                    // 执行method方法,并获取返回值
                    String returnValue = (String) method.invoke(c.newInstance());
     
     
                    // 使用返回的字符串去<action>下查找其子元素result的name属性值,获取与返回字符串相同的<result>元素
                    Element e = (Element) action.selectSingleNode("//result[@name='" + returnValue + "']");
     
                    if(e != null){
                        // 表示result存在,可以执行跳转
                        String skipPath = e.getText();
     
     
                        request.getRequestDispatcher(skipPath).forward(request, response);
                        return;
                    }
     
                }
     
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
     
     
            // 3、放行
            chain.doFilter(req, resp);
        }
     
        public void init(FilterConfig arg0) throws ServletException {
     
        }
     
    }

    ------------------------------------------------------------------------------------------------------------------

    HelloAction.java

    package com.wyc.action;
     
    public class HelloAction {
        public String hello(){
            System.out.println("hello");
            return "hello";
        }
    }
    =======================================================================



    ——Struts2的流程分析与工具配置

    1、运行流程:
        请求  -->  StrutsPrepareAndExecuteFilter(核心控制器、核心拦截器、前端控制器、前端拦截器)  -->  Interceptors(拦截器,实现代码功能,核心是AOP动态代理)  -->  Action的execute  -->  Result(结果页面)

        拦截器:在struts-default.xml中定义
        执行拦截器:在defaultStack中引用拦截器

        可以通过源码级别断点调试,证明拦截器执行了(学会导入源码,选中完整类名,然后ctrl + t)。

    图片


    2、手动配置struts.xml文件中提示操作
        1)复制http://struts.apache.org/dtds/struts-2.3.dtd
            到该目录中查找dtd文件:struts-2.3.15.1srccoresrcmain esources
        2)在Windows —— Preferences —— 输入XML —— XML Catalog —— Add ——在Location中填入dtd文件路径 ——Key type选择URI —— URI中填入(名称空间):http://struts.apache.org/dtds/struts-2.3.dtd —— OK

        导入DTD时,应该和配置DTD版本一致。

    3、关联Struts2的源文件
        Ctrl + Shift + t,输入类名查找对应类,然后关联源码。
        如果是com.opensymphony.xxx,就在xwork-core目录中查找。
        如果是org.apache.struts2.xxx,就在core目录中查找

    4、使用ConfigBroswer插件(了解)
        提供在浏览器中查看Struts2配置加载情况。
        将解压后的struts2/lib/struts2-config-browser-plugin-2.3.7.jar复制到WEB-INF/lib目录下
        访问:localhost:8080/struts2_day01/config-browser/index.action查看struts2配置加载情况。

    ——Struts2配置(重点)

    1、Struts2配置文件加载顺序:
        1)Struts2框架要想执行,必须先加载StrutsPrepareAndExecuteFilter
            在StrutsPrepareAndExecuteFilter类的init()方法中对Dispatcher进行了初始化操作。
            在Dispatcher类中定义的init()方法内就描述了Struts2配置文件的加载顺序:

     
                init_DefaultProperties(); // [1] —— struts2-core-2.3.15.1.jara包中的org/apache/struts2/default.properties
                init_TraditionalXmlConfigurations(); // [2] —— struts2-core-2.3.15.1.jara包中的struts-default.xml, struts-plugin.xml, struts.xml
                init_LegacyStrutsProperties(); // [3] —— 自定义struts.properties
                init_CustomConfigurationProviders(); // [5] —— 自定义配置文件
                init_FilterInitParameters() ; // [6] —— web.xml
                init_AliasStandardObjects() ; // [7] —— 加载Bean

                第一个加载的文件:default.properties文件
                    作用:定义了Struts2框架中所有常量。
                    位置:org/apache/struts2/default.properties

                    properties文件定义键值对,定义值。
                    XML文件定义关系。


                第二个加载的文件:
                    struts-default.xml:
                        作用:配置了bean, interceptor, result等信息。
                        位置:struts2-core-2.3.15.1.jara包中。
                    struts-plugin.xml
                        它是struts2框架中所使用的插件的配置文件。
                    struts.xml
                        使用struts2框架所使用的配置文件。

                第三个加载的文件:自定义的struts.properties
                    可以自定义常量,而不是用struts.properties中定义的常量。

                第四个加载的文件:web.xml

            在开发中,后加载文件中的配置会将先加载文件中的配置覆盖。

    ——关于Action的配置(重点)

    1、struts.xml
        1)<package>:
                用于声明一个包,管理Action类。(通常情况下一个模块一个package)
                Struts2所有action都通过package管理。
                struts-default是struts-default.xml定义的一个package,其中包含大量拦截器和结果集。
                Action的访问路径 = namespace + action的name属性

            *   name
                包名,用于声明一个包名,包名不能重复。

            *   namespace
                与<action>元素的name属性合并,确定了一个唯一可以访问Action类的路径。
     
            *   extends
                表示继承的包名。

            *   abstract
                可以取值为true或false,(true)表示可以用于继承。

        2)<action>
                用于声明一个Action类。
            *   name
                表示一个Action类的名称,在同一个包内,Action的名称是唯一的。
                它与<package>元素中的namespace属性确定了一个访问Action类的路径。

            *   class
                Action类的完整包名

            *   method(请求处理方法)
                表示要访问的Action类中的方法的名称。

        3)<result>
                用于确定返回结果。

            *   name
                与Action类中的方法返回值做对比,确定跳转路径。

            *   type
                确定跳转处理方式。

    2、关于Action配置其他细节
        1)默认值:
            <package namespace="默认值">
                *   namespace的默认值是"/";

            <action class="默认值" method="默认值">
                *   class的默认值:com.opensymphony.xwork2.ActionSupport
                *   method默认值:ActionSupport类中的execute()方法

            <result name="默认值">
                *   name的默认值是execute()方法的返回值return SUCCESS;,也就是"success"。

        2)关于访问Action的路径问题
            现在的Action配置是:
                <package name="default" namespace="/" extends="struts-default">
                    <action name="hello" class="com.wyc.action.DefaultAction">
                        <resule>/hello.jsp</result>
                    </action>
                </package>

            当输入:http://localhost/Struts2_day01_2/a/b/c/hello时,也可以访问到Action类。

            因为:Struts2中的Action被访问时,它会首先查找:
                1: namespace="/a/b/c"    action的name=hello,没有找到
                2: namespace="/a/b"       action的name=hello,没有找到
                3: namespace="/a"          action的name=hello,没有找到
                4: namespace="/"            action的name=hello,找到了

                如果最后也查找不到,会报404错误。

        3)默认的处理请求Action
            作用:处理其他Action处理不了的路径。
            <default-action-ref name="action的name属性" />
            配置这个元素后,当所有的Action无法处理访问路径时,会执行name指定的<action>元素。
            只在同包中有效。

        4)Action的默认处理类
            在Action配置时,如果不写class属性,默认是:comm.opensymphony.xwork2.ActionSupport。
            <default-class-ref class="com.wyc.action.DefaultAction"/>
            配置这个元素后,在当前包中,如果<action>元素不写class属性,那么默认处理Action请求的处理类就为class指定的类。
            只在同包中有效。

    3、关于Struts2中的常量配置
        在default.properties文件中声明了Struts2中的常量。

        可以在哪些文件中配置常量?
            *   struts.xml(应用最多)
                >   <constant name="常量名称" value="常量值"></constant>
            *   struts.properties(基本不用)
            *   web.xml(了解)
                >   在<filter>元素下通过<init-param>初始化参数进行配置。
                >   在web.xml文件中配置的常量会覆盖struts.xml文件中的配置。

        1)常用常量:
            *   struts.action.extension=action,,
                这个常量用于指定Struts2框架默认拦截的后缀名,例如:
                    localhost/Struts2_day01/hello.action(可以访问)
                    localhost/Struts2_day01/hello(可以访问)
                    localhost/Struts2_day01/hello.abc(不可以访问)
                在struts.xml文件中设置:
                    <constant name="struts.action.extension" value="abc,,"></constant>
                运行结果如下:
                    localhost/Struts2_day01/hello.action(不可以访问)
                    localhost/Struts2_day01/hello(可以访问)
                    localhost/Struts2_day01/hello.abc(可以访问)

            *   struts.i18n.encoding=UTF-8
                相当于request.setCharacterEncoding("UTF-8");,可以解决POST请求的乱码问题。

            *   struts.serve.static.browserCache=false
                false表示不缓存,true表示浏览器会缓存静态内容,产品环境设置true,开发环境设置false。

            *    struts.devMode=true
                DevelopModel,开发模式,相当于热部署。
                修改struts.xml文件后不需要重启服务器。
                提供详细报错页面,而不是只显示404等错误信息。

            *   struts.configuration.xml.reload=true
                当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开 



    4、struts.xml文件的分离
        因为多个模块的package太多会影响阅读,为了方便阅读,所以可以让一个模块保存一个配置文件,将多个package分离,使用时引入配置文件即可。
        引入方式:
            <include file="文件路径" />

    ——Action类的创建方式

    1、有三种创建方式:
        1)创建一个POJO类(直接创建一个class)
            POJO类表示没实现任何接口,没继承任何父类,除了Object类。
            优点:无耦合。
            缺点:所有工作都要自己实现,代码量大。

            底层通过反射来实现:
                Struts2框架读取struts.xml获得完整Action类名 —— object = Class.forName(完整类名).newInstance() —— Method m = obj.getMethod("execute"); —— m.invoke(obj); 通过反射执行execute()方法。

        2)实现Action接口
            为了让用户开发的Action更加规范,Struts2提供了一个Action接口。
            创建一个类,实现Action接口:com.opensymphony.xwork2.Action
            优点:耦合低,提供了五种逻辑视图(字符串常量),定义了一个行为方法(execute())。
            缺点:所有工作都要自己实现,但是已经得到标准规范。

            五种逻辑视图:(Action处理数据后进行页面跳转)
                public static final String SUCCESS = "success";    // 数据处理成功(成功页面)
                public static final String NONE = "none";    // 页面不跳转,与return null 效果相同
                public static final String ERROR = "error";    // 数据处理发送错误(错误页面)
                public static final String INPUT = "input";    // 用户输入数据有误,通常用于校验表单数据
                public static final String LOGIN = "login";    // 主要权限认证(登录页面)

            示例代码:
                public class HelloAction implements Action {
                    public String execute(){
                        System.out.println("hello");
                        return "success";
                    }
                }

        3)继承ActionSupport(推荐)
            com.opensymphony.xwork2.ActionSupport类实现了Action接口。
            优点:功能比较完善,ActionSupport支持校验(实现Validateable接口)、错误信息设置、支持国际化(实现LocaleProvider接口)
            缺点:耦合度高。

            示例代码:
                public class HelloAction2 extends ActionSupport {
                    @Override
                    public String execute(){
                        System.out.println("hello");
                        // return "success";
                        return NONE; // 相当于return null;
                    }
                }

    ——关于Action的访问

    如果没有指定method属性,则默认执行execute()方法。

    1、通过设置method的属性值,来确定访问action类中的哪一个方法。

        <package name="book" namespace="/" extends="struts-default">
            <action name="book_add" class="com.wyc.action.BookAction" method="add"></action>
            <action name="book_update" class="com.wyc.action.BookAction" method="update"></action>
            <action name="book_delete" class="com.wyc.action.BookAction" method="delete"></action>
            <action name="book_search" class="com.wyc.action.BookAction" method="search"></action>
        </package>

        当访问book_add时,会调用BookAction类中的add方法,以此类推。

    2、使用通配符来简化配置
        1)在struts.xml文件中配置:
            <action name="*_*" class="com.wyc.action.{1}Action" method="{2}"></action>

        2)在JSP页面中创建两个页面:book.jsp、product.jsp
            book.jsp:
                <body>
                    <a href="${pageContext.request.contextPath }/Book_add">book add</a>
                    <a href="${pageContext.request.contextPath }/Book_update">book update</a>
                    <a href="${pageContext.request.contextPath }/Book_delete">book delete</a>
                    <a href="${pageContext.request.contextPath }/Book_search">book search</a>
                </body>

            product.jsp:
                <body>
                    <a href="${pageContext.request.contextPath }/Product_add">product add</a>
                    <a href="${pageContext.request.contextPath }/Product_update">product update</a>
                    <a href="${pageContext.request.contextPath }/Product_delete">product delete</a>
                    <a href="${pageContext.request.contextPath }/Product_search">product search</a>
                </body>

            当访问book add时,这时的路径是:Book_add,那么对于struts.xml文件中第一个“*”就是Book,第二个“*”就是add。
            对于{1}Action就相当于BookAction,对于method="{2}",就相当于method="add"

        3)、使用通配符配置时注意事项:
           *   必须定义一个统一的命名规范
           *   不建议使用过多的通配符,影响阅读性

    3、动态方法调用(了解)
        在struts.xml文件中配置:
            <action name="book" class="com.wyc.action.BookAction"></action>
        访问:http://localhost/Struts2_day01_2/book!add
        就可以访问到BookAction类中的add方法了。

        book!add就是动态方法调用,叹号后面写的就是方法名。

        注意:
            Struts2框架支持动态方法调用,可以在default.properties中设置动态方法调用为true
            struts.enable.DynamicMethodInvocation = true

    ——在Struts2框架中获取Servlet API

    对于Struts2框架,不建议直接使用Servlet API。

    在Struts2中获取Servlet API有三种方式:
        1、通过ActionContext获取
            *   获取一个ActionContext对象
                >   ActionContext context = ActionContext();
            *   获取Servlet API
                >   通过ActionContext获取到的不是真正的Servlet API,而是一个Map集合,集合中存放的就是对象(用键值对)存放的数据。
        2、通过注入方式获取
        3、通过ServletActionContext获取

    ----------------------------------------------------------------------------------------------------------------------------

    1、Action访问Servlet
        在Action中用解耦和方式使用ActionContext对象间接访问Servlet API。
        在Struts2中Action API已经与Servlet API解耦和了(没有依赖关系)。
        Servlet API常见操作:
            *   获取表单提交请求参数
            *   向request, session, application三个作用域存取数据

        开发中应优先使用ActionContext,这样可以避免耦合。

    ActionContext方法:
        *   Map  getParameters()
            获取所有请求参数的Map集合。
            Map底层是一个HashMap。

        *   void  put(String key, Object value)
            对request域存放数据。

        *   Map  getApplication()
            获取ServletContext数据Map,对应用访问存取数据。

        *   Map  getSession()
            获取session数据Map,对Session范围存取数据。

    /*
     * 通过ActionContext获取Servlet API
     */
    public class ServletDemo1Action extends ActionSupport {
     
        @Override
        public String execute() throws Exception {
            /*
             * 1、获取ActionContext对象
             */
            ActionContext context = ActionContext.getContext();
     
            /*
             * 2、获取Servlet API
             */
     
            // 获取application中数据
            Map<String, Object> applicationMap = context.getApplication();
            System.out.println("application: " + applicationMap.get("aname"));
     
            // 获取session中数据
            Map<String, Object> sessionMap = context.getSession();
            System.out.println("session: " + sessionMap.get("sname"));
     
            return NONE;
        }
    }

    ----------------------------------------------------------------------------------------------------------------------------

    2、使用接口注入的方式操作Servlet API(耦合)
        这种方式能够真正获取到Web对象。

        步骤:
            1)要求Action类必须实现指定接口:
                ServletContextAware接口:注入ServletContext对象
                ServletRequestAware接口:注入request对象
                ServletResponseAware接口:注入response对象
            2)重写接口中指定的方法:
                public void setServletRequest(HttpServletRequest request)
            3)声明一个web对象,使用接口中的方法对声明的web对象赋值
                private HttpServletRequest request;
                public void setServletRequest(HttpServletRequest request){
                    this.request = request;
                }

        示例代码:

            /*
             * 通过注入方式获取Servlet API
             */
            public class ServletDemo2Action extends ActionSupport implements ServletRequestAware {
                private HttpServletRequest request;
     
                public String execute() {
     
                    System.out.println(request.getParameter("username"));
     
                    return null;
                }
     
                /*
                 * 实现接口方法
                 */
                public void setServletRequest(HttpServletRequest request) {
                    this.request = request;
                }
            }


        分析其实现方法:
            通过Struts2的interceptor实现的。
            struts-default.xml:
                <interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor"/>
            源码:
                org.apache.struts2.interceptor.ServletConfigInterceptor拦截器中的intercept()方法:
                    public String intercept(ActionInvocation invocation) throws Exception {
                        final Object action = invocation.getAction();
                        final ActionContext context = invocation.getInvocationContext();
     
                        if (action instanceof ServletRequestAware) {    // 判断Action类是否实现了ServletRequestAware接口
                            HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST);    // 得到request对象
                            // 因为action是Object类型,所以需要强转 
                            ((ServletRequestAware) action).setServletRequest(request);    // 将request对象通过Action中重写的方法注入,
                        }
                        ....... 
                        return invocation.invoke();
                    }

    ----------------------------------------------------------------------------------------------------------------------------

    3、通过ServletActionContext获取Servlet API
        在ServletActionContext中方法都是静态的。
        该类的父类是ActionContext,其内部代码也是通过ActionContext获取到的。

        方法概要:
            static PageContext  getPageContext()
                获取PageContext对象。

            static HttpServletRequest  getRequest()
                获取request对象。

            static HttpServletResponse  getResponse()
                获取response对象。

            static ServletContext  getServletContext()
                获取ServletContext对象。

            没有getSession()方法,但是可以通过getPageContext().getSession()获得。
            有了pageContext,其它八个对象都可以得到。

        示例代码:

            /*
             * 通过ServletActionContext获取Servlet API
             */
            public class ServletDemo3Action extends ActionSupport {
                public String execute() {
     
                    HttpServletRequest request = ServletActionContext.getRequest();
     
                    System.out.println(request.getParameter("username"));
     
                    return null;
                }
            }

    ——Result结果类型

    在:struts-default.xml文件中定义。

    1、理解处理结果
        *   Action处理完用户请求后,会返回一个普通字符串。
        *   整个普通字符串就是一个逻辑视图名。
        *   Struts2根据逻辑视图名,决定运行哪个结果。
        *   Struts2处理结果使用<result>元素进行配置。
            >   局部结果:将<result>作为<action>的子元素进行配置
            >   全局结果:将<result>作为<global-result>的子元素进行配置
        *   配置<result>元素通常需要指定两个属性
            >   name:该属性指定配置逻辑视图名
            >   type:该属性指定结果类型(跳转方式、处理方式)

    2、<result>标签属性:
        *   name属性:
            与action中的method的返回值匹配,获取跳转路径,进行跳转。

        *   type属性:
            作用是定义跳转方式。
            对于type属性的取值范围有以下几种:(可以在struts-default.xml文件中查看)
            >   chain:请求转发,一般情况下用于从一个Action跳转到另一个Action。
            >   dispatcher:请求转发,是默认值,一般用于从Action跳转到jsp页面。
            >   freemarker:模板技术,将页面与数据分离,通过freemarker将数据和页面整合到一起。
            >   httpheader
            >   plainText
            >   redirect:重定向,一般用于从Action重定向到页面。
            >   redirectAction:重定向,一般用于从Action重定向到另一个Action。
                redirectAction有两个参数:
                    actionname:指定目标Action的名称,它是默认属性。
                    namespace:用来指定目标Action的名称空间,默认为"/"。 
            >   stream:代表从服务器端返回一个流,一般用于下载。
            >   velocity:模板引擎
            >   xslt

        <package name="struts-default" abstract="true">
            <result-types>
                <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
                <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
                <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
                <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
                <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
                <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
                <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
                <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
                <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
                <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
            </result-types>
        </package>

        必须掌握:
            chain、dispatcher、redirect、redirectAction、stream
            两个转发、两个重定向、一个流。 
        了解:freemarker、velocity

    3、局部结果页面与全局结果页面
        当多个action中都是用了相同的result,这时可以把result定义为全局结果页面。
    <struts>
        <package name="default" namespace="/" extends="struts-default">
     
            <!-- 全局结果,当前package中的Action都可以使用 -->
            <global-results>
                <result>/demo2_success.jsp</result>
                <!-- 当存在多个result时,以后面的result为准 -->
                <result>/demo1_success.jsp</result>
            </global-results>

            <action name="demo1" class="com.wyc.action.ServletDemo1Action">
                <!-- 局部结果,仅限当前Action使用 -->
                <result>/demo1_success.jsp</result>
            </action>
            <action name="demo2" class="com.wyc.action.ServletDemo2Action">
                <!-- 如果当前action下没有result,那么就会到全局中查找 -->
            </action>
            <action name="demo3" class="com.wyc.action.ServletDemo3Action"></action>
        </package>
    </struts>

    ——练习:登录操作

    1、需求:
        用户通过表单进行登录,登陆失败将页面转发到login.jsp,并显示错误信息。
        登录成功后将用户存储到Session中,重定向到success.jsp页面,并展示用户信息。

    2、所需页面
        login.jsp
            >   提供登录表单
            >   登录失败时显示错误信息
        success.jsp
            >   登录成功后通过session获取用户信息并显示到页面
     
    3、所需类
        LoginAction
            >   获取Servlet API,获取表单信息
            >   校验用户信息
                >   登录成功,重定向到success.jsp
                >   登录失败,转发到login.jsp
        User类
            实体类
            >   private String username;
            >   private String password;

    ——总结

        1、Struts2环境搭建
            *   导入jar包:
                >   struts2/apps/strut_blank.war文件
            *   web.xml如何配置:
                >   配置StrutsPrepareAndExecuteFilter
            *   struts.xml如何配置:
                >   在src目录下(classes)
        2、Struts2运行流程
            *   如何通过反射执行action
        3、配置文件加载顺序
            *   每个配置文件的用途是什么
            1)default.properties
            2)struts-default.xml  struts-plugin.xml  struts.xml
            3)struts.properties
            4)web.xml 
        4、<package><action><result>元素的配置
            *   package:用于管理action
                >   name:包名,唯一
                >   namespace:与action的name属性确定访问action的路径。
                >   extends:继承的包名,一般继承struts-default
            *   action:声明一个action
                >   name:action名称,在同一个包下不能重名
                >   class:action完整类名,默认是ActionSupport
                >   method:action类中的方法名,要求无参,返回值为String,默认值为execute
            *   result:结果视图
                >   name:与action的method方法的返回值进行匹配确定跳转路径
                >   type:跳转方式
                    在struts-default.xml文件中定义:
                        chain, dispatcher, redirect, redirectAction, stream
        5、Action的三种创建方式
            *   POJO
            *   实现Action接口
            *   继承ActionSupport类
        6、指定method的调用方法
            *   指定method属性
            *   通配符
            *   动态方法调用
        7、Action访问Servlet API
            *   ActionContext
            *   访问指定接口(注入)
            *   ServletActionContext
        8、结果类型
            *   <result>标签的type属性取值。
        9、自定义常量
            *   在struts.xml文件中定义
                >   <constant name="" value="" />
            *   在struts.properties文件中定义
            *   在web.xml文件中定义 
                >   <init-param></initparam>
     
    ——Struts2核心知识点及问题

    1、struts2在web.xml配置的Filter叫什么?
    2、struts2的Action有几种书写方式?
    3、能否在struts2的Action定义多个业务方法?如何做到不同的请求访问Action的不同方法?
    4、自定义struts2类型转换器实现实现哪个接口,如何配置局部转换器和全局转换器?
    5、struts2的国际化信息文件有哪几类?
    6、xml进行struts2请求参数校验时,指定方法的校验文件和所有方法校验文件命名规则是什么?
    7、struts2的Action中如何使用ServletAPI?
    8、简单描述struts2的值栈对象的内部存储结构
    9、addFieldError、addActionError和addActionMessage 有何区别?
    10、struts2中有哪些常用结果类型?你用过哪些?
    11、你是否在struts2开发中 自定义过拦截器,实现什么功能?
    12、struts2 UI主题有哪些?你用过哪些? 底层实现是什么?
    13、struts2 和 struts1 有何区别?
    14、struts2 中如何使用 Ajax ?
    15、struts2 的拦截器使用了哪种设计模式 ?
     
    ——关于Struts2中约定访问规则

    从struts2.1开始,struts2 引入了Convention插件来支持零配置
    使用约定无需struts.xml或者Annotation配置
    需要 struts2-convention-plugin-2.3.7.jar 、asm-*.jar(三个)
    插件会自动搜索action、actions、struts、struts2包下所有Java类
    所有实现了com.opensymphony.xwork2.Action的Java类
    所有类名以Action结尾的Java类
    下面类名都符合Convention插件
    cn.itcast.struts2.HelloAction
    cn.itcast.actions.books.BookSearchAction
    cn.itcast.struts.user.UserAction
    cn.itcast.estore.action.test.LoginAction
     
     
    struts2-convention-plugin-2.3.7.jar 中struts-plugin.xml重要常量
    <constant name="struts.convention.package.locators" value="action,actions,struts,struts2"/>  默认扫描包
    <constant name="struts.convention.exclude.packages" value="org.apache.struts.*,org.apache.struts2.*,org.springframework.web.struts.*,org.springframework.web.struts2.*,org.hibernate.*"/> 不扫描
    <constant name="struts.convention.action.suffix" value="Action"/> 默认扫描以Action结尾的类
    <constant name="struts.convention.result.path" value="/WEB-INF/content/"/> 结果result页面存放位置
    <constant name="struts.convention.classes.reload" value="false" /> Action类文件重新自动加载
     
    如果Action类名包含Action后缀,将Action后缀去掉
    将Action类名的驼峰写法,转成中划线写法
    例如:
    cn.itcast.struts2.HelloAction 映射到 /hello.action
    cn.itcast.actions.books.BookSearchAction  映射到 /books/book-search.action
    cn.itcast.struts.user.UserAction 映射到 /user/user.action
    cn.itcast.estore.action.test.LoginAction 映射到 /test/login.action
     
    默认情况下,Convention总会到Web应用的WEB-INF/content路径下定位结果资源
    <constant name="struts.convention.result.path" value="/WEB-INF/content/"/>
    约定: actionName + resultCode + suffix 
    例如:
    访问cn.itcast.struts.user.UserAction返回success
    Convention优先使用 WEB-INF/content/user/user-success.jsp
    如果user-success.jsp不存在,会使用user-success.html
    如果user-success.html不存在,会使用user.jsp
  • 相关阅读:
    【POJ 3162】 Walking Race (树形DP-求树上最长路径问题,+单调队列)
    【POJ 2152】 Fire (树形DP)
    【POJ 1741】 Tree (树的点分治)
    【POJ 2486】 Apple Tree (树形DP)
    【HDU 3810】 Magina (01背包,优先队列优化,并查集)
    【SGU 390】Tickets (数位DP)
    【SPOJ 2319】 BIGSEQ
    【SPOJ 1182】 SORTBIT
    【HDU 5456】 Matches Puzzle Game (数位DP)
    【HDU 3652】 B-number (数位DP)
  • 原文地址:https://www.cnblogs.com/wwwwyc/p/6375396.html
Copyright © 2011-2022 走看看