IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> SSM框架学习记录-SpringMVC_day01 -> 正文阅读

[Java知识库]SSM框架学习记录-SpringMVC_day01

1.SpringMVC概述


SpringMVC功能与优点

  • SpringMVC是一种基于Java实现MVC模型的轻量级Web框架

  • SpringMVC技术与Servlet技术功能一样(对Servlet进行了封装),都属于Web层开发技术

  • SpringMVC的主要的作用就是用来接收前端发过来的请求和数据然后经过处理并将处理的结果响应给前端:

    • controller如何接收请求和数据
    • 如何将请求和数据转发给业务层
    • 如何将响应数据转换成json发回到前端
  • SpringMVC的优点:

    • 使用简单、开发便捷(相比于Servlet):上图为使用Servlet开发,下图为使用SpringMVC开发

    在这里插入图片描述
    在这里插入图片描述

    • 灵活性强

SpringMVC和Servlet的三层架构

  • 同步调用阶段:
    • 浏览器发送一个请求给后端服务器(使用Servlet来接收请求和数据)
    • 将后端服务器Servlet拆分成三层,分别是webservicedao(所有的处理都交给Servlet来处理导致耦合度高,对后期的维护和扩展不利)
      • web层主要由servlet来处理,负责页面请求和数据的收集以及响应结果给前端
      • service层主要负责业务逻辑的处理
      • dao层主要负责数据的增删改查操作
    • 针对web层进行了优化(servlet处理请求和数据时,一个servlet只能处理一个请求),采用了MVC设计模式,将其设计为controllerviewModel
      • controller负责请求和数据的接收,接收后将其转发给service进行业务处理
      • service根据需要会调用dao对数据进行增删改查
      • dao把数据处理完后将结果交给serviceservice再交给controller
      • controller根据需求组装成ModelView,二者组合起来生成页面转发给前端浏览器(controller可以处理多个请求,并对请求进行分发,执行不同的业务操作)
  • 异步调用阶段:同步调用的性能跟不上需求
    • 异步调用时后端不需要返回view视图,将其去除
    • 前端如果通过异步调用的方式进行交互,后台就需要将返回的数据转换成json格式进行返回

2.SpringMVC入门


主要步骤

  • 导入SpringMVC坐标与Servlet坐标(scope设置为provided,具体原因见代码中的注释)
  • 创建SpringMVC控制器类(等同于Servlet功能,具体代码见UserController.java)
  • 初始化SpringMVC环境,设定SpringMVC加载对应的bean(具体代码见SpringMvcConfig.java)
    • @ResponseBody:设置当前控制器方法响应内容(json格式)为当前返回值,无需解析成某个资源在项目中的路径
    • @RequestMapping:设置当前控制器方法请求访问路径
  • 初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC技术处理的请求(具体代码见ServletContainersInitConfig.java,简化版本可见Springmvc_02_bean_load中的)
    • createServletApplicationContext:创建Servlet容器时,加载SpringMVC对应的bean并放入WebApplicationContext对象范围(即整个web容器范围)中
    • getServletMappings方法:设定SpringMVC对应的请求映射路径(即SpringMVC拦截哪些请求)
    • createRootApplicationContext方法:如果创建Servlet容器时需要加载非SpringMVC对应的bean,使用当前方法进行
  • 通过插件启动tomcat(先按下图进行配置)

在这里插入图片描述
代码参考Springmvc_01_quickstart


工作流程解析

  • 启动服务器初始化过程:
    • 服务器启动,执行ServletContainersInitConfig类,初始化web容器(类似于以前的web.xml)
    • 执行createServletApplicationContext方法,创建WebApplicationContext对象
    • 加载SpringMvcConfig配置类
    • 执行@ComponentScan加载对应的bean
    • 加载UserController,每个@RequestMapping的名称对应一个具体的方法(所有映射会放置在一起管理)
    • 执行getServletMappings方法,设定SpringMVC拦截请求的路径规则

在这里插入图片描述

  • 单次请求过程:
    • 发送请求http://localhost/save
    • web容器发现该请求满足SpringMVC拦截规则,将请求交给SpringMVC处理
    • 解析请求路径/save,由/save匹配执行对应的save方法并执行
    • 检测到有@ResponseBody直接将save方法的返回值作为响应体返回给请求方

bean加载控制

com.psj包下有controllerservicedao等包,在SpringMVC的配置类SpringMvcConfig中扫描范围为controller,而在Spring的配置类SpringConfig中扫描的范围(com.psj)中包含了controller,如何避免Spring错误加载SpringMVCbean?

  • Spring加载的bean设定扫描范围为精准范围,例如service包、dao包等
@ComponentScan({"com.psj.service","com.psj.dao"})
  • Spring加载的bean设定扫描范围为com.psj,但排除掉controller
