SpringMVC学习简要

news2025/1/18 4:37:18

学习资料:

SpringMVC-03-入门案例工作流程解析_哔哩哔哩_bilibiliicon-default.png?t=N7T8https://www.bilibili.com/video/BV1ZF411G7eP/?p=3&spm_id_from=pageDriver&vd_source=4ac53f52a57eb96a3c8406b971b038ae

常用MYSQL命令:icon-default.png?t=N7T8http://t.csdn.cn/zshCP

学习要求 

什么是springmvc

  • springmvc是一种基于java实现MVC模型的轻量级web框架
  • 比servlet更便捷
  • MVC模式:后端服务器
    • controller

      view(页面)

      • HTML
      • CSS
      • VUE
      • ElementUI

      model

      (最终生成的model对象是一个java对象,不能直接返回页面,要使用json格式)

      service
      dao

springmvc基本使用步骤

  • 创建web工程(maven结构)
  • 设置tomcat服务器,加载web工程(tomcat插件)
  • 导入坐标(SpringMVC+Servlet)
  • 定义处理请求的功能类(UserController)
  • 设置请求映射 (配置映射关系)
  • 将SpringMVC设定加载到Tomcat容器中 

启动服务器初始化过程

  •  服务器启动,执行ServletContainersInitConfig类,初始化web容器
  • 执行createServletApplicationContext方法,创建了WebApplicationContext对象
  • 加载SpringMvcConfig
  • 执行@ComponentScan,加载对应的bean
  • 加载UserController,每个@RequestMapping的名称对应一个具体的方法
  • 执行getServletMappings方法,定义所有的请求都通过SpringMVC
  •  简而言之:
    • 1、把springmvc配置加载到tomcat容器中
    • 2、把所有请求拦截给springmvc处理

单次请求过程

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

Springmvc的bean扫描范围

  • 因为功能不同,如何避免spring错误地加载到SpringMVC的bean?
  • springmvc加载的bean均在com.itheima.controller包内
  • 所以要修改spring的bean扫描范围:
    • 方式一:把加载bean的扫描范围设定为com.itheima,再排除掉controller包内的bean
      @Configuration
      @ComponentScan(
              value="com.study",//扫描该包
              excludeFilters=@ComponentScan.Filter(
                      type= FilterType.ANNOTATION, //按注解排除
                      classes= Controller.class//不扫描有@Controller注解的包
          )
      )
      public class SpringConfig {
      }
      
    • 方式二:直接设定为更具体的包,如com.itheima.service,com.itheima.dao。。。
    • 在springmvc项目中,以使用方式二为主

