一文让你轻松拿捏 Spring MVC

这篇具有很好参考价值的文章主要介绍了一文让你轻松拿捏 Spring MVC。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

博主介绍: ✌博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家✌

Java知识图谱点击链接:体系化学习Java(Java面试专题)
💕💕 感兴趣的同学可以收藏关注下不然下次找不到哟💕💕

一文让你轻松拿捏 Spring MVC

1、什么是 MVC

MVC是一种软件架构模式,它将应用程序分为三个主要组成部分:模型(Model)、视图(View)和控制器(Controller)。MVC模式的目的是将应用程序的业务逻辑与用户界面分离,以便更好地管理和维护应用程序。

模型(Model):模型是应用程序的核心组件,它包含应用程序的数据和业务逻辑。模型通常包括数据访问、数据验证和数据处理等方面的逻辑。

视图(View):视图是应用程序的用户界面,它负责显示数据和与用户交互。视图通常包括用户界面的设计、布局和样式等方面的逻辑。

控制器(Controller):控制器是应用程序的逻辑处理部分,它负责协调模型和视图之间的交互。控制器通常包括用户输入的处理、业务逻辑的处理和视图的更新等方面的逻辑。

MVC模式的好处是它可以使应用程序更易于管理和维护,因为它将应用程序分为不同的组件,使每个组件都可以独立地进行开发和测试。此外,MVC模式还可以提高应用程序的可扩展性和可重用性,因为它可以使应用程序的各个组件更加松散耦合。

一文让你轻松拿捏 Spring MVC

2、什么是 Spring MVC

Spring MVC是一种基于MVC模式的Web框架,它是Spring Framework的一部分。它提供了一种简单的方式来开发Web应用程序,并且可以轻松地与其他Spring组件集成。Spring MVC框架的核心是一个前端控制器(Front Controller)Servlet,它负责将请求分派到适当的控制器(Controller)和视图(View)。

Spring MVC框架的核心组件包括以下内容:

  1. 前端控制器(Front Controller)Servlet:它是Spring MVC框架的核心,负责将请求分派到适当的控制器(Controller)和视图(View)。

  2. 控制器(Controller):它处理来自前端控制器的请求,并将请求转发给适当的服务层组件进行处理。控制器通常是一个Java类,它可以使用注解或XML配置进行配置。

  3. 视图(View):它负责呈现模型数据,并将其显示给用户。视图通常是一个JSP页面或HTML模板,它可以使用表达式语言(EL)或模板引擎进行渲染。

  4. 模型(Model):它是应用程序的业务逻辑和数据访问层。模型通常是一个Java类,它可以使用Spring的数据访问组件进行访问。

Spring MVC框架的好处是它可以帮助开发人员快速地构建Web应用程序,并且可以轻松地与其他Spring组件集成。此外,Spring MVC框架还提供了一些有用的功能,如表单处理、数据绑定、校验和国际化等。

3、Spring MVC 的请求流程

一文让你轻松拿捏 Spring MVC
Spring MVC的请求流程如下:

  1. 客户端向服务器发送请求,请求被DispatcherServlet接收。

  2. DispatcherServlet根据请求的URL和HandlerMapping找到对应的处理器(Handler)。

  3. 处理器执行业务逻辑,并将处理结果封装成一个ModelAndView对象。

  4. 处理器将ModelAndView对象返回给DispatcherServlet。

  5. DispatcherServlet根据ViewResolver找到对应的视图(View)。

  6. 视图将ModelAndView中的模型数据渲染成HTML或其他格式的响应。

  7. 响应被发送回客户端,请求结束。

在请求流程中,HandlerMapping和ViewResolver是两个重要的组件。HandlerMapping负责将请求映射到具体的处理器(Handler),而ViewResolver负责将逻辑视图名称解析为具体的视图实现。这两个组件都可以根据需要进行自定义配置。

4、Spring MVC 的五大组件

Spring MVC的五大组件包括:

  1. 前端控制器(DispatcherServlet):它是Spring MVC框架的核心,负责将请求分发到不同的处理器(Handler)和视图(View)进行处理。

  2. 处理器映射(HandlerMapping):它负责将请求映射到具体的处理器(Handler),根据不同的映射规则,可以将请求映射到不同的处理器。

  3. 处理器适配器(HandlerAdapter):它负责将不同类型的处理器适配成统一的处理器接口,以便DispatcherServlet可以调用它们。

  4. 视图解析器(ViewResolver):它负责将逻辑视图名称解析为具体的视图实现,根据不同的解析规则,可以将逻辑视图名称解析为不同的视图实现。

  5. 视图(View):它负责将模型数据渲染成HTML或其他格式的响应,根据不同的视图实现,可以将模型数据渲染成不同的响应格式。