// excludeFilters属性:设置扫描加载bean时,排除的过滤规则
//      type属性:设置排除规则,当前使用按照bean定义时的注解类型进行排除
//      classes属性:设置排除的具体注解类,当前设置排除@Controller定义的bean
@ComponentScan(value = "com.psj",
        excludeFilters = @ComponentScan.Filter(
                type = FilterType.ANNOTATION,
                classes = Controller.class
        )
)
  • 不区分SpringSpringMVC的环境,加载到同一个环境中

代码参考Springmvc_02_bean_load


3.请求与响应


请求映射路径

团队多人开发时,每人设置在设置路径时出现冲突该如何解决?比如下面这种情况,启动tomcat时会报错

// UserController中存在一个save方法,路径设置为/save
public class UserController {
    @RequestMapping("/save")
    @ResponseBody
    public String save(){
    	....
    }
}
// BookController中存在一个save方法,路径设置也为/save
public class BookController {
    @RequestMapping("/save")
    @ResponseBody
    public String save(){
    	....
    }
}

需要在类上加@RequestMapping注解进行优化,优化后的代码如下:

@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/save")
    @ResponseBody
    public String save(){
    	...
    }
}
@Controller
@RequestMapping("/book")
public class UserController {
    @RequestMapping("/save")
    @ResponseBody
    public String save(){
    	...
    }
}

代码参考Springmvc_03_request_mapping


请求方式和参数

请求方式有哪几种?主要是GETPOST

接收到请求后,如何接收页面传递的参数?开发中发送JSON格式数据为主,@RequestBody应用较广。如果发送非JSON格式数据,选用@RequestParam接收请求参数