请求(解决传参的问题)

  • 请求映射路径(@RequestMapping)

  • 该代码具有一般性
    • package com.study.config;
      
      import org.springframework.web.filter.CharacterEncodingFilter;
      import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
      
      import javax.servlet.Filter;
      
      public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
      
          protected Class<?>[] getRootConfigClasses() {
              return new Class[0];
          }
      
          protected Class<?>[] getServletConfigClasses() {
              return new Class[]{SpringMvcConfig.class};
          }
      
          protected String[] getServletMappings() {
              return new String[]{"/"};
          }
      
          //乱码处理
          @Override
          protected Filter[] getServletFilters() {
              //为web容器添加过滤器并指定字符集
              CharacterEncodingFilter filter=new CharacterEncodingFilter();
              filter.setEncoding("UTF-8");
              return new Filter[]{};//数组的形式
          }
      }
      
  • 1、五种数据类型的传参(@RequestParam)

    • package com.study.controller;
      
      import com.study.domain.User;
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestParam;
      import org.springframework.web.bind.annotation.ResponseBody;
      
      import java.util.Arrays;
      import java.util.List;
      
      @Controller
      public class UserController {
      
          //普通参数,当请求参数名与形参名不同时,使用RequestParam注解
          @RequestMapping("/commonParam")
          @ResponseBody
          public String commonParam(@RequestParam("name")String userName){
              System.out.println("普通参数传递,userName:"+userName);
              return "{'module':'common Param'}";
          }
      
          //POJO参数
          @RequestMapping("/pojoParam")
          @ResponseBody
          public String pojoParam(User user){
              System.out.println("pojo参数传递,user:"+user);
              return "{'module':'pojo Param'}";
          }
      
          //嵌套POJO参数
          @RequestMapping("/pojoContainPojoParam")
          @ResponseBody
          public String pojoContainPojoParam(User user){
              System.out.println("pojo嵌套参数传递,user:"+user);
              return "{'module':'pojo contain Param'}";
          }
      
          //数组参数
          @RequestMapping("/arrayParam")
          @ResponseBody
          public String arrayParam(String[] likes){
              System.out.println("数组参数传递,likes:"+ Arrays.toString(likes));
              return "{'module':'array Param'}";
          }
      
          //集合参数
          @RequestMapping("/listParam")
          @ResponseBody
          public String listParam(@RequestParam List<String> likes){
              System.out.println("集合参数传递,likes:"+ likes);
              return "{'module':'list Param'}";
          }
      }
      
    • 简而言之,url传递参数时,如果名称不对应,使用@RequestParam注解
  • 2、json数据传递参数(@RequestBody和@RequestParam

    • (1)导入坐标
      <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.10</version>
      </dependency>
    • (2)在核心注解类中加注解,开启自动转换json数据的支持
      • @EnableWebMvc
        public class SpringMvcConfig {
        }
        
    • (3)注意postman里的4处
    • (4)添加@RequestBody注解
          //集合参数:json格式
          @RequestMapping("/listParamForJson")
          @ResponseBody
          public String listParamForJson(@RequestBody List<String> likes){
              System.out.println("list common(json)参数传递,list:"+ likes);
              return "{'module':'list Param for json param'}";
          }
      
          //POJO参数:json格式
          @RequestMapping("/pojoParamForJson")
          @ResponseBody
          public String pojoParamForJson(@RequestBody User user){
              System.out.println("pojo(json)参数传递,user:"+ user);
              return "{'module':'pojo for json param'}";
          }
      
          //集合参数:json格式
          @RequestMapping("/listPojoParamForJson")
          @ResponseBody
          public String listPojoParamForJson(@RequestBody List<User> list){
              System.out.println("list pojo(json)参数传递,list:"+ list);
              return "{'module':'list pojo for json param'}";
          }
      • 发送json数据,用注解@RequestBody
      • 发送非json数据,用注解@RequestParam接收参数
  • 3、日期型参数传递(@DateTimeFormat)

    • 根据不同的日期格式设置不同的接收格式
          //日期参数
          @RequestMapping("/dataParam")
          @ResponseBody
          public String dataParam(Date date,
                                  @DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
                                  @DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date date2){
              System.out.println("参数传递,date:"+ date);//2088/08/08
              System.out.println("参数传递,date1(yyyy-MM-dd):"+ date1);//2088-08-08
              System.out.println("参数传递,date1(yyyy/MM/dd HH:mm:ss):"+ date2);//2088/08/08 8:08:08
              return "{'module':'date param'}";
          }
    • 注解@DateTimeFormat用于设定接收的日期格式

响应(@ResponseBody)

  • 1、响应页面

    • @RequestMapping("/toPage")
      public String toPage(){
          return "page.jsp";
      }
  • 2、响应json数据(对象转json)

    • @RequestMapping("/toJsonPOJO")
      @ResponseBody //把user对象转成json数据返回
      public User toJsonPOJO(){
              User user=new User();
              user.setName("itcast");
              user.setAge(15);
              return user;
      }
  • 3、响应json数据(对象集合转json数组)

    • @RequestMapping("/toJsonList")
      @ResponseBody
      public List<User> toJsonList(){
              System.out.println("返回json集合数据");
              User user1=new User();
              user1.setName("itcast");
              user1.setAge(15);
      
              User user2=new User();
              user2.setName("黑马");
              user2.setAge(12);
      
              List<User> userList=new ArrayList<>();
              userList.add(user1);
              userList.add(user2);
              return userList;
      }
  • 类型转换器(HttpMessageConverter)
        

REST风格

  • Representational State Transfer,表现层资源状态转移
  • 简而言之,REST风格就是访问网络资源的格式
  • 约定可以打破,所以叫REST风格,而不是REST规范
  • 模块名称通常用复数
  • 使用

    • 1、设定http请求动作
    • 2、设定请求参数路径变量
  • 三个接收参数的注解区别:
    • (1)@RequestParam用于接收url地址传参或表单传参
    • (2)@RequestBody用于接收json数据
    • (3)@PathVariable用于接收路径参数,使用{参数名称}描述路径参数
  • REST风格简化开发

    • //简化前
      @Controller
      public class UserController {
      
          @RequestMapping(value="/users",method=RequestMethod.POST)
          @ResponseBody
          public String save(){
              System.out.println("user save...");
              return "{'module':'user save'}";
          }
      
          @RequestMapping(value="/users/{id}",method=RequestMethod.DELETE)
          @ResponseBody
          public String delete(@PathVariable Integer id){//从路径处传过来的变量
              System.out.println("user delete..."+id);
              return "{'module':'user delete'}";
          }
      
          @RequestMapping(value="/users",method=RequestMethod.PUT)
          @ResponseBody
          public String update(@RequestBody User user){
              System.out.println("user update..."+user);
              return "{'module':'user update'}";
          }
      
          @RequestMapping(value="/users/{id}",method=RequestMethod.GET)
          @ResponseBody
          public String getById(@PathVariable Integer id){
              System.out.println("user getById..."+id);
              return "{'module':'user getById'}";
          }
      
          @RequestMapping(value = "/users",method = RequestMethod.GET)
          @ResponseBody
          public String getAll(){
              System.out.println("user getAll...");
              return "{'module':'user getAll'}";
          }
      }
      
      
      
      
      //简化后
      @RestController
      @RequestMapping("/users")
      public class UserController {
      
          @PostMapping
          public String save(){
              System.out.println("user save...");
              return "{'module':'user save'}";
          }
      
          @DeleteMapping("/{id}")
          public String delete(@PathVariable Integer id){
              System.out.println("user delete..."+id);
              return "{'module':'user delete'}";
          }
      
          @PutMapping
          public String update(@RequestBody User user){
              System.out.println("user update..."+user);
              return "{'module':'user update'}";
          }
      
          @GetMapping("/{id}")
          public String getById(@PathVariable Integer id){
              System.out.println("user getById..."+id);
              return "{'module':'user getById'}";
          }
      
          @GetMapping
          public String getAll(){
              System.out.println("user getAll...");
              return "{'module':'user getAll'}";
          }
      }
  • 基于RESTful页面数据交互 

    • 1、做后台功能,开发接口并调通接口
    • 2、做页面异步调用,确认功能正常可以访问
    • 3、完成页面数据展示 
    • 4、放行静态资源的访问

SSM整合(Spring,MyBatis,SpringMVC)

  • 详见具体项目代码
  • Spring整合MyBatis的结构

配置(config)

  • SpringConfig
  • JDBCConfig、jdbc.properties
  • MyBatisConfig

表现层(controller)

  • BookController
  • Result
  • Code

模型(domain)

  • Book

数据层标准开发(dao)

  • BookDao

业务层标准开发(service)

  • BookService
  • BookServiceImpl

测试接口(test/service)

  • BookServiceTest
  • 异常处理
    • 项目异常:
      • 1、业务异常(BusinessException)
        • 发送对应消息传递给用户,提醒规范操作
      • 2、系统异常(SystemException)
        • 发送固定消息传递给用户,安抚用户
      • 3、其他异常(Exception)
        • 发送固定消息传递给用户,安抚用户
    • 项目异常处理
      • 1、自定义项目系统级异常、业务级异常……
        • //自定义项目系统级异常
          axios.get("/books").then((res)=>{});//查询
          axios.post("/books",this.formData).then((res)=>{});//添加
          axios.delete("/books"+row.id).then((res)=>{});//删除
          axios.put("/books",this.formData).then((res)=>{});//修改
          axios.get("/books"+row.id).then((res)=>{});//查询
      • 2、自定义异常编码(类似404,500的存在)
      • 3、触发自定义异常

拦截器(Interceptor)

  • 是一种动态拦截方法调用的机制
  • 拦截器和过滤器的区别:
    • 1、Filter属于Servlet技术,Interceptor属于SpringMVC技术
    • 2、Filter对所有访问进行增强,Interceptor仅对SpringMVC的访问进行增强
  • 使用步骤:

    • 1、声明拦截器的bean,并实现HandlerInterceptor接口
    • 2、定义配置类,继承WebMvcConfigurationSupport,实现addInterceptor方法
    • 3、添加拦截器并设定拦截的访问路径,路径可以通过可变参数设置多个
  • 拦截器参数:

    • 1、前置处理
      public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
              String contentType=request.getHeader("Content-Type");
              System.out.println("preHandle..."+contentType);
              return true;
      }
      • 参数:
        • request:请求对象
        • response:响应对象
        • handler:被调用的处理器对象
      • 返回值: false,被拦截的处理器将不执行
    • 2、后置处理
      public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
              System.out.println("postHandle...");
      
      }
      • modelAndView: 读取并调整返回结果对应的数据和页面信息
    • 3、完成后处理
      public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
              System.out.println("afterCompletion...");
      
      }
      • ex:处理处理器执行过程中出现的异常情况
  • 多拦截器执行顺序(了解即可,通常一个拦截器就够用了) 

    • 配置的多个拦截器形成拦截器链
    • 拦截器链的运行顺序以拦截器添加顺序为准

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/997858.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微信小程序Day4笔记

