当前位置: 首页 > news >正文

SpringMVC的基本使用

SpringMVC简介

SpringMVC是Spring提供的一套建立在Servlet基础上,基于MVC模式的web解决方案

SpringMVC核心组件

  • DispatcherServlet:前置控制器,来自客户端的所有请求都经由DispatcherServlet进行处理和分发
  • Handler:处理器,包括了拦截器和控制器中的方法,主要负责处理请求
  • HandlerMapping:映射器,解析文件和扫面注解,内部缓存了handler和handler的访问路径,被DispatcherServlet调用,用于查找路径对应的handler
  • HandlerAdapter:适配器,处理请求参数和处理响应数据,DispatcherServlet就是通过HandlerAdapter间接调用handler
  • ViewResolver:视图解析器,返回的视图是逻辑视图,需要进行解析、渲染之后才是给用户看的页面

img

SpringMVC的工作流程

前端发送的请求由DispatcherServlet接收到,然后DispatcherServlet调用HnadlerMapping映射器,通过URL去匹配对应的handler,因为无法确定处理的类型,所以调用HandlerAdapter适配器去适配handler,适配之后就会调用这个handler处理器(实际就是拦截器和控制器下的方法),如果返回的类型是ModelAndView,就会将这个ModelAndView返回给ViewResolver视图解析器进行解析,得到视图的位置,然后对这个视图进行渲染,最后将渲染好的视图交给DispatcherServlet返回给前端展示;如果在控制器(比如说类或者某个方法上)中加上了@ResponseBody这个注解,就代表handler的返回值是直接返回给前端的,不会经过视图解析器

SpringMVC的使用

第一步:引入依赖

<properties><lombok-vesion>1.18.24</lombok-vesion><fastjson-version>2.0.42</fastjson-version><spring-context-version>5.3.8</spring-context-version><spring-context-supprt-version>5.3.8</spring-context-supprt-version><spring-aop-version>5.3.23</spring-aop-version><project.compile.source>1.8</project.compile.source><project.compile.target>1.8</project.compile.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring-context-version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>${spring-context-supprt-version}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok-vesion}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>${spring-aop-version}</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>${aspectJ-version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring-context-version}</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson-version}</version></dependency>
</dependencies>

第二步:创建spring.xml

在resources文件夹下创建spring.xml文件

错误一:命名空间的标签不匹配,比如xmlns:mvc="http://www.springframework.org/schema/c",mvc应该对应的是../schema/mvc

错误二:没有添加对应的xsi:schemaLocation,比如引入了xmlns:mvc="http://www.springframework.org/schema/mvc",但是没有在最后添加http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--视图解析器:在控制器返回视图的时候生效--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!--视图资源的前缀--><property name="prefix" value="/"/><!--视图资源的后缀--><property name="suffix" value=".jsp"/></bean><!-- 映射器 --><!-- <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/> --><!-- 适配器 --><!-- <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/> --><!-- 较新的版本支持注解驱动,效果等同于上面两句 --><mvc:annotation-driven><mvc:message-converters><ref bean="stringHttpMessageConverter"/><ref bean="jsonConverter"/></mvc:message-converters></mvc:annotation-driven><!-- 添加需要扫描的包 --><context:component-scan base-package="cn.cnmd.controller, cn.cnmd.exception"/><!-- 编码转换器 --><!-- 字符串数据转换器 --><bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter"/><!-- JSON格式数据转换器 --><bean id="jsonConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"><property name="supportedMediaTypes"><list><value>text/html;charset=UTF-8</value><value>application/json;charset=UTF-8</value></list></property></bean></beans>

第三步:编写controller类

报错:415-不支持的媒体类型

解决方案:在spring.xml中配置编码转化器

<!--在注解驱动中添加编码转换器-->
<mvc:annotation-driven><mvc:message-converters><ref bean="stringHttpMessageConverter"/><ref bean="jsonConverter"/></mvc:message-converters>
</mvc:annotation-driven><!-- 字符串数据转换器 -->
<bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter"/><!-- JSON格式数据转换器 -->
<bean id="jsonConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"><property name="supportedMediaTypes"><list><value>text/html;charset=UTF-8</value><value>application/json;charset=UTF-8</value></list></property>
</bean>

