SpringMVC学习笔记

Posted *^O^*—*^O^*

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringMVC学习笔记相关的知识,希望对你有一定的参考价值。

文章目录

概述和设计模式介绍

SpringMVC框架围绕 DispatcherServlet(前端控制器) 这个核心展开, DispatcherServlet 是
SpringMVC框架的总导演、总策划,它负责截获请求并将其分派给相应的处理器处理。这部分我们在学
习完 SpringMVC 的使用后再来结合整体流程回顾。
传统的基于Spring Framework的web开发需要大量的 xml 配置,在有SpringBoot以后,Web开发的效
率得到了很大的提升,几乎大部分配置可以使用默认约定的规则。

MVC(Model View Controller)是软件工程中的一种软件架构模式,它把软件系统分为模型、视图和控制器三个基本部分。
==Model(模型)==是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。
==View(视图)==是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。
==Controller(控制器)==是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。

@Controller

表示web控制器,处理web请求响应

@RequestMapping

定义在类,方法上,配置url,请求方法等。
提供的服务路径为:类和方法上的路径拼接,类上可以没有,方法上有该注解,也叫请求应映射方法
请求映射方法返回类型:前后端分离模式,是互联网公司采取的主流技术,一般返回json结合

 类上:该类中,所有请求映射方法,都是带body内容
 方法上:默认是所有请求方法都支持

@ResponseBody

定义在类和方法上,表示方法返回值作为响应体内容, 一般是返回自定义类型的对象,会序列化json字符串
 类上:该类中,所有请求映射方法,都是带body内容
 方法:建议设置返回类型为Object,返回自定义类型的值(springmvc框架自动序列化为json)

组合注解
@RestController:定义在类上,等于@Controlller+@ResponseBody注解
@GetMapping:定义在方法上,=@RequestMapping(method=RequestMethod.GET)
@PostMapping:定义在方法上,只提供post请求

控制器方法的返回

有两种使用方式:

  1. 返回 URI 资源路径的字符串,可以使用 redirect:/服务路径 表示重定向到某个路径,
    forward:/服务路径 表示转发到某个路径,如果前边不写默认就是转发。
  2. @RequestMapping结合@ResponseBody,返回的字符串会作为响应体内容。此时响应的
    Content-Type为 text/plain 普通文本。

String返回类型

返回普通的Java类型

返回ResponseEntity

package org.example.controller;

import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

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

@Controller
public class test2Controller 
	@RequestMapping("/1")
    public String t1()     //重定向
        return "redirect:/home.html";
    
  
    @RequestMapping(value = "/test2",method = RequestMethod.GET)
    public String test2()     //转发
        return "forward:/home.html";
    
    @RequestMapping("/3")
    @ResponseBody
    public String test3()
        return "好了,已经知道了";
    

    @RequestMapping("/4")
    @ResponseBody
    public Object test4()
        Map<Integer, Object> map = new HashMap<>();
        map.put(1, "张三");
        map.put(2, 23333);
        map.put(3, true);
        return map;
    

    @RequestMapping("/5")
    public Object t5()
        Map<Integer, Object> map = new HashMap<>();
        map.put(1, "乾坤");
        map.put(2, 23333);
        map.put(3, true);
        return ResponseEntity.status(200).body(map);
    

控制器方法支持的参数类型

@PathVariable

提供了restful可变风格,路径带变量占位符,url就是可变,且占位符可以绑定到参数
提供url传参的方式
一般的传参方式:url上的queryString(?后的),body
    @RequestMapping("/user/id")
    @ResponseBody
    public Object user(@PathVariable Integer id)
        System.out.println("========="+id);
        Map<String, Object> map = new HashMap<>();
        map.put("username", "张三");
        map.put("password", "123");
        map.put("email", "xxx@qq.com");
        return map;
    

@RequestParam

绑定请求参数(绑定一个键的值:根据一个键名,获取值)
 queryString
 表单格式(Content-Type为表单默认提交的格式 application/x-www-form-urlencoded ,请求体中的数据)
 from-data( Content-Type为 multipart/form-data ,请求体中的数据。form-data 可以提交文本数据,也可以提交二进制文件)
需要注意@RequestParam注解参数默认为 required=true ,如果不传该参数就会报错,需要指定为: @RequestParam(required = false) 。
必填字段,使用required=true,选填字段,使用required=false
通过 post 请求,使用 form-data 提交一个键为 file 的二进制文件,需要注意整个请求数据大小不能超过10m,单个文件大小不超过1m。(这是 SpringBoot 的默认设置,修改需要通过src/main/resources/application.properties 文件配置)

    @RequestMapping("/3")
    @ResponseBody
    public Object t3(@RequestParam String username,
                     @RequestParam  String password,
                     @RequestParam(required = false) String email)
        System.out.println("========="+username+"\\n"+"========"+password);
        Map<String, Object> map = new HashMap<>();
        map.put("username", "张三");
        map.put("password", "123");
        map.put("email", "xxx@qq.com");
        return map;
    

    @RequestMapping("/4")
    @ResponseBody
    public Object t4(@RequestParam String username,
                     @RequestParam  String password,
                     @RequestParam(required = false)MultipartFile head)
        System.out.println("========="+username+"\\n"+"========"+password);
        Map<String, Object> map = new HashMap<>();
        map.put("username", "张三");
        map.put("password", "123");
        map.put("email", "xxx@qq.com");
        return map;
    

