SpringMVC

SpringMVC

Spring Web MVC 是基于servlet API构建的原始Web框架,本身被SpringFramework包含其中

  • DispatcherServlet
    • Servlet核心,用来接收request和返回response
  • HandlerMapping
    • 缓存handler方法和地址
    • 在普通的MVC中,我们通过模糊WebServlet注解的方式通过业务+方法名来调用业务接口
  • HandlerAdapter
    • 简化参数处理,原始的参数转成handler需要的参数
    • 简化数据响应,将handler返回的数据封装到response中x
  • ViewResovler(视图解析器)
    • 简化URL的前缀和后缀,直接使用页面名字就能查找,方便查找

依赖导入

  • SpringIoC
  • SpringMVC
  • Servlet
<dependencies>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/jakarta.servlet/jakarta.servlet-api -->
    <dependency>
        <groupId>jakarta.servlet</groupId>
        <artifactId>jakarta.servlet-api</artifactId>
        <version>${servlet.version}</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

WebApplicationInitializer接口(祖宗)

此接口由org.springframework.web提供,当web项目启动时,自动执行onStartup的方法

public void onStartup(ServletContext servletContext) throws ServletException {}

我们最后使用的是具体实现类AbstractAnnotationConfigDispatcherServletInitializer,有着层层实现的关系

AbstractContextLoaderInitializer

这个类直接实现了WebApplicationInitializer接口,并且创建了一个重要的方法:createRootApplicationContext

AbstractDispatcherServletInitializer

这个类继承了AbstractContextLoaderInitializer类,并且创建了另一个重要的方法:createServletApplicationContext

还有一个重要的方法:getServletMappings

AbstractAnnotationConfigDispatcherServletInitializer

这个类继承了AbstractDispatcherServletInitializer类,并创建了两个抽象的方法:

@Nullable
protected abstract Class<?>[] getRootConfigClasses();

@Nullable
protected abstract Class<?>[] getServletConfigClasses();

他进一步实现了createRootApplicationContext

protected WebApplicationContext createRootApplicationContext() {
    Class<?>[] configClasses = getRootConfigClasses(); // 调用上面的抽象方法,由用户来返回这个配置类
    if (!ObjectUtils.isEmpty(configClasses)) {
        // 利用配置类创建IoC对象
       AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
       context.register(configClasses);
       return context;
    }
    else {
       return null;
    }
}

还进一步实现了createServletApplicationContext

protected WebApplicationContext createServletApplicationContext() {
    // 利用配置类创建IoC对象
    AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
    Class<?>[] configClasses = getServletConfigClasses(); // 调用上面的抽象方法,由用户来返回这个配置类
    if (!ObjectUtils.isEmpty(configClasses)) {
       context.register(configClasses);
    }
    return context;
}

用户自定义初始化类

这个类就是用户自己编写的类,继承于AbstractAnnotationConfigDispatcherServletInitializer类

它的作用就是通过配置类对SpringMVC的项目进行初始化操作

真是忍不住吐槽这类名有点过于长了吧!!! 😓

重写三个重要方法:

  • getRootConfigClasses:提供配置类,其父类会对service,mapper层的IoC容器进行初始化
  • getServletConfigClasses:通过配置类对,其父类会对springMVC,controller层的IoC容器进行初始化
  • getServletMappings:配置SpringMVC内部自带的Servlet访问地址,一般配置成 “/”

这三个都是以数组的方式返回值,我们只需要提供值,其父类会用值进行相应的初始化

package com.xiaobai;

import com.xiaobai.config.MvcConfig;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class Main extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{MvcConfig.class};
    }

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }
}


@RequestMapping

RequestMapping注解可以将Controller层的业务方法加入到HandlerMapping中

其中的值是URI访问地址,和JavaWeb中的WebServlet功能类似

注:书写形式没有那么规范,把/user/login写成user/login也是可以的

在类上使用RequestMapping注解可提取前缀

@Controller
@RequestMapping("User")
public class UserController {
    // 如果括号中没有内容,则通过根访问,例如,这个index是通过/user/访问
    @RequestMapping
    public String index() {
        return "index";
    }

    @RequestMapping("login")
    public String login() {
        return null;
    }

    @RequestMapping("register")
    public String register() {
        return null;
    }
}

多个访问方式和模糊访问

使用方法基本与@WebServlet相同

// 多个注解
@RequestMapping(
        {
        "register","regist"
        }
)
public String register() {
    return null;
}

指定请求方式

默认情况下,不指定请求方式时,可以被任何请求方式访问

当不符合指定的请求方式时,会返回405,请求方式异常

// 设置login的请求方式只能为Post
@RequestMapping(value = "login",method = RequestMethod.POST)
public String login() {
    return null;
}

注解扩展

以下注解的功能相同,但扩展的注解不能使用在类上,只能使用在方法上

@RequestMapping(value = "login",method = RequestMethod.GET)
@GetMapping

@RequestMapping(value = "login",method = RequestMethod.POST)
@PostMapping

@RequestMapping(value = "login",method = RequestMethod.PUT)
@PutMapping

@RequestMapping(value = "login",method = RequestMethod.DELETE)
@DeleteMapping