# SpringMVC 简介

# SpringMVC 概述

  1. SpringMVC 是一种基于 Java 实现 MVC 模型的轻量级 Web 框架
  2. 优点
    1. 使用简单,开发便捷
    2. 灵活性强

# SpringMVC 入门案例

# 导入依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.23</version>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>

# 创建 SpringMVC 控制器类

@Controller
public class UserController {
    @RequestMapping("/save")
    @ResponseBody
    public String save() {
        System.out.println("user save ...");
        return "{'module':'springmvc'}";
    }
}

# 初始化 SpringMVC 环境

@Configuration
@ComponentScan("com.baozi.controller")
public class SpringMvcConfig {
}

# 初始化 Servlet 容器,加载 SpringMVC 环境,设置 SpringMVC 技术处理的请求

public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
    @Override
    protected WebApplicationContext createServletApplicationContext() {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringMvcConfig.class);
        return ctx;
    }
    @Override
    protected String[] getServletMappings() {
        return new String[] {"/"};
    }
    @Override
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }
}

# 工作流程分析

# 启动服务器初始化过程

  1. 服务器启动,执行 ServletContainerInitConfig 类,初始化 Web 容器
  2. 执行 createServletApplicationContext 方法,创建 WebApplicationContext 对象
  3. 加载 SpringMvcConfig
  4. 执行 @ComponentScan 加载对应的 bean
  5. 加载 UserController,每个 @RequestMapping 的名称对应一个具体的方法
  6. 执行 getServletMapping 方法,定义所有的请求都通过 SpringMVC

# 单次请求过程

  1. 发送请求 localhost/save
  2. web 容器发现所有请求都经过 SpringMVC,将请求交给 SpringMVC 处理
  3. 解析请求路径 /save
  4. 由 /save 匹配执行对应的方法 save ()
  5. 执行 save ()
  6. 检测到有 @ResponseBody 直接将 save () 方法的返回值作为响应体返回请求方

# bean 加载控制

# Controller 加载控制与业务 bean 加载控制

  1. SpringMVC 控制的 bean(表现层 bean)
  2. Spring 控制的 bean
    1. 业务 bean(Service)
    2. 功能 bean(DataSource 等)
  3. SpringMVC 相关 bean 加载控制
    1. SpringMVC 加载的 bean 对应的包均在 com.baozi.controller 包内
  4. Spring 相关 bean 加载控制
    1. 方式一:Spring 加载的 bean 设定扫描范围为 com.baozi,排除调 controller 包内的 bean
    2. 方式二:Spring 记载的 bean 设定扫描为精准范围,例如 service 包,dao 包等

# 代码实现

@Configuration
@ComponentScan(value = "com.baozi",excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Controller.class))
public class SpringConfig {
}
  1. 名称: @ConponentScan
  2. 类型:类注解
  3. 属性:
    1. excludeFilters :排除扫描路径中加载的 bean,需要指定类别(type)与具体项(classes)
    2. includeFilters :加载指定的 bean,需要指定类别(type)与具体项(classes)

# 简化开发

public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    protected Class<?>[] getServletConfigClasses {
        return new Class[]{SpringMvcConfig.class};
    }
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }
}

# 请求与响应

# 请求的映射路径

@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/save")
    @ResponseBody
    public String save() {
        System.out.println("user save ...");
        return "{'module':'user save'}"
    }
}
  1. 名称: @RequestMapping
  2. 类型:方法注解,类注解
  3. 位置:SpringMVC 控制器方法定义上方
  4. 作用:设置当前控制器方法请求访问路径,如果设置在类上统一设置当前控制器方法请求访问路径前缀
  5. 属性:
    1. value(默认):请求访问路径,或访问路径前缀

# 请求方式

# Get 请求

普通参数:url 地址传参,地址参数名与形参变量名相同,定义形参即可接受参数

image-20230328215729381

@RequestMapping("/commonParam")
@RessponseBody
public String commonParam(String name, int age) {
    System.out.println(name + age);
    return "Get参数获取成功";
}

# Post 请求

普通参数:form 表单 post 请求传参,表单参数名与形参变量名相同,定义形参即可接受参数

image-20230328220003508

@RequestMapping("/commonParam")
@ResponseBody
public String commonParam(String name ,int age) {
    System.out.println(name + age);
    return "Post请求参数获取成功";
}

# Post 请求中文乱码处理

为 web 容器添加过滤器并指定字符集,Spring-web 包中提供了专用的字符过滤器

public class ServletContainerInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("utf-8");
        return new Filter[]{filter};
    }
}