1. 组件的创建与引用 创建组件 在项目的根目录中&#xff0c;鼠标右键&#xff0c;创建components -> test文件夹在新建的test文件夹上&#xff0c;鼠标右键&#xff0c;点击新建Component键入组件的名称之后回车&#xff0c;会自动生成组件对应的4个文件&#xff0c;后缀…

《服务器无状态设计:为什么如何实现无状态API?》

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

3.1 栈和队列的定义和特点

3.1.1 栈的定义和特点 主要内容&#xff1a; 3.1 栈和队列的定义和特点 3.1.1 栈的定义和特点 定义&#xff1a; 栈是一种特殊的线性表&#xff0c;只允许在一端进行插入或删除操作。这一端被称为栈顶&#xff0c;而另一端则称为栈底。不包含任何元素的栈被称为空栈。 特点…

分布式调度 Elastic-job

分布式调度 Elastic-job 1.概述 1.1什么是任务调度 我们可以思考一下下面业务场景的解决方案: 某电商平台需要每天上午10点&#xff0c;下午3点&#xff0c;晚上8点发放一批优惠券某银行系统需要在信用卡到期还款日的前三天进行短信提醒某财务系统需要在每天凌晨0:10分结算…

Java虚拟机(JVM)解析:内存区域、类加载、垃圾回收和选型考虑

