一、MVC模式与三层架构

1、MVC 模式

MVC 模式,全称为 Model-View-Controller(模型-视图-控制器)模式,它是一种软件架构模式,其目标是将软件的用户界面(即前台页面)和业务逻辑分离,使代码具有更高的可扩展性、可复用性、可维护性以及灵活性。

MVC 模式将应用程序划分成模型(Model)、视图(View)、控制器(Controller)等三层,如下图所示:

java controller 怎么调用controller的方法 java中的controller层_servlet

分层

描述

Model(模型)

它是应用程序的主体部分,主要由以下 2 部分组成: 实体类 Bean:专门用来存储业务数据的对象,它们通常与数据库中的某个表对应,例如 User、Student 等。业务处理 Bean:指 Service 或 Dao 的对象,专门用于处理业务逻辑、数据库访问。一个模型可以为多个视图(View)提供数据,一套模型(Model)的代码只需写一次就可以被多个视图重用,有效地减少了代码的重复性,增加了代码的可复用性。

View(视图)

指在应用程序中专门用来与浏览器进行交互,展示数据的资源。在 Web 应用中,View 就是我们常说的前台页面,通常由 HTML、JSP、CSS、JavaScript 等组成。

Controller(控制器

通常指的是,应用程序的 Servlet。它负责将用户的请求交给模型(Model)层进行处理,并将 Model 层处理完成的数据,返回给视图(View)渲染并展示给用户。在这个过程中,Controller 层不会做任何业务处理,它只是 View(视图)层和 Model (模型)层连接的枢纽,负责调度 View 层和 Model 层,将用户界面和业务逻辑合理的组织在一起,起粘合剂的效果。

2、三层架构

和 MVC 模式类似,三层架构同样将系统划分成了 3 层:

  • 表示层(UI):用来实现与用户的交互,接收用户请求,并将请求交给业务逻辑层(BLL)和数据访问层(DAL)进行处理,最后将处理结果返回给用户。
  • 业务逻辑层(BLL):起到承上启下的作用,接收表示层传递来的请求,并针对业务对数据进行处理,以实现业务目标。
  • 数据访问层(DAL):用于实现与数据库的交互和访问,例如从数据库中获取数据、保存或修改数据库中的数据等。

虽然三层架构和 MVC 模式一样,都是将应用划分成了 3 层,但它们的划分方式是不同的。

下图展示了三层架构的划分方式,我们可以很清楚地分辨出它与 MVC 模式的不同。

java controller 怎么调用controller的方法 java中的controller层_spring_02


从上图可以看出,三层架构是由表示层(UI)、业务逻辑层(BLL)和数据访问层(DAL)三个层次构成的,而 MVC 则是由视图(View)层、控制(Controller)层以及模型(Model)层,且它们之间并不是一一对应的。

三层架构将应用中的各个模块划分为表示层(UI)、业务逻辑层(BLL)和数据访问层(DAL)等三层,各层之间采用接口相互访问,并通过实体类作为数据传递的载体。不同的实体类一般对应于数据库中不同的数据表,且实体类的属性与数据库表的字段名一一对应 。

3、MVC 模式和三层架构中各层对应关系

  • 三层架构中的表示层(UI)包含 HTML、JSP 等前台页面以及后台的 Servlet,即它相当于 MVC 模式中的 View 层 + Controller 层。
  • 三层架构中的业务逻辑层(BLL),则只包含了 Service 接口及其实现类(Servicelmpl)的代码,即它相当于 MVC 模式中 Model 层的一部分,并不包含 Dao 和实体类。
  • 三层架构中的数据访问层(DAL),则只包含了 Dao 接口及其实现类(DaoImpl)的代码,即它相当于 MVC 模式中 Model 层的一部分,并不包含 Service 和实体类。

从上面的划分方式来看,三层架构和 MVC 模式确实是不一样的,但从它们的核心来看,两者又是一样的,它们的核心都是“分层、解耦”。

二、MVC 的工作流程及优缺点

1、MVC 的工作流程

MVC 的工作流程如下:

  1. 用户发送请求到服务器;
  2. 在服务器中,请求被控制层(Controller)接收;
  3. Controller 调用相应的 Model 层处理请求;
  4. Model 层处理完毕将结果返回到 Controller;
  5. Controller 再根据 Model 返回的请求处理结果,找到相应的 View 视图;
  6. View 视图渲染数据后最终响应给浏览器。

2、MVC 的优点

MVC 模式具有以下优点:

  • 降低代码耦合性:在 MVC 模式中,三层之间相互独立,各司其职。一旦某一层的需求发生了变化,我们就只需要更改相应层中的代码即可,而不会对其他层中的代码造成影响。
  • 有利于分工合作:在 MVC 模式中,将应用系统划分成了三个不同的层次,可以更好地实现开发分工。例如,网页设计人员专注于视图(View)层的开发,而那些对业务熟悉的开发人员对 Model 层进行开发,其他对业务不熟悉的开发人员则可以对 Controller 层进行开发。
  • 有利于组件的重用:在 MVC 中,多个视图(View)可以共享同一个模型(Model),大大提高了系统中代码的可重用性。

3、MVC 的缺点

MVC 模式存在以下不足之处:

  • 增加了系统结构和实现的复杂性:对于简单的应用,如果也严格遵循 MVC 模式,按照模型、视图与控制器对系统进行划分,无疑会增加系统结构的复杂性,并可能产生过多的更新操作,降低运行效率。
  • 视图与控制器间的联系过于紧密:虽然视图与控制器是相互分离的,但它们之间联系却是十分紧密的。视图没有控制器的存在,其应用是很有限的,反之亦然,这样就妨碍了它们的独立重用。
  • 视图对模型数据的低效率访问:视图可能需要多次调用才能获得足够的显示数据。对未变化数据的不必要的频繁访问,也将损害操作性能。

4、SpringMVC概述

SpringMVC 是一种基于 Java 实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,它和 Struts2 都属于表现层的框架,属于 Spring FrameWork 的后续产品,Spring MVC 分离了控制器、模型对象、过滤器以及处理程序对象的角色,这种分离让它们更容易进行定制。

SpringMVC 已经成为目前最主流的 MVC 框架之一,并且随着 Spring3.0 的发布,全面超越 Struts2,成 为最优秀的 MVC 框架,它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持 RESTful 编程风格的请求。

SpringMVC是一种基于Java实现MVC模型轻量级框架, 底层基于Servlet封装。

三、SpringMVC环境搭建(注解启动方式)

1、创建Maven项目

java controller 怎么调用controller的方法 java中的controller层_spring_03

2、导入Maven依赖

在pom.xml中添加 Maven 依赖。

<!-- 整合springmvc框架依赖  -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.1.RELEASE</version>
</dependency>

<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>3.1.0</version>
  <scope>provided</scope>
</dependency>

3、创建控制器层

  • 创建java文件夹,并创建控制器层。

java controller 怎么调用controller的方法 java中的controller层_MVC_04

  • 控制器:
package com.qizekj.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.Map;

/**
 * @author chenqun
 * @date 2023/3/18 13:03
 */
@Controller
public class QizekjController {
    /**
     * 1.@Controller作用:需要在我们的类上加上@Controller注解 标记该类是为springmvc控制类
     * 2. @RequestMapping:定义url映射
     * 3. @ResponseBody:该接口返回我们的json数据
     */
    /**
     * 访问到该请求 返回json数据
     * @return
     */
//    @RequestMapping("/getQizekj")
//    @ResponseBody
//    public Map<String, Object> getQizekj() {
//        HashMap<String, Object> result = new HashMap<>();
//        result.put("code", "200");
//        result.put("msg", "ok");
//        //访问该接口的 返回json数据
//        return result;
//    }
    @RequestMapping("/getQizekj")
    @ResponseBody
    public String getQizekj() {
        return "{code:'200',msg:'ok'}";
    }

}

4、创建配置类

package com.qizekj.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
 * @author chenqun
 * @date 2023/3/18 13:07
 */
@Configuration
@ComponentScan("com.qizekj.controller")
public class SpringMVCConfig {
    /**
     * 1.@Configuration  定义SpringMVCConfig.xml配置文件
     * 2.需要将我们的控制类注入到ioc容器 @ComponentScan("com.qizekj.springmvc")
     * @ComponentScan("com.qizekj.springmvc")将该包下所有的类 注入到IOC容器种
     * 3.在springmvc原理 所有请求过来先达到DispatcherServlet 分发具体控制类 方法执行
     */
}

5、注册配置类

package com.qizekj.config;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;

/**
 * @author chenqun
 * @date 2023/3/18 13:09
 */
public class ServletInitializer extends AbstractDispatcherServletInitializer {

    @Override
    protected WebApplicationContext createServletApplicationContext() {
        // 注册我们的 springmvc config 配置类
        AnnotationConfigWebApplicationContext annotationConfigWebApplicationContext
                = new AnnotationConfigWebApplicationContext();
        annotationConfigWebApplicationContext.register(SpringMVCConfig.class);
        return annotationConfigWebApplicationContext;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    @Override
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }
}

6、maven tomcat插件运行

  • pom.xml中添加tomcat插件代码
<build>
    <plugins>
        <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat8-maven-plugin</artifactId>
                <version>3.0-r1655215</version>
                <configuration>
                    <port>85</port>
                    <path>/</path>
                    <ignorePackaging>true</ignorePackaging>
                </configuration>
            </plugin>
    </plugins>
</build>
  • 如果下载不了tomcat8插件就要添加本地仓库:
<pluginRepositories>
   <pluginRepository>
       <id>alfresco-public</id>
       <url>https://artifacts.alfresco.com/nexus/content/groups/public</url>
   </pluginRepository>
   <pluginRepository>
       <id>alfresco-public-snapshots</id>
       <url>https://artifacts.alfresco.com/nexus/content/groups/public-snapshots</url>
       <snapshots>
           <enabled>true</enabled>
           <updatePolicy>daily</updatePolicy>
       </snapshots>
   </pluginRepository>
   <pluginRepository>
       <id>beardedgeeks-releases</id>
       <url>http://beardedgeeks.googlecode.com/svn/repository/releases</url>
   </pluginRepository>
</pluginRepositories>
  • 配置Tomcat执行:

java controller 怎么调用controller的方法 java中的controller层_spring_05

  • 执行Tomcat:

java controller 怎么调用controller的方法 java中的controller层_mvc_06

  • 运行结果:

java controller 怎么调用controller的方法 java中的controller层_mvc_07

  • 通过浏览器访问:

http://localhost:8081/getQizekj

java controller 怎么调用controller的方法 java中的controller层_MVC_08

7、搭建环境常见问题

  • 扫包范围填写错误 @ComponentScan(“com.qizekj.controller”)
  • 在控制类没有加上@Controller 导致接口访问404

四、SpringMVC环境搭建(xml启动方式)

1、Maven依赖

<!-- 整合springmvc框架依赖  -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.1.RELEASE</version>
</dependency>

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>

2、定义控制器

package com.qizekj.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @author chenqun
 * @date 2023/3/18 15:51
 */
@Controller
public class QizekjController {
    /**
     * 1.@Controller作用:需要在我们的类上加上@Controller注解 标记该类是为springmvc控制类
     * 2. @RequestMapping:定义url映射
     * 3. @ResponseBody:该接口返回我们的json数据
     */
    /**
     * 访问到该请求 返回json数据
     * @return
     */

    @RequestMapping("/getQizekj")
    @ResponseBody
    public String getQizekj() {
        return "{code:'200',msg:'ok'}";
    }
}

3、创建spring-mvc.xml并配置扫描

  • 创建resources文件夹,并创建spring-mvc.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!--1.配置spring创建容器时要扫描的包-->
    <context:component-scan base-package="com.qizekj.controller"></context:component-scan>
    <!--2.配置spring开启注解mvc 的支持-->
    <mvc:annotation-driven></mvc:annotation-driven>

</beans>

4、web.xml配置

  • 所有请求过来都是先达到 DispatcherServlet
  • springmvc 是基于 Servlet 封装的
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">

  <!-- SpringMVC前端控制器 -->
  <!-- 配置springmvc DispatcherServlet -->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <!--运用的是java反射机制加载-->
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--servlet初始化时需要加载-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <!--此处配置是为了让springmvc DispatcherServlet优先加载-->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <!--客户端发送所有请求都会先达到DispatcherServlet 静态资源 控制器类中-->
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

</web-app>

5、外部tomcat运行

  • 需要将这些jar包存入 tomcat 的 lib目录,不然会报找不到jar包的错

java controller 怎么调用controller的方法 java中的controller层_spring_09

  • 运行结果:

java controller 怎么调用controller的方法 java中的controller层_MVC_10