POJO对象

请求映射方法,不带任何注解,使用pojo自定义类型,pojo对象的属性,会绑定请求数据(请求数据的键绑定属性名)
如果不传,或者传入的请求数据,键不一致,属性就是new对象时的默认值
属性使用包装类型
 请求数据比较少的时候,使用请求映射方法的方法参数
 请求数据比较多的时候,使用自定义类型作为方法产生
支持的请求数据

    @RequestMapping("/5")
    @ResponseBody
    public Object t5(User user)
        System.out.println(user);
        return null;
    

@RequestBody

请求数据类型json/application类型,可以使用该注解,把请求体body中的json字符串,反序列化/解析为Java对象
如果属性和请求数据的键不太一样,就不会填充
建议:属性使用包装类型

    @RequestMapping("/6")
    @ResponseBody//必须是json格式,raw之中写
    public Object t6(@RequestBody User user)
        System.out.println(user);
        return null;
    

@RequestPart

from-data请求数据类型时,用于绑定请求的二进制文件

    @RequestMapping("/7")
    @ResponseBody//必须是json格式,raw之中写
    public Object t7(User user,@RequestPart MultipartFile head)
        System.out.println(user);
        return null;
    

SpringMVC自定义配置

@Configuration配置类中,实现WebMvcConfigurer接口,重写接口方法
1) 添加服务路径前缀
2) 添加拦截器

自定义后端路径映射

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) 
        configurer.addPathPrefix("api",c->true);
    

自定义Controller拦截器

对于web项目来说,拦截器可以拦截某些请求,以完成统一的业务
拦截器可以配置需要拦截的路径规则
如果请求路径,匹配到该拦截的路径规则,则会执行拦截方法
拦截方法就可以执行统一业务
 统一记录日志
 统一计算请求响应处理的时间
 统一的用户会话管理
 登录,创建session,并保存用户信息
 访问前端敏感资源,没有登陆,不允许访问,重定向到登录页面
 访问后端敏感资源,没有登陆,不允许访问,返回401,json格式

在preHandle方法中,返回类型为boolean,代表的含义为:

  1. 返回true,允许继续往下执行(往下一个拦截器传递执行,如果没有下一个拦截器,就调用请求映射方法)
  2. 返回false,不往下执行,从拦截器直接返回响应,这个时候,要在preHandle方法中,自行设置返回的响应

@ControllerAdvice

1) 大量的url需要拦截处理时使用
2) 拦截是基于url路径拦截
先添加要拦截的路径,可以再排除不拦截的路径
可以使用模糊匹配,*代表一级路径,**代表多级路径
3) 处理:
场景:通用处理场景使用,如请求的日志记录,请求到响应的执行时间,响应的敏感信息过滤,响应的字段脱敏(手机号)
Api方法:围绕Controller的请求映射方法,前后加入拦截逻辑(实现HandleInterceptor接口)
重写preHandle,前置处理方法,调用前执行
返回true,表示继续往下执行
返回false,表示不往下执行,直接返回响应给客户端

应用一:统一异常处理

package org.example.config;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

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

//注册当前类为一个Bean,结合SpringMVC一些api(接口,注解)
//可以完成统一请求响应的处理:
// (1)统一响应数据格式封装
// (2)统一异常处理
@ControllerAdvice
public class ExceptionAdvice 
    /**
     * 统一异常处理:
     * try
     *     controller.请求映射方法
     * catch(异常类型 e)
     *     调用@ExceptionHandler注解的方法(异常类型是捕获类型的子类)
     * 
     * 该异常处理的方法,http响应和请求映射方法设置方式一样
     * (1)返回类型String,返回视图
     * (2)@ResponseBody,返回json
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Object handle(Exception e)
        e.printStackTrace();
        Map<String, Object> map = new HashMap<>();
        map.put("ok", false);
        map.put("message", e.getMessage());
        return map;
    


测试代码

    @RequestMapping("/8")
    @ResponseBody
    public void t8()
        int i=2/0;
    

以上是关于SpringMVC学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

springmvc学习笔记-springmvc整合mybatis之controller

springmvc学习笔记-springmvc整合mybatis之service

springMVC学习笔记初识springmvc

springmvc学习笔记(11)-springmvc注解开发之简单参数绑定

springmvc学习笔记(15)-数据回显

springmvc学习笔记(13)-springmvc注解开发之集合类型参数绑定