UserController类

@RestController//@RestController = @Controller + @ResponseBody
@RequestMapping("/user")
public class UserController {/*** 获取一个学生的信息** @param id 学生编号* @return 学生对象*/@GetMappingpublic Student getStudent(@RequestParam("id") int id) {// System.out.println(1/0); => 遇到异常会被带有@RestControllerAdvice注解的ExceptionController处理return new Student();}/*** 添加一个学生** @param student 学生对象的JSON数据* @return 状态码*/@PostMappingpublic int addStudent(@RequestBody Student student) {System.out.println("student = " + student);return 0;}/*** 更新一个学生的信息** @param student 更新后的学生信息* @return 状态码*/@PutMappingpublic int updateStudent(@RequestBody Student student) {System.out.println("student = " + student);return 0;}/*** 通过学生id删除一个学生** @param id 学生编号* @return 状态码*/@DeleteMapping("/{id}")public int deleteStudent(@PathVariable("id") int id) {System.out.println("id = " + id);return 0;}/*** 批量查询学生** @param currentPage 当前页数* @param pageSize    当页数据条数* @return 学生集合*/@GetMapping("/stuList")public List<Student> getAllStudent(@RequestParam("currentPage") int currentPage,@RequestParam("pageSize") int pageSize) {System.out.println("currentPage = " + currentPage + ", pageSize = " + pageSize);return new ArrayList<>();}/*** 获取请求头中的数据** @param ua 请求头中的User-Agent*/@GetMapping("/header")public void getHeader(@RequestHeader("User-Agent") String ua) {System.out.println("ua = " + ua);}/*** 获取cookie中的数据** @param status cookie中的key:status*/@GetMapping("/cookie")public void getCookie(@CookieValue("status") String status) {System.out.println("status = " + status);}}

全局异常处理

@RestControllerAdvice
public class ExceptionController {/*** 处理全局异常的方法** @param e 异常对象* @return 异常信息*/@ExceptionHandler(Exception.class)public String exceptionHandler(Exception e) {return e.getMessage();}
}

常用的注解

实例都在上方

//用于标记是否是一个控制器
@Controller//匹配请求中的URL地址来调用对应的handler
@RequestMapping//用于匹配URL地址中的parameter参数
@RequestParam//用于匹配URL路径上的参数
@PathVariable//用于匹配前端发送给后端的JSON数据
@RequestBody//用于匹配请求头中的数据
@RequestHeader//用于匹配Cookie中的数据
@CookieValue//用于标记一个方法的返回值是否直接返回给前端
@ResponseBody//RESTFul风格下的注解,等同于@Controller + @ResponseBody
@RestController//RESTFul风格下的用于匹配不同请求方式
@GetMapping/@PostMapping/@PutMapping/@DeleteMapping//该注解只能应用在类上,表示这个类就是处理异常的控制器    
@ControllerAdvice//RESTFul风格下的用于表示这个类就是处理异常的控制器,并且返回值直接返回给前端,等同于@ControllerAdvice + @ResponseBody 
@RestControllerAdvice//该注解只能应用在@ControllerAdvice或者说@RestControllerAdvice标识的类的方法上,用来处理异常
@ExceptionHandler

静态资源访问解决

为什么静态资源无法访问?

因为在Tomcat的自带的web.xml中有这样一个配置

<!--.......-->
<servlet><servlet-name>default</servlet-name><servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class><init-param><param-name>debug</param-name><param-value>0</param-value></init-param><init-param><param-name>listings</param-name><param-value>false</param-value></init-param><load-on-startup>1</load-on-startup>
</servlet>
<!--.......-->
<!-- The mapping for the default servlet -->
<servlet-mapping><servlet-name>default</servlet-name><url-pattern>/</url-pattern>
</servlet-mapping>

说明在创建webapp项目时,我们在web.xml中配置的DispathcerServlet的映射覆盖了DefaultServlet的映射,所以就不会再使用默认的DefaultServlet,造成了静态资源无法访问

解决方案

方案一:修改@XxxMapping中的url,比如加上后缀.do.action

方案二【推荐】:在web.xml中配置静态资源的访问地址,比如将js、css、图片等静态资源放在static文件夹下

<!-- web.xml -->
<servlet-mapping><servlet-name>default</servlet-name><url-pattern>/static/*</url-pattern>
</servlet-mapping>

方案三:在spring.xml文件中配置 default-servlet-handler

<!-- 
这个handler就是处理静态资源的,它的处理方式就是将请求转会到tomcat中名为default的Servlet 
-->
<mvc:default-servlet-handler/>
<!-- mapping是访问路径,location是静态资源存放的路径 -->
<mvc:resources mapping="/static/**" location="/static/" />

中文乱码问题

解决方案:编码转换器

<!-- 编码转换器 -->
<!-- 字符串数据转换器 -->
<bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter"/><!-- JSON格式数据转换器 -->
<bean id="jsonConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"><property name="supportedMediaTypes"><list><value>text/html;charset=UTF-8</value><value>application/json;charset=UTF-8</value></list></property>
</bean>
<!--在注解驱动中添加编码转化器-->
<mvc:annotation-driven><mvc:message-converters><ref bean="stringHttpMessageConverter"/><ref bean="jsonConverter"/></mvc:message-converters>
</mvc:annotation-driven>

相关文章:

  • Spring Data与多数据源配置
  • 《昇思25天学习打卡营第9天|onereal》
  • adb shell logcat -b all|grep如何可以grep两个子串?
  • Rust Eq 和 PartialEq
  • 第三节:如何理解Spring的两个特性IOC和AOP(自学Spring boot 3.x第一天)
  • 嵌入式学习(Day 51:ARM指令/汇编与c语言函数相互调用)
  • 红酒SPA:享受放松与奢华的很好结合
  • (四)opengl函数加载和错误处理
  • 【RNN练习】LSTM-火灾温度预测
  • 【软考论文】论基于架构的软件设计方法及应用(ABSD)
  • 【C++】数组、字符串
  • .NET编程C#线程之旅:十种开启线程的方式以及各自使用场景和优缺点
  • 【ajax实战08】分页功能
  • Lua博客网站支持搜索、评论、登录注册
  • postman
  • 【Amaple教程】5. 插件
  • java第三方包学习之lombok
  • JDK 6和JDK 7中的substring()方法
  • js如何打印object对象
  • laravel with 查询列表限制条数
  • MySQL的数据类型
  • October CMS - 快速入门 9 Images And Galleries
  • oschina
  • PHP 小技巧
  • Python代码面试必读 - Data Structures and Algorithms in Python
  • QQ浏览器x5内核的兼容性问题
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 成为一名优秀的Developer的书单
  • 二维平面内的碰撞检测【一】
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 翻译:Hystrix - How To Use
  • 构建工具 - 收藏集 - 掘金
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 前端_面试
  • 强力优化Rancher k8s中国区的使用体验
  • 微服务入门【系列视频课程】
  • 我从编程教室毕业
  • 在weex里面使用chart图表
  • gunicorn工作原理
  • Nginx实现动静分离
  • Spring Batch JSON 支持
  • ( )的作用是将计算机中的信息传送给用户,计算机应用基础 吉大15春学期《计算机应用基础》在线作业二及答案...
  • (1)(1.13) SiK无线电高级配置(六)
  • (MATLAB)第五章-矩阵运算
  • (第9篇)大数据的的超级应用——数据挖掘-推荐系统
  • (附源码)spring boot网络空间安全实验教学示范中心网站 毕业设计 111454
  • (附源码)ssm教师工作量核算统计系统 毕业设计 162307
  • (精确度,召回率,真阳性,假阳性)ACC、敏感性、特异性等 ROC指标
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (完整代码)R语言中利用SVM-RFE机器学习算法筛选关键因子
  • (译) 函数式 JS #1:简介
  • (转载)hibernate缓存
  • .NET Core日志内容详解,详解不同日志级别的区别和有关日志记录的实用工具和第三方库详解与示例
  • .NET 中各种混淆(Obfuscation)的含义、原理、实际效果和不同级别的差异(使用 SmartAssembly)