# @RequestBody@RequestParam 区别

  1. 区别:
    1. @RequestParam 用于接受 url 地址传参,表单传参
    2. @RequestBody 用于接受 json 数据
  2. 应用:
    1. 后期开发中,发送 json 格式数据为主
    2. 如果发送非 json 格式数据,选用 @RequestParam 接受请求参数

# 响应

# 响应页面

@RequestMapping("/toPage")
public String toPage() {
    return "page.jsp";
}

# 响应文本数据

@RequestMapping("/toText")
@ResponseBody
public String toText() {
    return "response text";
}

# 响应 json 数据

@RequestMapping("/toJsonPOJO")
@ResponseBody
public String toPOJO() {
    User user = new User();
    user.setName("baozi");
    user.setAge(10);
    return user;
}

# REST 风格

# REST 简介

REST(Representational State Transfer),表现形式状态转换

访问路径 简介以及请求方式
http://localhost/users 查询全部用户信息 GET(查询)
http://localhost/users/1 查询指定用户信息 GET(查询)
http://localhost/users 添加用户信息 POST(新增 / 保存)
http://localhost/users 修改用户信息 PUT(修改 / 更新)
http://localhost/users/1 删除用户信息 DELETE

# 代码开发

@RequestMapping(value = "/users", method = RequestMethod.POST)
@ResponsetBody
public String save(@RequestBodu User user) {
    System.out.println("user save..." + user);
    return "RESTful POST";
}

# @RequestBody & @RequestParam & @PathVariable

名称 区别 应用
@RequestBody 用于接受 json 数据 后期开发中,发送请求以 json 为主,应用广泛
@RequestParam 用于接受 url 地址传参或者表单传参 如果采用非 json 格式数据,选用此注解传递参数
@PathVariable 用于接受路径参数 用来接收请求路径变量,通常用于传递 id 值

# 拦截器

# 拦截器概念

  1. 拦截器(Interceptor)是一种动态拦截方法调用的机制,在 SpringMVC 中动态拦截控制器方法的执行
  2. 作用:
    1. 在指定的方法调用前后执行预先设定的代码
    2. 阻止原始方法的执行

# 拦截器与过滤器区别

  1. 归属不同:Filter 属于 Servlet 技术,Interceptor 属于 SpringMVC 技术
  2. 拦截内容不同:Filter 对所有访问进行增强,Interceptor 仅针对 SpringMVC 的访问进行增强

# 定义拦截器

# 声明实现拦截器的 bean

@Component
// 定义拦截器类,实现 HandlerInterceptor 接口
// 注意当前类必须受 Spring 容器控制
public class ProjectInterceptor implements HandlerInterceptor {
    @Override
    // 原始方法调用前执行的内容
    // 返回值类型可以拦截控制的执行,true 放行,false 终止
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String contentType = request.getHeader("Content-Type");
        HandlerMethod hm = (HandlerMethod)handler;
        System.out.println("preHandle..."+contentType);
        return true;
    }
    @Override
    // 原始方法调用后执行的内容
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle...");
    }
    @Override
    // 原始方法调用完成后执行的内容
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion...");
    }
}

# 定义配置类,集成 WebMvcConfigurationSupport,实现 addInterceptor 方法

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    @Autowired
    private ProjectInterceptor projectInterceptor;
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        // 配置拦截器
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
    }
}

# 简化开发

@Configuration
@ComponentScan({"com.itheima.controller"})
@EnableWebMvc
// 实现 WebMvcConfigurer 接口可以简化开发,但具有一定的侵入性
public class SpringMvcConfig implements WebMvcConfigurer {
    @Autowired
    private ProjectInterceptor projectInterceptor;
    @Autowired
    private ProjectInterceptor2 projectInterceptor2;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 配置多拦截器
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
        registry.addInterceptor(projectInterceptor2).addPathPatterns("/books","/books/*");
    }
}

# 执行流程

# 无拦截器

image-20230330210812664

# 有拦截器

image-20230330210831126

# 拦截器参数

# 前置处理

  1. 参数:
    1. request :请求对象
    2. response :响应对象
    3. handler :被调用的处理器对象,本质上是一个方法对象,对反射技术的 Method 对象进行了再包装
  2. 返回值:返回值为 false,被拦截的处理器将不执行

# 完成后处理

  1. 参数:
    1. exception :如果处理器执行过程中出现异常对象,可以针对异常情况进行单独处理

# 多拦截器执行流程

image-20230330211845101

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

Baozi 微信支付

微信支付

Baozi 支付宝

支付宝

Baozi 微信

微信