4.1、前端控制器(DispatcherServlet)

DispatcherServlet的工作原理可以通过以下代码说明:

public class DispatcherServlet extends HttpServlet {
    
    // 处理器映射器
    private List<HandlerMapping> handlerMappings;
    
    // 处理器适配器
    private List<HandlerAdapter> handlerAdapters;
    
    // 视图解析器
    private List<ViewResolver> viewResolvers;
    
    // 初始化方法
    @Override
    public void init(ServletConfig config) throws ServletException {
        // 初始化处理器映射器
        handlerMappings = new ArrayList<>();
        handlerMappings.add(new BeanNameUrlHandlerMapping());
         // 初始化处理器适配器
        handlerAdapters = new ArrayList<>();
        handlerAdapters.add(new HttpRequestHandlerAdapter());
         // 初始化视图解析器
        viewResolvers = new ArrayList<>();
        viewResolvers.add(new InternalResourceViewResolver());
    }
    
    // 处理请求方法
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 根据请求URL和处理器映射器找到对应的处理器
        Object handler = getHandler(request);
        if (handler == null) {
            // 如果找不到处理器,则返回404错误
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
            return;
        }
        // 根据处理器和处理器适配器执行业务逻辑
        HandlerAdapter handlerAdapter = getHandlerAdapter(handler);
        ModelAndView modelAndView = handlerAdapter.handle(request, response, handler);
        // 根据ModelAndView和视图解析器找到对应的视图
        View view = getView(modelAndView);
        if (view == null) {
            // 如果找不到视图,则返回500错误
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            return;
        }
        // 渲染视图,生成响应
        view.render(modelAndView.getModel(), request, response);
    }
    
    // 根据请求URL和处理器映射器找到对应的处理器
    private Object getHandler(HttpServletRequest request) {
        for (HandlerMapping handlerMapping : handlerMappings) {
            Object handler = handlerMapping.getHandler(request);
            if (handler != null) {
                return handler;
            }
        }
        return null;
    }
    
    // 根据处理器和处理器适配器执行业务逻辑
    private HandlerAdapter getHandlerAdapter(Object handler) {
        for (HandlerAdapter handlerAdapter : handlerAdapters) {
            if (handlerAdapter.supports(handler)) {
                return handlerAdapter;
            }
        }
        return null;
    }
    
    // 根据ModelAndView和视图解析器找到对应的视图
    private View getView(ModelAndView modelAndView) {
        String viewName = modelAndView.getViewName();
        for (ViewResolver viewResolver : viewResolvers) {
            View view = viewResolver.resolveViewName(viewName);
            if (view != null) {
                return view;
            }
        }
        return null;
    }
}

在上面的代码中,DispatcherServlet继承自HttpServlet,它是一个Servlet,负责处理HTTP请求。在初始化方法中,DispatcherServlet初始化了处理器映射器、处理器适配器和视图解析器等组件。在处理请求方法中,DispatcherServlet根据请求URL和处理器映射器找到对应的处理器,然后根据处理器和处理器适配器执行业务逻辑,最后根据ModelAndView和视图解析器找到对应的视图,渲染视图,生成响应。

4.2、处理器映射(HandlerMapping)

HandlerMapping的工作原理可以通过以下代码说明:

public interface HandlerMapping {
    Object getHandler(HttpServletRequest request);
}

public class BeanNameUrlHandlerMapping implements HandlerMapping {
   
    private Map<String, Object> handlerMap = new HashMap<>();
   
    public void registerHandler(String url, Object handler) {
        handlerMap.put(url, handler);
    }
    
    @Override
    public Object getHandler(HttpServletRequest request) {
        String url = request.getRequestURI();
        Object handler = handlerMap.get(url);
        return handler;
    }
}

在上面的代码中,HandlerMapping是一个接口,定义了获取处理器的方法。BeanNameUrlHandlerMapping是HandlerMapping的一个实现类,它通过URL和处理器的映射关系来获取处理器。

BeanNameUrlHandlerMapping维护了一个handlerMap,用于存储URL和处理器的映射关系。通过registerHandler方法,可以将一个URL和对应的处理器注册到handlerMap中。

