zoukankan      html  css  js  c++  java
  • Struts2(一)— 入门

    一、概述

    1、什么是Struts2

      Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts 2可以理解为WebWork的更新产品。虽然从Struts 1到Struts 2有着太大的变化,但是相对于WebWork,Struts 2的变化很小。

    二、Struts2入门

    1.环境下载

    下载地址:http://struts.apache.org/download.cgi;

    2. 导入jar

    ​ struts的jar比较多,可以从Struts官方提供的demo中拿到必要的jar就行. 在apps/struts2-blank项目下 

    3. 编写Action类

    • 新建一个类,里面定义一个方法

    • /**
       *一,创建了一个普通的类 ,定义了一个execute()方法
       *好比我们之前:创建了一个ProductServlet,然后创建了一个doGet()方法一样
       *二, 配置Action 好比配置Servlet一样,只不过不在web.xml里面配置,自己整了一套
      *   在src目录下struts.xml的文件里面配置
      */
      public class ActionDemo {
          public void execute(){
              System.out.println("收到到了请求...");
          }
       }

    4. 配置struts.xml文件

    • 在src底下新建一个xml 名称为 struts.xml. 在struts.xml里面配置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="test" extends="struts-default" namespace="/">
              <!--一个请求对应一个Servlet, struts2里面一个请求配置一个Action  -->
              <action name="demo" class="com.itheima.web.ActionDemo"></action>
          </package>
      </struts>

    注意:

    1. struts.xml文件名不可随意取,必须叫做struts.xml

    2. struts.xml必须放在src类路径下

    3. 到struts的核心包中可以找到struts-2.3.dtd文件(建议配置本地的dtd,没网情况下也可以使用...)

    5. 前端控制器配置

    • 在web.xml下配置

      <!--前端控制器(过滤器)  -->
      <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>

      其实就是在web.xml中配置struts2的filter

    6. 编写访问路径,进行测试

    http://localhost:8080/day42A_Struts2/demo

    三、Struts2的运行流程

    1.服务器启动(项目部署)

    • 当项目部署的时候,会执行StrutsPrepareAndExecuteFilter的init()方法,在init方法里面有这样的一行代码 :

      dispatcher = init.initDispatcher(config);

      init_DefaultProperties(); // [1] —> 加载 default.properties 常量配置(国际化编码, 文件上传的size...)
      init_TraditionalXmlConfigurations(); // [2] ->加载 struts-default.xml,struts-plugin.xml,struts.xml
      init_LegacyStrutsProperties(); // [3] —> 加载struts.properties
      init_CustomConfigurationProviders(); // [5] ---> 加载自定义的一些初始化类. 一般不写
      init_FilterInitParameters() ; // [6]  ---> 加载初始化参数。 initparam
      init_AliasStandardObjects() ; // [7] ---> 给对象起别名
    • 图示

      顺序配置文件名所在位置说明
      1 default.properties ..srccoresrcmain esourcesorgapachestruts2 不能修改
      2 struts-default.xml ..struts-2.3.32srccoresrcmain esources 不能修改
      3 strtuts-plugin.xml 在struts2提供的插件jar包中 不能修改
      4 struts.xml 我们的应用中 我们修改的:推荐
      5 struts.properties 我们的应用中 我们修改的:不建议用
    • 后面配置的会把前面的覆盖

     

    2.请求到来

    ​ 当我们在浏览器输入请求路径 http://localhost:8080/day01A_Struts2/demo01

    四、Struts.xml中的配置详解

    • eg

      <struts>
          <!--一, package指的是一组请求的集合; 一般一个模块创建一个package
                  1.1 name: 包名; 随便取, 不要重复就行
                  1.2 extends: 继承的意思, 我们当前的test包继承了名字叫struts-default这个包, struts-default这个包里面的功能我们test包都可以使用的
                  1.3 namespace: 名称空间; 用意在于访问action的时候加一层路径(方便自己看的)
                      eg: 当前配置的是/, http://localhost:8080/day42A_Struts2/demo01
                          当前配置的是/test, http://localhost:8080/day42A_Struts2/test/demo01
                  1.4 abstract: 抽象, 用意在于表明这个包是抽象的, 也就是说让别的包继承的; 如果这个包让别的包继承,习惯设置为true
             -->
          <package name="test" extends="struts-default" namespace="/" >
              <!--二, 一个请求配置一个Action标签, 不是说一个请求就要创建一个Action类
                  2.1 name: action的名字,  说白了就是当前action的访问路径. 名字随便取, 不要重复就行了
                  2.2 class:当前Action类的全限定名
                  2.3 method: 处理当前请求的方法; 说白了也就是当前Action类里面的方法名(默认是execute)
               -->
              <action name="demo01" class="com.itheima.web.ActionDemo01"></action>
              <action name="demo01_regist" class="com.itheima.web.ActionDemo01" method="regist">
                  <!--三, 配置的就是结果
                      3.1 name: 结果视图的名字; 说白了就是处理这个请求对应方法的返回值
                      3.2 type: 配置跳转的类型(默认就是转发到页面) 
                      3.3 result标签里面值: 就是要跳转的路径
                    -->
                  <result name="registSuccess">
                      /registSuccess.jsp
                  </result>
              </action>
          </package>
      </struts>

    五、Action进阶

    1、Action规范和特点

    1.1 Action的编写规范
    1. action类需要提供无参构造函数

    2. action中方法规定

      ​ 修饰符:方法的修饰符必须是public

      ​ 参数列表:方法必须是无参方法

      ​ 返回值类型:String

    1.2 action多例性

    ​   每次url访问时,action的实例就会被创建一次。action类是多实例的。

    2.Action的通用写法

    2.1普通类

    ​ 这种方式就是我们最开始给大家写的, 就是一个普通类,然后里面写一个方法,具有String类型返回值即可。

    2.2实现Action接口
    • 好处是 : 我们少写一点代码, 可以使用接口里面定义的常量 SUCCESS ERROR ....

      public class HelloWorld02 implements Action{
          @Override
          public String execute() throws Exception {
              System.out.println("hi struts");
              return SUCCESS;
          }
      }
    2.3继承ActionSupport【重点】

    ​   这种做法,相比较前面的好处在于, ActionSupport 虽然是实现了Action的接口 , 但是内部自己也扩展了些功能 :eg: 提供了信息的校验、并且能够根据校验的结果回到原来的页面。如 : 它里面也集成了获取国际化资源的方法,我们可以直接使用。

    • Java代码

      public class ActionDemo03 extends ActionSupport {
          @Override
          public String execute() throws Exception {
              System.out.println("ActionDemo03 execute()...");
              return SUCCESS;
          }
      }

    3.Action访问的路径配置

    3.1通过method属性访问【重点】

    ​   一般来讲,我们的action类都不会只有一个execute方法,如果存在很多的方法 ,我们如何在struts.xml 里面映射到方法里面去呢? struts提供的第一种方法是在action里面使用method属性来指定访问的具体的方法。 举例如下:

    <action name="user_login" class="com.itheima.web.UserAction" method="login"></action>
    <action name="user_regist" class="com.itheima.web.UserAction" method="regist"></action>
    <action name="user_active" class="com.itheima.web.UserAction" method="active"></action>
    <action name="user_loginout" class="com.itheima.web.UserAction" method="logout"></action>

      这样看上去是挺好的。 直接指定method ,就会找到具体的方法。 但是如果以后我们的方法很多,这样就要配置很多的action标签了。这就不太好维护了。代码先就显得很多,所以这种方式用的不多.

    3.2通过通配符访问【重点】

    ​      通配符的访问其实还是要依赖于method的属性,只不过在匹配来访的地址 和 action的名称的时候使用通配符来匹配。采取method属性访问的方式,一个请求需要写一个Action。

      如果采取通配符的方式,只需要配置一个Action就可以了, *用于表示匹配任意字符。 后面的{1} 就表示能够取到 * 所处位置的字符,然后找到对应的方法。

    <action name="user_*" class="com.itheima.web.UserAction"  method="{1}"></action>

      我们在开发中通常采取通配符方式访问.

    3.3通过动态方法访问【了解】

    ​   第三种方式可读性不强 ,这种方式使用动态代理访问。用的很少. 使用步骤:

    1. 打开动态访问开关,在Struts.xml文件配置

      <constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
    2. 配置Action的名字

      <action name="userAction" class="com.itheima.web.UserAction"></action>
    3. 访问路径通过actionName + !+ action类中的方法名访问

      http://localhost:8080/day02D_Struts2/userAction!login

    知识点补充:Constant用来配置常量值的,目的是修改Struts的default.propertis中的默认值的;

    ​  在Struts.xml中使用 <constant name="" value=""></constant>标签

    • 常量举例

      常量名常量值说明
      struts.i18n.encoding UTF-8 应用中使用的编码
      struts.multipart.maxSize 2097152 文件上传总文件大小限制:2M
      struts.action.extension action,, 能进入Struts2框架内部的url地址后缀名。多个值用逗号分隔
      struts.enable.DynamicMethodInvocation false 是否允许动态方法调用
      struts.devMode false 是否是开发模式。开发模式:改了配置文件,不需要重启。输出更多的错误信息。开发阶段建议为true。
      struts.ui.theme xhtml 页面展示用的主题
    • eg,在struts.xml里面配置常量

      <struts>
          <!-- 一,配置常量的 -->
          <!-- 1.1 打开允许动态方法访问的权限 -->
          <!-- <constant name="struts.enable.DynamicMethodInvocation" value="true"></constant> -->
          <!--1.2 添加action的访问的后缀(有用的,权限的框架(Shiro,SpringSecurity))  -->
          <constant name="struts.action.extension" value="pri,do,action,,"></constant>
          <!-- 1.3配置改了struts.xml配置文件,不需要重启服务器 -->
          <constant name="struts.devMode" value="true"></constant>
      </struts>

    六、Struts2 + Hibernate整合

    1. 案例需求

    • 使用Struts2 + Hibernate完成展示商品的案例.

    2. 案例实现

    2.1 创建web层(struts2)
    • 创建web项目, 导入jar包

    • 创建CategoryAction

      public class CategoryAction extends ActionSupport {
          
          public String findAll(){
              try {
                  //1. 获得请求参数
                  //2. 调用业务
                  CategoryService categoryService = new CategoryService();
                  List<Category> list =  categoryService.findAll();
                  //3. 把list存到域里面, 转发页面 
                  HttpServletRequest request = ServletActionContext.getRequest();
                  request.setAttribute("list", list);
                  return "findAllSuccess";
              } catch (Exception e) {
                  e.printStackTrace();
                  ServletActionContext.getRequest().setAttribute("msg", "查询失败...");
                  return "findAllError";
              }
          }
      }
    • 在classpath(src)目录下创建struts.xml配置CategoryAction

      <?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="category" extends="struts-default" namespace="/">
              <action name="category_*" class="com.itheima.web.CategoryAction" method="{1}">
                  <result name="findAllSuccess">
                      /list.jsp
                  </result>
                  <result name="findAllError">
                      /msg.jsp
                  </result>
              
              </action>
          </package>
      </struts>
    • 在web.xml里面配置前端控制器

      <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>

    3. 发现获得商品的时候出现了bug

    org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.itheima.bean.Category.products, could not initialize proxy - no Session

    1. 使用openSession(), 不手动调用close() [千万不要用]

    2. 不使用懒加载, 再查询类别的同时就把商品查询出来

      <set name="products" fetch="select" lazy="false">
           <!--1.2 column: 外键的列名  -->
           <key column="cid"/>
           <!--1.3  class: 对方类的全限定名  -->
           <one-to-many class="com.itheima.bean.Product"/>
      </set>
    3. 还使用懒加载, 在CategoryDao使用一个商品就行了

  • 相关阅读:
    Eclipse 不能build, pom文件上面有叉叉 解决办法
    WCF分布式开发必备知识(1):MSMQ消息队列
    MSMQ创建消息队列出现“工作组安装计算机不支持该操作”
    在asp.net利用jquery.MultiFile实现多文件上传(转载)
    让ASP.NET MVC不使用jsonp也可以跨域访问
    设计模式学习之适配器模式(Adapter,结构型模式)(14)
    设计模式学习之策略模式(Strategy,行为型模式)(13)
    设计模式学习之命令模式(Command,行为型模式)(12)
    设计模式学习之代理模式(Proxy,结构型模式)(11)
    设计模式学习之组合模式(Composite,结构型模式)(10)
  • 原文地址:https://www.cnblogs.com/gdwkong/p/8360740.html
Copyright © 2011-2022 走看看