【JavaWeb】MVC

79 阅读5分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情

本文项目见:JavaWeb: 本仓库介绍JavaWeb的三个项目。 (gitee.com))

MVC

  • 将各种Servlet转为一个FruitServlet。JavaWeb_mvc 之前的做法是,一个请求对应一个Servlet,这样Servlet太多了。所以把各种Servlet整合为一个FruitServlet。通过一个operator的值决定调用哪个Servlet。这里使用反射获取operator的值。 在这里插入图片描述
  • JavaWeb_mvc00_dispatcher:引入使用中央控制器。 由于每一个Servlet中都有反射代码,所以继续抽取,设计一个中央控制器。

DispatcherServlet类的工作分为两部分:

  1. 根据url定位到能够处理这个请求的Controller组件

    1. 从url中提取ServletPath:/fruit.do——fruit
    2. 根据fruit找到对应的FruitController组件。具体通过applicationController.xml文件,并且使用DOM技术读取配置文件,在中央控制器中形成一个beanMap容器,存放所有的对应关系。
    3. 根据operator的值定位到FruitController需要调用的方法。
  2. 通过反射调用Controller组件中的方法(index、add、del等)

    1. 获取参数

      获取即将要调用的方法的参数签名信息: Parameter[] parameters = method.getParameters(); 通过parameter.getName()获取参数的名称;准备了Object[] parameterValues 这个数组用来存放对应参数的参数值 另外,我们需要考虑参数的类型问题,需要做类型转化的工作。通过parameter.getType()获取参数的类型

    2. 执行方法

      Object returnObj = method.invoke(controllerBean , parameterValues);

    3. 视图处理

      String returnStr = (String)returnObj; if(returnStr.startWith("redirect:")){ .... }else if.....

  • JavaWeb_mvc01_controller:优化Controller中获取参数和重定向/转发的操作。 在这里插入图片描述
  • 关于XML: 概念 HTML:超文本标记语言 XML:可扩展的标记语言 可以认为:HTML是XML的子集。
  • XML的三个部分:
  1. XML声明 , 必须在文件的第一行。
  2. DTD 文档类型定义
  3. XML正文
  • Java8新特性 Parameter[] parameters = method.getParameters(); String name = parameters[0].getName(); 默认获取名称为args0、1等。其实可以获取到属性名。 操作: IDEA下:文件——设置——构建、运行、部署——Java编译器—— 在这里插入图片描述

常见错误:argument type mismatch 使用反射传入pageNo时,parameterValue获取的是字符串类型。所以错误。

Servlet

  1. Servlet生命周期:实例化、初始化、服务、销毁

Servlet中的初始化方法有两个:init() , init(config) 其中带参数的方法代码如下:

        public void init(ServletConfig config) throws ServletException {
       this.config = config ;
       init();
          }
          //另外一个无参的init方法如下:
          public void init() throws ServletException{
          }

如果我们想要在Servlet初始化时做一些准备工作,那么我们可以重写init方法。

我们可以通过如下步骤去获取初始化设置的数据

  • 获取config对象:ServletConfig config = getServletConfig();
  • 获取初始化参数值: config.getInitParameter(key);
  • 在web.xml文件中配置Servlet
<servlet>
    <servlet-name>Demo01Servlet</servlet-name>
    <servlet-class>com.atguigu.servlet.Demo01Servlet</servlet-class>
    <init-param>
        <param-name>hello</param-name>
        <param-value>world</param-value>
    </init-param>
    <init-param>
        <param-name>uname</param-name>
        <param-value>jim</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>Demo01Servlet</servlet-name>
    <url-pattern>/demo01</url-pattern>
</servlet-mapping>

也可以通过注解的方式进行配置:

@WebServlet(urlPatterns = {"/demo01"} ,
initParams = {
    @WebInitParam(name="hello",value="world"),
    @WebInitParam(name="uname",value="jim")
})
  1. 学习Servlet中的ServletContext(application)和

    首先在配置文件中进行配置:

    <!-- 配置上下文参数 -->
        <context-param>
            <param-name>view-prefix</param-name>
            <param-value>/</param-value>
        </context-param>
        <context-param>
            <param-name>view-suffix</param-name>
            <param-value>.html</param-value>
        </context-param>
    
    1. 获取ServletContext,有很多方法。 可以在初始化方法中: ServletContxt servletContext = getServletContext(); 也可以在服务方法中通过request对象获取,也可以通过session获取: request.getServletContext(); session.getServletContext()

    1. 获取初始化值: servletContext.getInitParameter();
  2. 业务层

    1. MVC:Model(模型)、View(视图)、Controller(控制器) 视图层:用于做数据展示以及和用户交互的一个界面 控制层:能够接受客户端的请求,具体的业务功能还是需要借助于模型组件来完成 模型层:模型分为很多种:有比较简单的pojo/vo(value object),有业务模型组件,有数据访问层组件

    1. pojo/vo : 值对象
    2. DAO : 数据访问对象
    3. BO : 业务对象

区分业务对象和数据访问对象: 1) DAO中的方法都是单精度方法(细粒度方法)。什么叫单精度?一个方法只考虑一个操作,比如添加,那就是insert操作、查询那就是select操作.... 2) BO中的方法属于业务方法,而实际的业务是比较复杂的,因此业务方法的粒度是比较粗的。

举例: 注册这个功能属于业务功能,也就是说注册这个方法属于业务方法。 那么这个业务方法中包含了多个DAO方法。也就是说注册这个业务功能需要通过多个DAO方法的组合调用,从而完成注册功能的开发。 注册:

  • 检查用户名是否已经被注册 - DAO中的select操作

  • 向用户表新增一条新用户记录 - DAO中的insert操作

  • 向用户积分表新增一条记录(新用户默认初始化积分100分) - DAO中的insert操作等。

  • 在库存系统中添加业务层组件。见JavaWeb_mvc02_BO

  1. IOC
    1. 耦合/依赖 依赖指的是某某某离不开某某某。在软件系统中,层与层之间是存在依赖的。我们也称之为耦合。我们设计的一个原则是: 高内聚低耦合。 即:层内部的组成应该是高度聚合的,而层与层之间的关系应该是低耦合的,最理想的情况0耦合(就是没有耦合)

    2. IOC - 控制反转 / DI - 依赖注入

    • 控制反转:

      1. 之前在Servlet中,我们创建service对象 , FruitService fruitService = new FruitServiceImpl(); 这句话如果出现在servlet中的某个方法内部,那么这个fruitService的作用域(生命周期)应该就是这个方法级别; 如果这句话出现在servlet的类中,也就是说fruitService是一个成员变量,那么这个fruitService的作用域(生命周期)应该就是这个servlet实例级别
      2. 之后我们在applicationContext.xml中定义了这个fruitService。然后通过解析XML,产生fruitService实例,存放在beanMap中,这个beanMap在一个BeanFactory中。 因此,我们转移(改变)了之前的service实例、dao实例等等他们的生命周期。控制权从程序员转移到BeanFactory。这个现象我们称之为控制反转
    • 依赖注入:

      1. 之前我们在控制层出现代码:FruitService fruitService = new FruitServiceImpl(); 那么,控制层和service层存在耦合。
      2. 之后,我们将代码修改成FruitService fruitService = null ; 然后,在配置文件中配置:
      <bean id="fruit" class="FruitController">
           <property name="fruitService" ref="fruitService"/>
      </bean>
      

现在的项目架构: 在这里插入图片描述