在getHandler方法中,BeanNameUrlHandlerMapping首先通过HttpServletRequest获取请求的URL。然后从handlerMap中根据URL获取对应的处理器。如果找不到对应的处理器,则返回null。

通过这样的方式,BeanNameUrlHandlerMapping实现了根据URL获取处理器的功能。其他的HandlerMapping实现类可能会使用不同的方式来获取处理器,但都需要实现HandlerMapping接口中的getHandler方法。

4.3、 处理器适配器(HandlerAdapter)

处理器适配器(HandlerAdapter)是一个桥梁,用于将处理器(Handler)适配到处理器映射(HandlerMapping)机制中。不同类型的处理器需要不同的适配器来适配到处理器映射机制中。

以下是一个示例代码,用于说明处理器适配器的工作原理:

public interface HandlerAdapter {
    boolean supports(Object handler);
    ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;
}

public class SimpleControllerHandlerAdapter implements HandlerAdapter {
    
    @Override
    public boolean supports(Object handler) {
        return handler instanceof SimpleController;
    }
    
    @Override
    public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        SimpleController controller = (SimpleController) handler;
        return controller.handleRequest(request, response);
    }
}

在上面的代码中,HandlerAdapter是一个接口,定义了两个方法:supports和handle。supports方法用于判断一个处理器是否支持当前的适配器。handle方法用于执行处理器的业务逻辑,并返回ModelAndView对象。

SimpleControllerHandlerAdapter是HandlerAdapter的一个实现类,用于适配SimpleController类型的处理器。在supports方法中,SimpleControllerHandlerAdapter判断传入的处理器是否是SimpleController类型的实例。如果是,则返回true,表示当前适配器可以处理该类型的处理器。如果不是,则返回false,表示当前适配器无法处理该类型的处理器。

在handle方法中,SimpleControllerHandlerAdapter将传入的处理器强制转换为SimpleController类型,并调用其handleRequest方法来执行业务逻辑。handleRequest方法返回一个ModelAndView对象,SimpleControllerHandlerAdapter将其返回给调用者。

通过这样的方式,SimpleControllerHandlerAdapter实现了将SimpleController类型的处理器适配到处理器映射机制中的功能。其他类型的处理器适配器也可以通过实现HandlerAdapter接口来实现适配器的功能。

4.4、 视图解析器(ViewResolver)

视图解析器(ViewResolver)是将逻辑视图名(如"home")解析为实际视图(如"/WEB-INF/views/home.html")的机制。以下是一个示例代码,用于说明视图解析器的工作原理:

public interface ViewResolver {
    View resolveViewName(String viewName, Locale locale) throws Exception;
}

public class InternalResourceViewResolver implements ViewResolver {
    
    private String prefix = "/WEB-INF/views/";
    
    private String suffix = ".html";
   
    @Override
    public View resolveViewName(String viewName, Locale locale) throws Exception {
        String viewPath = prefix + viewName + suffix;
        InternalResourceView view = new InternalResourceView(viewPath);
        return view;
    }
}

在上面的代码中,ViewResolver是一个接口,定义了一个方法resolveViewName,用于将逻辑视图名解析为实际视图。

InternalResourceViewResolver是ViewResolver的一个实现类,用于将逻辑视图名解析为HTML视图。在InternalResourceViewResolver中,我们定义了prefix和suffix两个属性,用于指定HTML视图的路径前缀和后缀。在resolveViewName方法中,我们将逻辑视图名和前缀、后缀拼接起来,得到实际的HTML视图路径。然后创建一个InternalResourceView对象,将实际视图路径作为参数传入。最后返回这个InternalResourceView对象。

通过这样的方式,InternalResourceViewResolver实现了将逻辑视图名解析为HTML视图的功能。其他类型的视图解析器也可以通过实现ViewResolver接口来实现解析器的功能。

4.5、视图(View)

视图(View)是用户界面的一部分,用于呈现模型数据。以下是一个示例代码,用于说明视图的工作原理:

public interface View {
    void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception;
}

public class HtmlView implements View {
    
    private String viewName;
    
    public HtmlView (String viewName) {
        this.viewName = viewName;
    }
    
    @Override
    public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
        request.setAttribute("model", model);
        request.getRequestDispatcher(viewName).forward(request, response);
    }
}