目录 一、JVM内存区域划分 二、JVM类加载 三、JVM垃圾回收&#xff08;GC&#xff09; 一、JVM内存区域划分 栈堆方法区(元数据区)程序计数器 1.栈 举个例子&#xff1a; 那具体是怎么分的呢&#xff1f;如下图 本地方法栈&#xff1a;给JVM内部的方法准备的栈空间 虚拟…

在MySQL客户端使用Tab健进行命令补全

在MySQL客户端中&#xff0c;你可以使用Tab键进行命令补全&#xff0c;这将提高我们的效率&#xff0c;这与Linux命令行中的行为类似。例如&#xff0c;如果你输入SEL然后按Tab键&#xff0c;MySQL客户端会自动补全为SELECT。 然而&#xff0c;需要注意的是&#xff0c;这个功能…

数据结构 - 栈

目录 二、栈的实现 1.数组模拟实现栈 设计思想: 方法实现: Peek(): 偷窥栈顶元素 pop(): 栈顶出栈 push(): 2.链表模拟实现 3 . 栈的继承体系 总结 前言 大家好,这篇博客带大家了解一下栈是什么? 并且用两种方式为大家实现一下栈 一、栈是什么&#xff1f; 栈是一种数…

npm介绍

npm介绍 npm&#xff08;Node Package Manager的缩写&#xff09;是一个软件包管理器&#xff0c;主要进行JavaScript的包管理。通过npm&#xff0c;我们可以很方便地进行JavaScript包的下载、升级&#xff0c;我们也可以把我们开发的JavaScript包共享给其他使用者。 在npm没…

大数据-玩转数据-Flink状态后端(下)

一、状态后端 每传入一条数据&#xff0c;有状态的算子任务都会读取和更新状态。由于有效的状态访问对于处理数据的低延迟至关重要&#xff0c;因此每个并行任务(子任务)都会在本地维护其状态&#xff0c;以确保快速的状态访问。 状态的存储、访问以及维护&#xff0c;由一个…