代码参考Springmvc_04_request_param


  • 请求方式:

    • GET发送不同种类的参数:
      • 如果参数中传输中文导致接收到的参数出现乱码,可以在pom.xml中添加<uriEncoding>)
    • POST发送不同种类的参数:和GET请求一致(只不过参数写在请求体中)
      • 使用PostMan发送POST请求时,选择form-datax-www-form-urlencoded的区别在于后者可以传输文件
      • 如果控制台打印出现中文乱码问题,可以在ServletContainersInitConfig中配置过滤器
  • 请求参数:具体参考UserController.java

    • 普通参数:

      • 参数名与形参变量名相同时,定义形参即可接收参数
      // http://localhost/commonParam?name=psj&age=18
      @RequestMapping("/commonParam")
      @ResponseBody
      public String commonParam(String name ,int age){
          ...
      }
      
      • 参数名与形参变量名不相同时,在形参前使用@RequestParam注解
      // http://localhost/commonParamDifferentName?name=psj&age=18
      @RequestMapping("/commonParamDifferentName")
      @ResponseBody
      public String commonParamDifferentName(@RequestParam("name") String userName, int age){
      	...
      }
      
    • POJO类型参数:请求参数名与形参对象属性名相同,定义POJO类型形参即可接收参数(请求参数key的名称要和POJO中属性的名称一致,否则无法封装)

    // http://localhost/pojoParam?name=psj&age=18(User对象中包含这两个属性)
    @RequestMapping("/pojoParam")
    @ResponseBody
    public String pojoParam(User user){
        System.out.println("pojo参数传递 user ==> "+user);
        return "{'module':'pojo param'}";
    }
    
    • 嵌套POJO类型参数:与POJO类型参数一致,只不过在发生请求时有所区别
    // http://localhost/pojoContainPojoParam?name=psj&age=18&address.city=yunnan(User对象中包含这两个属性以及Address对象)
    @RequestMapping("/pojoContainPojoParam")
    @ResponseBody
    public String pojoContainPojoParam(User user){
    	...
    }
    
    • 数组类型参数:请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型即可接收参数
    // http://localhost/arrayParam?likes=game&likes=ball(传入两个属性名一致的参数)
    @RequestMapping("/arrayParam")
    @ResponseBody
    public String arrayParam(String[] likes){
    	...
    }
    
    • 集合类型参数:请求参数名与形参集合对象名相同且请求参数为多个,使用@RequestParam绑定参数关系
    // http://localhost/listParam?likes=game&likes=ball(传入两个属性名一致的参数)
    @RequestMapping("/listParam")
    @ResponseBody
    // SpringMVC将List看做是一个POJO对象来处理(相当于把likes视为List中的属性),但是List是一个接口无法创建对象,所以报错,需要使用@RequestParam
    public String listParam(@RequestParam List<String> likes){  
        System.out.println("集合参数传递 likes ==> "+ likes);
        return "{'module':'list param'}";
    }
    
    • JSON类型参数(GETPOST皆可):SpringMVC默认使用的是jackson来处理JSON的转换,所以需要在pom.xml添加jackson依赖。并且在PostMan中需要设置为Body然后再写入JSON数据。最后要在SpringMvcConfig中开启SpringMVC的注解支持(包含了将JSON转换成对象的功能)

      • JSON普通数组:如{"game, "ball"}
      @RequestMapping("/listParamForJson")
      @ResponseBody
      // 使用@RequestBody注解将外部传递的JSON数组数据映射到形参的集合对象中作为数据
      public String listParamForJson(@RequestBody List<String> likes){
      	...
      }
      
      • JSON对象数据:如{"name":"psj", "age":18}
      @RequestMapping("/pojoParamForJson")
      @ResponseBody
      public String pojoParamForJson(@RequestBody User user){
      	...
      }
      
      • JSON对象数组:如[{"name":"psj", "age":18},{"name":"psw", "age":18}]
      @RequestMapping("/listPojoParamForJson")
      @ResponseBody
      public String listPojoParamForJson(@RequestBody List<User> list){
      	...
      }
      
    • 日期类型参数:如果传入的参数为日期,并且每个参数的日期格式不固定

    @RequestMapping("/dataParam")
    @ResponseBody
    // 使用@DateTimeFormat注解设置日期类型数据格式,默认格式yyyy/MM/dd
    public String dataParam(Date date,
                            @DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
                            @DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2){
    	...
    }
    

响应

主要就包含两部分内容:

  • 响应页面:不能添加@ResponseBody注解
  • 响应数据:
    • 文本数据:需要依赖@ResponseBody注解(方法的返回值为字符串,会将其作为文本内容直接响应给前端)
    • JSON数据:需要依赖@ResponseBody注解和@EnableWebMvc注解,同时要在pom.xml中添加jackson依赖包用于转换为JSON(方法的返回值为对象,会将对象转换成JSON响应给前端)

代码参考Springmvc_05_response


4.REST风格

RESTRepresentational State Transfer,它是一种软件架构风格

RESTful:即根据REST风格对资源进行访问


简介

要表示一个网络资源的时候,可以使用两种方式:

  • 传统风格资源描述形式:不仅麻烦,也不安全(通过URL就可知道是什么操作)
    • http://localhost/user/getById?id=1
    • http://localhost/user/saveUser
  • REST风格描述形式:简化请求地址,并且很难猜出该URL的具体功能
    • http://localhost/user/1
    • http://localhost/user

一个相同的URL可是新增也可是修改或者查询,如何区分该请求是什么操作?按照不同的请求方式代表不同的操作类型(这只是风格,并不是规范),比如发送http://localhost/users 请求时,根据发送时的请求方式即可区分

  • 发送GET请求是用来做查询
  • 发送POST请求是用来做新增
  • 发送PUT请求是用来做修改
  • 发送DELETE请求是用来做删除

入门案例

代码参考Springmvc_06_rest中的UserController.java

注意事项:

  • 如果有多个参数需要传递,比如前端发送请求http://localhost/users/1/psj
@Controller
public class UserController {
    @RequestMapping(value = "/users/{id}/{name}",method = RequestMethod.DELETE)
    @ResponseBody
    public String delete(@PathVariable Integer id,@PathVariable String name)
    {
    System.out.println("user delete..." + id +","+name);
    return "{'module':'user delete'}";
    }
}
  • 形参中的注解@RequestBody@RequestParam@PathVariable 的区别和应用:

    • 区别:

      • @RequestParam用于接收URL传参或表单传参
      • @RequestBody用于接收JSON数据
      • @PathVariable用于接收路径参数(即使用{参数名称}描述的路径参数)
    • 应用:

      • 发送请求参数超过1个时,以JSON格式为主,@RequestBody应用较广
      • 发送非JSON格式数据,选用@RequestParam接收请求参数
      • 采用RESTful进行开发,且参数数量只有1、2个时,可用@PathVariable接收请求路径变量

RESTful快速开发

在代码中有许多重复的地方,以下图为例:

  • 每个方法的@RequestMapping注解中都定义了访问路径/books
  • 每个方法的@RequestMapping注解中都要使用method属性定义请求方式
  • 每个方法响应JSON都需要加上@ResponseBody注解

解决方式如下:

  • @RequestMapping提到类上面,用来定义所有方法共同的访问路径
  • 使用@GetMapping@PostMapping@PutMapping@DeleteMapping代替@RequestMapping注解及其method属性
  • @ResponseBody提到类上面,此时类上有@Controller@ResponseBody,可以使用@RestController替换这两个注解

在这里插入图片描述
代码参考Springmvc_06_rest中的BookController.java


5.案例

代码参考Springmvc_07_rest_case

注意事项:

  • 页面访问处理:
    • 当页面发送请求http://localhost/pages/book.html,正常来说应该显示html页面,但是会显示404,这是因为SpringMVC拦截了静态资源(ServletContainersInitConfig中的getServletMappings方法),根据/pages/books.htmlcontroller找对应的方法
    • SpringMVC需要将静态资源进行放行(具体代码在SpringMvcSupport中),并且对SpringMvcConfig进行修改让其能扫描到该配置类

参考


https://www.bilibili.com/video/BV1Fi4y1S7ix?p=43-58

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-12-25 10:52:39  更:2022-12-25 10:57:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/22 18:17:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码