在上面的代码中,View是一个接口,定义了一个方法render,用于呈现模型数据。HtmlView是View的一个实现类,用于呈现JSP视图。在HtmlView中,我们定义了一个viewName属性,表示HTML视图的名称。在render方法中,我们将模型数据和request对象绑定,然后调用request.getRequestDispatcher方法获取HTML视图的请求转发器,最后将request和response对象传递给请求转发器的forward方法,将HTML视图呈现给用户。

通过这样的方式,HtmlView实现了将模型数据呈现为HTML视图的功能。其他类型的视图也可以通过实现View接口来实现视图的功能。

5、Spring MVC 的代码案例

以下是一个简单的Spring MVC代码案例,用于展示如何创建一个简单的控制器和视图,并将它们组合在一起来实现一个完整的Web应用程序。

首先,我们需要创建一个控制器类,用于处理来自客户端的HTTP请求。在这个示例中,我们将创建一个名为HelloController的控制器,它将处理来自客户端的"/hello"请求,并返回一个简单的问候语。

package com.pany.camp.spring;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 *
 * @description:  hello
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-12 21:55 
 */
@Controller
public class HelloController {

    @RequestMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("message", "Hello, World!");
        return "hello";
    }
}

在上面的代码中,我们使用@Controller注解将HelloController类标记为Spring MVC控制器。我们还使用@RequestMapping注解将"/hello"请求映射到hello()方法。在hello()方法中,我们使用Model对象将一个名为"message"的属性添加到模型中,并将视图名称"hello"返回。

接下来,我们需要创建一个视图来呈现模型数据。在这个示例中,我们将创建一个名为hello.html的HTML视图,它将显示一个简单的问候语。


<!DOCTYPE html>
<html>
<head>
    <title>Hello</title>
</head>
<body>
    <h1 th:text="${message}"></h1>
</body>
</html>

在上面的代码中,我们使用Thymeleaf模板引擎的th:text属性将模型中的"message"属性绑定到页面上的 h1元素。

最后,我们需要配置Spring MVC框架以使用我们的控制器和视图。在这个示例中,我们将使用Java配置来配置Spring MVC。

package com.pany.camp.spring;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;


/**
 *
 * @description:  MVC Config
 * @copyright: @Copyright (c) 2022 
 * @company: Aiocloud
 * @author: pany
 * @version: 1.0.0 
 * @createTime: 2023-06-12 21:55 
 */
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.pany.camp.spring")
public class AppConfig implements WebMvcConfigurer {
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("classpath:templates/");
        resolver.setSuffix(".html");
        return resolver;
    }
}

在上面的代码中,我们使用@Configuration注解将AppConfig类标记为Spring配置类。我们还使用@EnableWebMvc注解启用Spring MVC框架,并使用@ComponentScan注解扫描我们的控制器类。在viewResolver()方法中,我们创建了一个InternalResourceViewResolver对象,并将视图的前缀设置为"/WEB-INF/views/“,将后缀设置为”.html",以便Spring MVC可以将逻辑视图名解析为HTML视图。

现在我们已经创建了控制器、视图和配置类,我们可以将它们组合在一起来创建一个完整的Web应用程序。我们可以使用Spring Boot框架来快速创建一个可执行的Web应用程序。

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

在上面的代码中,我们使用@SpringBootApplication注解将Application类标记为Spring Boot应用程序,并在main()方法中使用SpringApplication.run()方法启动应用程序。

一文让你轻松拿捏 Spring MVC

参考我的静态文件的目录结构,因为我这边设置了 context-path: /console-service,端口设置的是port: 19096,所以在浏览器中访问 http://localhost:19096/console-service/hello,应该会看到一个包含"Hello,World!"的标题的页面。

一文让你轻松拿捏 Spring MVC

一文让你轻松拿捏 Spring MVC

💕💕 本文由激流原创,首发于CSDN博客,博客主页 https://blog.csdn.net/qq_37967783?spm=1010.2135.3001.5421
💕💕喜欢的话记得点赞收藏啊文章来源地址https://www.toymoban.com/news/detail-480519.html

