七、Spring MVC高级技术
知识点
- 处理文件上传
- 使用flash属性
- 在控制器中处理异常
关键词
- 控制器通知 (Controller Advice)
7.1 处理异常
Spring提供了多种方式将异常转换为响应:
- 特定的Spring异常将会自动映射为指定的HTTP状态码
- 异常上可以添加@RequestStatus注解,从而将其映射为某一个HTTP状态码
- 在方法上可以添加@ExceptionHandler注解,使其用来处理异常
最简单的方式就是第二种,映射。
7.1.1 将异常映射为HTTP状态码
在默认情况下,Spring会将自身的一些异常自动转化为合适的状态码。
| Spring异常 | HTTP状态码 |
|---|---|
| BindException | 400-Bad Request |
| ConversionNotSupportedException | 500-Internal Server Error |
| HttpMessageNotReadableException | 400-Bad Request |
| HttpMessageNotWriteableException | 500-Internal Server Error |
| HttpRequestMethodNotSupportedException | 405-Method Not Allowed |
| MethodArgumentNotValidException | 400-Bad Request |
| MissingServletRequestParameterException | 400-Bad Request |
| MissingServletRequestPartException | 400-Bad Request |
| NoSuchRequestHandlingMethodException | 404-Not Found |
| TypeMismatchException | 400-Bad Request |
@ResponseStatus(value=HttpStatus.NOT_FOUND, reason="Spittle Not Found")
public class .....
7.2 为控制器添加通知
控制器通知是任意带有@ControllerAdvice注解的类,这个类包含以下的方法:
- @ExceptionHandler 注解标注的fangfa
- @InitBinder注解标注的方法
- @ModelAttribute注解标注的方法
以上这些方法会自动运用到整个应用程序所有控制器中带有@RequestMapping注解的方法上。
// 写一个控制器异常处理类
package test
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
// 定义控制器类
@ControllerAdvice
public class AppWideExceptionHandler {
// 定义处理异常的方法
@ExceptionHandler(DuplicateSpittleException.class)
public String duplicateSpittleHandler() {
return "error/duplicate";
}
}
如果任何地方抛出DuplicateSpittleException,则会调用duplicateSpittleHandler方法来处理异常。
7.5 跨重定向请求传递数据
在5.4说了重定向的基础功能,Spring还为其提供了其他的辅助功能。
Q:正在发起重定向功能的方法该如何发送数据给重定向的目标方法呢?
当一个处理器方法完成之后,该方法所指定的模型数据将会复制到请求中,并作为请求中的属性,请求会转发到视图上进行渲染。因为控制器方法和视图所处理的是同一个请求,所以在转发中请求属性能够得以保存。
以上是请求的处理内容,但是重定向不同。
当控制器返回的结果是重定向的话,原始的请求就结束了,并且会发起新的一个GET请求。原始请求中带有的参数也会一起消失,在新请求属性中,没有任何来自模型的数据,必须通过方法内获取后,赋值到重定向的结果中,作为新请求的数据。
重定向传递数据的两种方法:
- 使用URL模板以路径变量和/或查询参数的形式传递数据。
- 通过flash属性发送数据。
第一种方法
@RequestMapping(value="/register",method=POST)
public String executeRegister(Spittr spittr,Model model) {\
spitterRepository.save(spittr);
model.addAttribute("username",spitter.getUsername());
// 假设有一个POJO类为spittr,且有一个变量为Username,并生成一个getUsername()的方法
// 5.4中的写法
// return "redirect:/home/" + spittr.getUsername()
return "redirect:/home/{username}";
}
将username作为占位符填充到URL模板中,而不是直接连接字符串,在占位符中重新转义编码,提升了一定的安全性。
例2:
@RequestMapping(value="/register",method=POST)
public String executeRegister(Spittr spittr,Model model) {\
spitterRepository.save(spittr);
model.addAttribute("username",spitter.getUsername());
model.addAttribute("userId",spitter.getId());
// 假设有一个POJO类为spittr,且有一个变量为Username,并生成一个getUsername()的方法
// 5.4中的写法
// return "redirect:/home/" + spittr.getUsername()
return "redirect:/home/{username}";
}
新增userId,但是在重定向路径中并没有userId的占位符,重定向后它会被加载到尾部,假设ID=47,生成
/home/lihua?userId=47。有没有对这个url比较熟悉,?后面的内容就是这样子加上去的。
该方法的局限性:在于它只可以发送简单的值,比如字符串或者数字等,没办法处理更为复杂的值。处理复杂的值就是flash方法存在的意义。
第二章方法--flash
如果要发送实际的对象等,Spring会将胯重定向存活的数据放到会话中,提供将数据发送为flash属性的功能,按照定义,flash属性会一直携带这些数据直到下一次请求。提供RedirectAttributes设置flash属性的方法。该模块不仅包含了Model的所有功能,还提供几个方法设置flash属性。
@RequestMapping(value="/register",method=POST)
public String executeRegister(Spittr spittr,RedirectAttributes model) {\
spitterRepository.save(spittr);
model.addAttribute("username",spitter.getUsername());
// 假设有一个POJO类为spittr,且有一个变量为Username,并生成一个getUsername()的方法
// 5.4中的写法
// return "redirect:/home/" + spittr.getUsername();
model.addFlashAttribute("spitter",spitter);
return "redirect:/home/{username}";
}
"spitter"为key,后面spitter为值,而flash会自动进行推断而不需要设置。
七、Spring MVC高级技术的更多相关文章
- 【Spring】Spring MVC高级技术
前言 前面学习了简单的Spring Web知识,接着学习更高阶的Web技术. 高级技术 Spring MVC配置的替换方案 自定义DispatcherServlet配置 在第五章我们曾编写过如下代码. ...
- Spring学习(七)--Spring MVC的高级技术
一.Spring MVC配置的替代方案 我们已经了解如何通过AbstractAnnotationConfigDispatcherServlet- Initializer快速搭建了Spring MVC环 ...
- Spring系列(七) Spring MVC 异常处理
Servlet传统异常处理 Servlet规范规定了当web应用发生异常时必须能够指明, 并确定了该如何处理, 规定了错误信息应该包含的内容和展示页面的方式.(详细可以参考servlet规范文档) 处 ...
- Spring MVC(3)Spring MVC 高级应用
一.Spring MVC 的数据转换和格式化 前面的应用,都只是用HandlerAdapter去执行处理器. 处理器和控制器不是一个概念,处理器是在控制器功能的基础上加上了一层包装,有了这层包装,在H ...
- 第七篇 .NET高级技术之关于相等 Equals
查看判断两个对象是否是同一个对象要用:object.ReferenceEquals(); 因为“==”默认值是比较两个对象是不是同一个对象.所以有时候两个对象的内容相等,但是比较后还是false. O ...
- spring入门(七) spring mvc+mybatis+generator
1.Mybatis-Generator下载 地址:https://github.com/mybatis/generator/releases 我使用的是 mybatis-generator-core- ...
- spring-mvc高级技术
Spring MVC高级技术包括但不限于web.xml配置.异常处理.跨重定向请求传递数据 1.web.xml文件的配置 <!DOCTYPE web-app PUBLIC "-//Su ...
- spring MVC框架入门(外加SSM整合)
spring MVC框架 一.什么是sping MVC Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 W ...
- Java方式配置Spring MVC
概述 使用Java方式配置Spring MVC,以及回顾一下Spring MVC的各种用法. Spring MVC简述 关于Spring MVC的介绍网上有很多,这里就不再赘述了,只是要说一下,Spr ...
随机推荐
- zabbix日常问题总结
1.connection to database 'zabbix' failed: [1040] Too many connections 问题:数据库连接池太少解决:增加数据库连接池步骤:(1).进 ...
- 安装MySQL8(附详细图文)
安装MySQL8(附详细图文) 删除mysql服务:mysqld -remove mysql 1.下载 mysql 8 下载地址:https://dev.mysql.com/downloads/mys ...
- [hdu4609]计数方法,FFT
题目:给一个数组a,从里面任选三个数,求以这三个数为三条边能构成三角形的概率. 思路:由于每个数只能用一次,所以考虑枚举三边中的最大边.先将a数组排序,然后枚举它的每个数x作为最大边,那么问题就是要求 ...
- 批量下载B站视频
一个一个下载:https://www.zhihu.com/question/41367609 WSDAB的回答批量下载:https://www.zhihu.com/question/49793759( ...
- Android fragment 使用replace并保存状态
Fragment的地位在开发中可是举足轻重的,掌握它的的生命周期以及使用特性是非常重要的,例如在开发中常使用的模板: 点击菜单,中心内容跟随菜单变化,但是在菜单间切换时,需要保存之前输入的信息或其他状 ...
- TreeSet的两种实现方法:Comparable和Comparator(Java比较器)
Comparable与Comparator实际上是TreeSet集合的两种实现方式,用来实现对象的排序.下边介绍一下两种比较器的使用方法和区别. Comparable称为元素的自然顺序,或者叫做默认顺 ...
- OData武装你的WEBAPI-分页查询
本文属于OData系列 目录 武装你的WEBAPI-OData入门 武装你的WEBAPI-OData便捷查询 武装你的WEBAPI-OData分页查询 武装你的WEBAPI-OData资源更新 武装你 ...
- jenkins 流水线学习
最佳实践: https://www.cnblogs.com/itech/p/5678643.html 一些样例 https://jenkins.io/doc/pipeline/examples/ gi ...
- RabbitMQ及延时队列
一.简介 我用过RabbirMQ的发布订阅模式,以及一对一的延迟队列. 1.RabbitMQ的有消息确认机制,消费一条则队列中少一条,也有对应的消费到消息及认为是消费成功这样的模式,一般使用前者. 发 ...
- 【雕爷学编程】Arduino动手做(48)---三轴ADXL345模块
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践(动手试试)出真知的理念,以学习和交流为目的,这里准备 ...