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
  • 相关阅读:
    酱茄WordPress社区论坛圈子小程序为解决用户活跃变现而生
    太顶了!爆肝3.5W字长文Java 集合!(建议收藏)
    美团二面:内存耗尽后Redis会发生什么?
    UE4_C++自定义log
    python3进制转换
    UE4蓝图Blueprint->组件->TreeView/ListView
    C++,win编程
    2020-11-11
    b站视频详情数据抓取,自动打包并发送到指定邮箱(单个或者群发)
    BiLiBiLi爬虫
  • 原文地址:https://www.cnblogs.com/wwwwyc/p/6375396.html
Copyright © 2011-2022 走看看