到了这里,关于一文让你轻松拿捏 Spring MVC的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Java 高阶】一文精通 Spring MVC - 基础概念(一)

    👉 博主介绍 : 博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家,WEB架构师,阿里云专家博主,华为云云享专家,51CTO 专家博主 ⛪️ 个人社区:个人社区 💞 个人主页:个人主页 🙉 专栏地址: ✅ Java 高阶 🙉八股文专题:剑指大厂,手撕

    2024年02月11日
    浏览(43)
  • 【Java 高阶】一文精通 Spring MVC - 转发重定向(四)

    👉 博主介绍 : 博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家,WEB架构师,阿里云专家博主,华为云云享专家,51CTO 专家博主 ⛪️ 个人社区:个人社区 💞 个人主页:个人主页 🙉 专栏地址: ✅ Java 高阶 🙉八股文专题:剑指大厂,手撕

    2024年02月11日
    浏览(46)
  • spring的单元测试那些事,一文让你了解透

    目录 一、什么是单元测试 二、如何进行单元测试 三、为什么要进行单元测试   Spring单元测试是指使用Spring框架提供的测试工具,对Spring应用程序中的单个单元进行测试的过程。它旨在验证应用程序中的各个组件是否按预期工作,并确保它们能够正确地集成和交互。 Spring单

    2024年02月04日
    浏览(39)
  • Spring Boot进阶(51):如何在Spring Boot项目中轻松集成HTML:让你的应用更具吸引力!

            我们都知道,Spring Boot作为一款广泛应用于企业级的开发框架,其通过简化开发过程、提高开发效率赢得了众多开发者的青睐。在实际项目开发中,集成 HTML作为 Web 应用程序中的一个基本需求,也是现在极其常见的场景之一。在此,我将为大家分享一下Spring Boot如何

    2024年02月11日
    浏览(47)
  • Spring Boot进阶(58):轻松搞定数据存储!Spring Boot与PostgreSQL完美集成,让你的应用更稳定更高效!

            PostgreSQL是一种广泛使用的开源关系型数据库,具有可靠性高、性能优异、拥有丰富的数据类型和扩展等优点,越来越多的企业和开发者开始使用它来存储和管理数据。而Spring Boot是一种快速开发的框架,可以简化开发过程并提高开发效率。本文将介绍如何使用Sp

    2024年02月10日
    浏览(54)
  • 【Spring底层原理高级进阶】轻松掌握 Spring MVC 的拦截器机制:深入理解 HandlerInterceptor 接口和其实现类的用法

     🎉🎉欢迎光临🎉🎉 🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀 🌟特别推荐给大家我的最新专栏 《Spring 狂野之旅:底层原理高级进阶》 🚀 本专栏纯属为爱发电永久免费!!! 这是苏泽的个人主页可以看到我其他的内容哦👇👇 努力的苏泽 http://suze

    2024年02月20日
    浏览(52)
  • ChatGPT微信开发,轻松拿捏

    在人工智能领域, Ai 已经是一个屡见不鲜的东西了,为什么这次 openAi 推出的 chatGPT 却异常的受人欢迎?其实这还得益于 GPT 模型。 那么什么是 GPT 模型?我们可以看一下 chatGPT 自己的回答: GPT(Generative Pre-trained Transformer) 是一种基于变换器的语言模型,用于自然语言处理

    2024年02月08日
    浏览(37)
  • Apifox:详细使用教程,带你轻松拿捏

    目录 Apifox简介 Apifox的安装与使用 Apifox新建项目的流程 编写接口文档 我们在日常编程开发过程中经常实行的是前后端分离架构的模式,一个项目的落地会通过产品、开发、测试三方会审,对项目需求评审过后,前后端开发会制定一些接口,他们通常会用以下方式: 开发指定

    2024年02月03日
    浏览(62)
  • iPad怎么分屏?学会这个方法,轻松拿捏

    ​很多小伙伴都喜欢使用iPad来学习、娱乐和工作。在使用iPad的时候,有时候需要同时处理两个事情,这种时候,就需要借助分屏功能了。iPad怎么分屏?别着急,学会这个方法,轻松拿捏!   今天小编就具体的来讲一下iPad怎么分屏,还不会使用iPad分屏的小伙伴一起来看看哦

    2024年02月15日
    浏览(35)
  • 【数据结构】带你轻松拿捏顺序表(内附源码)

    君兮_的个人主页 勤时当勉励 岁月不待人 C/C++ 游戏开发 Hello,米娜桑们,这里是君兮_,今天正式开始开新坑啦!在接下来的这一个月来我会逐步带大家了解初阶数据结构的知识,如果是你主修的是计算机专业数据结构的重要性不言而喻,哪怕在以后你工作面试时,它也是面试

    2024年02月15日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包