SpringMVC简介

SpringMVC简介

一、总述

二、快速入门

2.1概述

下面直接动手吧:

2.2实现

1、导入坐标:

java 复制代码
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.7</version>
        </dependency>

注意改为war包

java 复制代码
<groupId>com.itheima</groupId>
    <artifactId>spring_webmvc_test02</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

2、在web.xml配置前端控制器

这里直接所有一起配了,注释里面有详细解释了,就不再过多赘述了。

java 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

<!--配置前端控制器-->
<servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--    设置启动时加载-->
    <load-on-startup>2</load-on-startup>
</servlet>
<!--    配置前端控制器的映射,让前端找得到-->
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

3、配置Controlle控制器

同时使用注解交由SpringMVC容器进行管理

java 复制代码
package com.itheima.controller;

import com.itheima.service.QuickService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

//定义成为Bean
@Controller
public class QuickController2 {
    //这是映射地址
    @RequestMapping("/quick")
    public void quick(){
        System.out.println("quick is running");
    }
}

既然是使用注解交由SpringMVC容器进行管理,那么就必定要在SpringMVC的配置文件配置注解扫描了:

java 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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
">
<!--    配置组件扫描扫描到我们的控制器-->
    <context:component-scan base-package="com.itheima.controller"></context:component-scan>


</beans>

那么如何让web.xm与SpringMVC的配置文件连接起来呢,当然还要进行配置一下,最后是这样的:

java 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">

<!--配置前端控制器-->
<servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--    配置一下我们Spring配置文件的路径-->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-mvc2.xml</param-value>
    </init-param>
<!--    设置启动时加载-->
    <load-on-startup>2</load-on-startup>
</servlet>
<!--    配置前端控制器的映射-->
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

测试一下访问QuickController2的quick方法:

控制台成功打印,没有问题。

但是我们可以看到前端报的是500的错误:

这是因为Controller是控制器,本来应该返回的是视图名称,但是什么返回的是空,所以报的是500,现在我们来返回一个视图试一下:

java 复制代码
package com.itheima.controller;

import com.itheima.service.QuickService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

//定义成为Bean
@Controller
public class QuickController2 {
    //这是映射地址
    @RequestMapping("/quick")
    public String quick()
    {
        System.out.println("quick is running");
        return "/index.jsp";
    }
}

这是要返回的jsp视图:

java 复制代码
<%--
  Created by IntelliJ IDEA.
  User: haohao
  Date: 2022/12/1
  Time: 16:04
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>Hello SpringMVC!</h1>
</body>
</html>

结论得证。

三、在SpringMVC中注入Spring中配置的Bean

先进行Spring的Bean的配置,这里为了测试使用简单的Bean:

java 复制代码
package com.itheima.service;

public interface QuickService {
}
java 复制代码
package com.itheima.service.impl;

import com.itheima.service.QuickService;
import org.springframework.stereotype.Service;

@Service
public class QuickServiceImpl implements QuickService {
}

在Spring的配置文件中配置组件扫描:

java 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">

    <!--组件扫描-->
    <context:component-scan base-package="com.itheima.service"/>

</beans>

在web.xml中配置监听器且加载Spring的配置文件:

java 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
<!--配置监听器-->
<!--    配置参数-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
<!--配置前端控制器-->
<servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--    配置一下我们Spring配置文件的路径-->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-mvc2.xml</param-value>
    </init-param>
<!--    设置启动时加载-->
    <load-on-startup>2</load-on-startup>
</servlet>
<!--    配置前端控制器的映射-->
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

在Controller中注入Spring中配置的Bean:

java 复制代码
package com.itheima.controller;

import com.itheima.service.QuickService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

//定义成为Bean
@Controller
public class QuickController2 {
//    注入配置好的Service
//    @Autowired
//    private QuickService quickService;
    //这是映射地址
    @RequestMapping("/quick")
    public String quick()
    {
        System.out.println("quick is running");
        return "/index.jsp";
    }
}

四、SpringMVC加载组件的策略


其实际上这些HandlerMapping、HandlerAdapter、ViewResolver存在于org\springframework\spring-webmvc\5.3.7\spring-webmvc-5.3.7.jar!\org\springframework\web\servlet\DispatcherServlet.properties的文件中:

