• Struts笔记一


    Struts

    概念:

        是一个MVC框架;

    Servlet的缺点

    1.在web.xml中文件中需要配置很多行代码,维护起来很不方便呢,不利于团队合作。

    2.一个servlet的入口只有一个doPost或者doGet方法,如果在一个servlet在写好几个方法 ,怎么办?

    这样会导致代码结构很乱

    3.servlet类与servlet容器高度耦合,每个方法中都有两个参数,request、response、如果服务器不启动,这两个参数没有办法初始化(单元测试)。

    4.如果在servlet中的一个方法中,有很多功能,这个时候会导致该方法比较复杂、以至于不利于维护。

    用户注册完成四件事情、所以整个方法比较杂乱。

    5.如果一个servlet类中有很多方法、浏览器对这些方法进行请求、URL写起来麻烦

    6.在servlet中如果要获取页面表单中的数据,那么在方法中会写很多行代码。

    Servlet的重构

     目的:

      1.在web.xml文件中只写一个过滤器

      2.用action处理业务逻辑

      3.在过滤器中动态的调用action中的方法处理业务逻辑。

    类的设计:

      

    1.监听器:

      1.准备一个map

      2.把所有的action的key,value放到map中

      3.把map放到application域中;

    2过滤器:

      1.获取application域中的map

      2.解析URL

      3.根据解析的URL从map中把value提取出来

      4.根据java的反射机制动态调用action

      5.根据action返回的方法跳转到相应的页面

    3.执行action的execute方法,该方法返回一个字符串

    实现:

    1.写监听器:

     1 import java.util.HashMap;
     2 import java.util.Map;
     3 
     4 import javax.servlet.ServletContextEvent;
     5 import javax.servlet.ServletContextListener;
     6 
     7 public class ServletListener implements ServletContextListener{
     8     /**
     9      * 在tomcat销毁的时候执行
    10      */
    11     @Override
    12     public void contextDestroyed(ServletContextEvent arg0) {
    13         arg0.getServletContext().setAttribute("mappings", null);
    14     }
    15     /**
    16      *    在tomcat启动的时候执行 
    17      */
    18     @Override
    19     public void contextInitialized(ServletContextEvent arg0) {
    20         Map<String, String> map = new HashMap<String, String>();
    21         map.put("userAction", "com.itheima09.action.UserAction");
    22         arg0.getServletContext().setAttribute("mappings", map);
    23     }
    24 }
    ServletListener

    2.写过滤器:

     1 import java.io.IOException;
     2 import java.lang.reflect.Method;
     3 import java.util.HashMap;
     4 import java.util.Map;
     5 
     6 import javax.servlet.Filter;
     7 import javax.servlet.FilterChain;
     8 import javax.servlet.FilterConfig;
     9 import javax.servlet.ServletContext;
    10 import javax.servlet.ServletException;
    11 import javax.servlet.ServletRequest;
    12 import javax.servlet.ServletResponse;
    13 import javax.servlet.http.HttpServletRequest;
    14 import javax.servlet.http.HttpServletResponse;
    15 
    16 import com.itheima09.servlet.utils.ServletUtils;
    17 
    18 public class DispatcherFilter implements Filter{
    19     
    20     private ServletContext servletContext;
    21 
    22     @Override
    23     public void destroy() {
    24         // TODO Auto-generated method stub
    25         
    26     }
    27 
    28     @Override
    29     public void doFilter(ServletRequest arg0, ServletResponse arg1,
    30             FilterChain arg2) throws IOException, ServletException {
    31         /**
    32          * 1、从 application域中获取map
    33          */
    34         HttpServletRequest request = (HttpServletRequest)arg0;
    35         HttpServletResponse response = (HttpServletResponse)arg1;
    36         Map<String, String> map = (HashMap<String, String>)this.servletContext.getAttribute("mappings");
    37         /**
    38          * 2、获取浏览器中的url,把url解析出来
    39          *     http://localhost:8080/itheima09_servlet_super/userAction.action
    40          *     ---->userAction
    41          */
    42         //mapping = userAction
    43         String mapping = ServletUtils.parse(request.getRequestURI());
    44         String value = map.get(mapping); //value就是action的类的全名
    45         try {
    46             Class class1 = Class.forName(value);
    47             Method method = class1.getMethod("execute", HttpServletRequest.class,HttpServletResponse.class);
    48             //调用了action中的方法
    49             String jspName = (String)method.invoke(class1.newInstance(), request,response);
    50             request.getRequestDispatcher(jspName).forward(request, response);
    51         } catch (Exception e) {
    52             // TODO Auto-generated catch block
    53             e.printStackTrace();
    54         }
    55     }
    56 
    57     @Override
    58     public void init(FilterConfig arg0) throws ServletException {
    59         // TODO Auto-generated method stub
    60         this.servletContext = arg0.getServletContext();
    61     }
    62     
    63 }
    DispatcherFilter

     3.工具类:

     1 import org.junit.Test;
     2 
     3 public class ServletUtils {
     4     /**
     5      * http://localhost:8080/itheima09_servlet_super/userAction.action
     6      * @param url
     7      * @return
     8      */
     9     public static String parse(String url){
    10         String[] array = url.split("/");
    11         String mapping = array[array.length-1].substring(0,array[array.length-1].indexOf("."));
    12         return mapping;
    13     }
    14     
    15     @Test
    16     public void test(){
    17         System.out.println(ServletUtils.parse("http://localhost:8080/itheima09_servlet_super/userAction.action"));
    18     }
    19 }
    ServletUtils

    4.action类:

    1 import javax.servlet.http.HttpServletRequest;
    2 import javax.servlet.http.HttpServletResponse;
    3 
    4 public class UserAction {
    5     public String execute(HttpServletRequest request,HttpServletResponse response){
    6         return "index.jsp";
    7     }
    8 }
    UserAction

    5.配置文件:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
     3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
     5     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
     6     <listener>
     7         <listener-class>com.itheima09.servlet.listener.ServletListener</listener-class>
     8     </listener>
     9     
    10     <filter>
    11         <filter-name>actionFilter</filter-name>
    12         <filter-class>com.itheima09.servlet.filter.DispatcherFilter</filter-class>
    13     </filter>
    14     <filter-mapping>
    15         <filter-name>actionFilter</filter-name>
    16         <url-pattern>*.action</url-pattern>
    17     </filter-mapping>
    18     <welcome-file-list>
    19         <welcome-file>login.jsp</welcome-file>
    20     </welcome-file-list>
    21 </web-app>
    Web.xml

    Struts2的历史

     1.servlet

     2.struts1

        1,写action

        2,写了一个中控的servlet

        3,actionForm和页面表单中的内容一致

    3.webwork(框架MVC):

        1.使得action和servlet容器完全松耦合

        2.属性驱动和模型驱动获取页面上表单中的数据

        3.利用拦截器的概念把servlet容器的第四个缺点克服掉了

    4.struts1+webwork=struts2

    Struct2的第一个例子:

    1.创建一个web project

    2.导入jar包

    3.编写web.xml文件

    4.写一个action

    5.编写struts.xml文件;(放在classpath根目录下)

    6.运行访问:格式:http://localhost:8080/ProjectName/[namespace]/ActionName.action

    解析:

    1.structs.xml文件内容:

    上图为加载流程

    注意:

    1、  struts.xml文件必须放在classpath的根目录下

    2、  名字必须为struts.xml文件

    3、  因为整个加载过程写在了过滤器中的init方法中,所以tomcat启动的时候就把该文件加载了

    2.Package:

    1.目的:用来管理action的;

    从上图可以看出system模块下有三个action

    2.name属性:

      为包名称,是惟一的;

    3.namespace:命名空间,针对URL的

    上述的命名空间针对的是:itheima09_struts2_helloworld/hello

    当浏览器提交一个url:

     

    上述的url直接从项目的根目录查找,所以找不到

     

    该路径和上述的url是对应的

     

    先找hello/a下的action,如果找不到,则查找上一层,再找不到再找上一层,直到找到,如果最上层找不到,则报错

    如果我们的namespace设的是/a 那么:工程名/a/xx/xx/xx.action可以由右向左找到此目录,但是如果在工程名后面写不存在的目录则会报错:工程名xx/xx/a/xx/xx/xx.action这个样就报错了,可以理解为在url中工程名与namespace地址是紧密关联的,

     

    上述的命名空间针对的是:itheima09_struts2_helloworld

    只要命名空间加一层,最后跳转到相应的jsp以后,也会加上相应的路径

     

     

    这样的体系不好。

    4.extends:

      1.在Tomcat启动的时候,不仅仅加载了struts.xml文件,还加载了struts-default.xml文件,而这个文件在classpath下,针对该文件的路径在:

    在一个配置文件中:

    说明helloworld拥有package的名称为struts-default包的所有功能;

    案例:

    Action:

        action元素代表一个类

        class为action的类的全名,可以写,也可以不写

                             如果不写class属性,则默认执行ActionSupport中的execute方法

                                该方法什么都没有做,仅仅返回了一个success字符串

    如图:

    Result

           代表一种结果集

      Type 为结果集的类型

      Name 属性的值和action中某一个方法的返回值一致

      type属性不写,则默认和struts-default中的结果集中的default="true"的结果集保持一致

                            为dispatcher,转发

                             result标签中的内容就是要转发到的页面

    在struts-default.xml文件中

    Name属性也可以不写,如果不写,则默认值为”success”

    Struts2基本用法的其他方法

    Include

           在struts.xml文件中

      

      就可以把struts-helloworld.xml文件包括进来了

    Action的写法

    1.简单的javabean

    2.实现action接口

    3.继承ActionSupport

    .Action和.do

    structs2默认的是以.action为后缀,springmvc是以.do为后缀。structs1也是.do。两者并没什么区别,名字不同而已。

    structs2修改为.do后缀的方法如下:

    可以在struts.xml中costant标签中,设置“struts.action.extension”的值为do即可。。

        <constant name="struts.action.extension" value="do"/>

    并且value可以设置成任意值。比如.hello,.haha。你开心就好

    springmvc我现在还不知道怎么改。但是controller可以接收.html和.do。在web.xml里配置servlet-mapping映射吧

    Action的模式

           在action的构造器中输出一句话,在浏览器中多次请求,可以看到构造器执行了好几次,所以action是多例的。

    结果集:

    转发

    重定向

    重定向到action

    通配符映射

    第一种:

    将执行UrlPatternAction中的execute方法

    第二种:

     

     

    缺点:action中有几个方法就得在配置文件中写几个action元素

    第三种

          

    第四种

          

     

    第五种

          

     标识符:*写什么  {1}就代表什么    <action name=类名_*     method={1}    class=类所在路径

    该模型的好处:如果在action中增加了一个方法,配置文件是不需要改变的,在写url时

    urlPatternAction_后面的内容变成要请求的方法的名称就可以了

    第六种

         

       针对不同action中的同名方法;

      格式:<action name=类名_*     method=方法名    class=类所在路径{1}

    第七种(不推荐)

     

    这么写不好,覆盖范围太大,很有可能出现和其他的action 的配置冲突的情况

    第八种

          

     格式:<action name=类名_*     method={1}    class=类所在路径

        <result>{1}.jsp<result>

    强制让url中的_后面的内容和方法保持一致,跳转到的jsp页面的名称和方法的名称也保持一致。这么写带有一定的规范性

    Struts2与servlet容器的交互

     

    这种方法可以交互,但是这种方法把ServletAction与servlet容器耦合性变高了,不利于测试。

     

    可以通过ServletActionContext把servlet容器相关的类调出来

     

    该写法使得action与servlet容器的耦合性不是很强。

    总结

    1、  sturts2的配置文件中用了package的机制,这样可以分模块

    name是唯一的名称,extends采用了继承的机制

    2、  写的action与servlet容器完全松耦合了

    3、  通配符映射解决:很容器就把一个url映射到一个action的方法中了

    4、  Include保证了可以写多个配置文件

    5、  结果集的封装

         struts内核流程图:

    合群是堕落的开始 优秀的开始是孤行
  • 相关阅读:
    elasticsearch(一):JAVA api操作
    elasticsearch(一):安装与配置
    Apache POI导出excel
    Java实现验证码
    Java数据库连接池原理与简易实现
    SpringMvc注解开发
    类型转换的时候,.valueOf()和.parseX(),.Xvalue()的区别
    kmp算法模板
    java 的任意进制间转换(很方便)
    海伦-秦九韶公式(利用三角形的三边求面积)
  • 原文地址:https://www.cnblogs.com/biaogejiushibiao/p/9372087.html
Copyright © 2020-2023  润新知