goweb入门

创建gomod项目 go mod init web01新建main.go package mainimport ("fmt""net/http" )func handler(writer http.ResponseWriter, request *http.Request) {fmt.Fprintf(writer, "Hello World,%s!", request.URL.Path[1:]) } func main() {fmt…

Mysql基于成本选择索引

本篇文章介绍mysql基于成本选择索引的行为&#xff0c;解释为什么有时候明明可以走索引&#xff0c;但mysql却没有走索引的原因 mysql索引失效的场景大致有几种 不符合最左前缀原则在索引列上使用函数或隐式类型转换使用like查询&#xff0c;如 %xxx回表代价太大索引列区分度过…

PHP8中获取并删除数组中最后一个元素-PHP8知识详解

在php8中&#xff0c;array_pop()函数将返回数组的最后一个元素&#xff0c;并且将该元素从数组中删除。语法格式如下&#xff1a; array_pop(目标数组) 获取并删除数组中最后一个元素&#xff0c;参考代码&#xff1a; <?php $stu array(s001>明明,s002>亮亮,s…

Ansible数组同步至Shell脚本数组中

1、ansible中定义数组&#xff0c;我以 ccaPojectList 数组为例子,如下图数组内容 2、需要写一个j2模板的Shell脚本&#xff0c;在j2模板的Shell脚本中引用ansible的 ccaPojectList 数组&#xff0c;大致如下图&#xff1a; {% for item in ccaPojectList %} "{{ item }…

Linux JAVA环境的搭建tomcat的部署(含多实例)

tomcat tomcat是Apache软件基金会项目中的一个核心项目由 Apache、Sun 和其他一些公司及个人共同开发而成。tomcat 是 Java 语言开发的&#xff0c;Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器. tomcat的组成 tomcat用于支持Java Servlet和JSP。它是一个重要的We…

手动开发-简单的Spring基于注解配置的程序--源码解析

文章目录 设计注解$设计容器 $#完整代码# 在前文中 《手动开发-简单的Spring基于XML配置的程序–源码解析》&#xff0c;我们是从XML配置文件中去读取bean对象信息&#xff0c;再在自己设计的容器中进行初始化&#xff0c;属性注入&#xff0c;最后通过getBean()方法进行返回。…

Service Mesh目的:是解决系统架构微服务化后的服务间通信和治理问题。

参考链接&#xff1a;https://www.zhihu.com/tardis/bd/art/397945267?source_id1001 1、Service Mesh 是什么 Service Mesh的定义&#xff1a; 服务网格是一个基础设施层&#xff0c;用于处理服务间通信。云原生应用有着复杂的服务拓扑&#xff0c;服务网格保证请求在这些…

Docker:01 OverView

Docker&#xff1a;01 OverView 基本介绍 Docker是一个用于开发、交付、运行应用程序的开放平台&#xff0c;可以使应用程序与基础架构分开&#xff0c;以便快速交付软件。 Docker在一个被叫做容器的隔离环境下&#xff0c;提供了打包和运行的能力。 容器非常轻量化&#x…

[SICTF 2023] webmisc

文章目录 webBaby_PHP涉及知识点 我全都要RCE你能跟得上我的speed吗 miscPixel_art攻破这个压缩包&#xff01; web Baby_PHP 涉及知识点 php解析特性apache换行解析漏洞无参RCE 源代码 <?php highlight_file(__FILE__); error_reporting(0);$query $_SERVER[QUERY_ST…

【新版】软考 - 系统架构设计师(总结笔记)

个人总结学习笔记&#xff0c;仅供参考&#xff01;&#xff01;&#xff01; →点击 笔者主页&#xff0c;欢迎关注哦&#xff08;互相学习&#xff0c;共同成长&#xff09; 笔记目录 &#x1f4e2;【系统架构设计系列】系统架构设计专业技能 计算机组成与结构操作系统信…

AI系统论文阅读:SmartMoE

提出稀疏架构是为了打破具有密集架构的DNN模型中模型大小和计算成本之间的连贯关系的——最著名的MoE。 MoE模型将传统训练模型中的layer换成了多个expert sub-networks&#xff0c;对每个输入&#xff0c;都有一层special gating network 来将其分配到最适合它的expert中&…