java 复制代码
# Default implementation classes for DispatcherServlet's strategy interfaces.
# Used as fallback when no matching beans are found in the DispatcherServlet context.
# Not meant to be customized by application developers.

org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver

org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver

org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping,\
	org.springframework.web.servlet.function.support.RouterFunctionMapping

org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
	org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter,\
	org.springframework.web.servlet.function.support.HandlerFunctionAdapter


org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\
	org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
	org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver

org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

这里面有那么对应的实现,而这些实现会在DispatcherServlet前端控制器进行加载,里面哪些List就是有来存对应的实现的:

java 复制代码
@Nullable
    private MultipartResolver multipartResolver;
    @Nullable
    private LocaleResolver localeResolver;
    @Nullable
    private ThemeResolver themeResolver;
    @Nullable
    private List<HandlerMapping> handlerMappings;
    @Nullable
    private List<HandlerAdapter> handlerAdapters;
    @Nullable
    private List<HandlerExceptionResolver> handlerExceptionResolvers;
    @Nullable
    private RequestToViewNameTranslator viewNameTranslator;
    @Nullable
    private FlashMapManager flashMapManager;
    @Nullable
    private List<ViewResolver> viewResolvers;

且只有自己的Spring和SpringMVC容器里面没有配置相应的Bean前端控制器才会加载对应类型默认的实现:

java 复制代码
private void initHandlerMappings(ApplicationContext context) {
        this.handlerMappings = null;
        if (this.detectAllHandlerMappings) {
            Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
            if (!matchingBeans.isEmpty()) {
                this.handlerMappings = new ArrayList(matchingBeans.values());
                AnnotationAwareOrderComparator.sort(this.handlerMappings);
            }
        } else {
            try {
                HandlerMapping hm = (HandlerMapping)context.getBean("handlerMapping", HandlerMapping.class);
                this.handlerMappings = Collections.singletonList(hm);
            } catch (NoSuchBeanDefinitionException var4) {
            }
        }

        if (this.handlerMappings == null) {
            this.handlerMappings = this.<HandlerMapping>getDefaultStrategies(context, HandlerMapping.class);
            if (this.logger.isTraceEnabled()) {
                this.logger.trace("No HandlerMappings declared for servlet '" + this.getServletName() + "': using default strategies from DispatcherServlet.properties");
            }
        }

        for(HandlerMapping mapping : this.handlerMappings) {
            if (mapping.usesPathPatterns()) {
                this.parseRequestPath = true;
                break;
            }
        }

    }


最终都放到对应的List当中了。

当我们在SpringMVC容器中配置了一个自己的HandlerMapping,那么前端控制器DispatcherServlet就不会再加载它默认的四个实现了,以为此时的matchingBeans不再等于空了,但是只是HandlerMapping不再加载默认的,如果HandlerAdapter等其他类型的没有自己配置的话,它依然还会加载。

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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
">
<!--    配置组件扫描扫描到我们的控制器-->
    <context:component-scan base-package="com.itheima.controller"></context:component-scan>
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>
</beans>
相关推荐
雪碧聊技术4 小时前
深入理解 Java GC:从“房间清洁工”到解决系统卡顿实战
java·开发语言
大鹏说大话4 小时前
Java并发编程核心:线程安全、synchronized与volatile的深度剖析
java·开发语言
迷藏4944 小时前
# 发散创新:低代码开发新范式——用可视化逻辑构建企业级业务系统 在当今快速迭代的软件工程实践
java·python·低代码
JAVA+C语言4 小时前
Java IO 流
java·开发语言
山川行4 小时前
Python快速闯关8:内置函数
java·开发语言·前端·笔记·python·学习·visual studio
Java基基4 小时前
sdkman 一键切换 JDK 版本管理工具
java·开发语言·sdkman
美好的事情能不能发生在我身上4 小时前
Jmeter压测遇到的问题
java·分布式·jmeter
云烟成雨TD4 小时前
Spring AI 1.x 系列【14】三月双版本连发!Spring AI 最新功能全掌握
java·人工智能·spring
XiYang-DING4 小时前
【Java SE】var关键字
java·开发语言
AskHarries5 小时前
openclaw升级和参数调整
后端·ai编程