知识点

  • 处理文件上传
  • 使用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高级技术的更多相关文章

  1. 【Spring】Spring MVC高级技术

    前言 前面学习了简单的Spring Web知识,接着学习更高阶的Web技术. 高级技术 Spring MVC配置的替换方案 自定义DispatcherServlet配置 在第五章我们曾编写过如下代码. ...

  2. Spring学习(七)--Spring MVC的高级技术

    一.Spring MVC配置的替代方案 我们已经了解如何通过AbstractAnnotationConfigDispatcherServlet- Initializer快速搭建了Spring MVC环 ...

  3. Spring系列(七) Spring MVC 异常处理

    Servlet传统异常处理 Servlet规范规定了当web应用发生异常时必须能够指明, 并确定了该如何处理, 规定了错误信息应该包含的内容和展示页面的方式.(详细可以参考servlet规范文档) 处 ...

  4. Spring MVC(3)Spring MVC 高级应用

    一.Spring MVC 的数据转换和格式化 前面的应用,都只是用HandlerAdapter去执行处理器. 处理器和控制器不是一个概念,处理器是在控制器功能的基础上加上了一层包装,有了这层包装,在H ...

  5. 第七篇 .NET高级技术之关于相等 Equals

    查看判断两个对象是否是同一个对象要用:object.ReferenceEquals(); 因为“==”默认值是比较两个对象是不是同一个对象.所以有时候两个对象的内容相等,但是比较后还是false. O ...

  6. spring入门(七) spring mvc+mybatis+generator

    1.Mybatis-Generator下载 地址:https://github.com/mybatis/generator/releases 我使用的是 mybatis-generator-core- ...

  7. spring-mvc高级技术

    Spring MVC高级技术包括但不限于web.xml配置.异常处理.跨重定向请求传递数据 1.web.xml文件的配置 <!DOCTYPE web-app PUBLIC "-//Su ...

  8. spring MVC框架入门(外加SSM整合)

    spring MVC框架 一.什么是sping MVC Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 W ...

  9. Java方式配置Spring MVC

    概述 使用Java方式配置Spring MVC,以及回顾一下Spring MVC的各种用法. Spring MVC简述 关于Spring MVC的介绍网上有很多,这里就不再赘述了,只是要说一下,Spr ...

随机推荐

  1. Android | 带你零代码实现安卓扫码功能

    目录 小序 背景介绍 前期准备 开始搬运 结语 小序   这是一篇纯新手教学,本人之前没有任何安卓开发经验(尴尬),本文也不涉及任何代码就可以使用一个扫码demo,华为scankit真是新手的福音-- ...

  2. Web 组态运用之用户数据 ARPU 分析图

    前言 作为企业的发展,通过运营的有效管理,增加收入.降低成本,取得更好的经济效益,是核心所在,在电信企业同样如此.电信企业的利润大体上是由业务收入和成本决定的,而收入和成本又可进一步分别分解表达为不同 ...

  3. 戴尔服务器ipmi报错

    戴尔服务器ipmi配置完成,用浏览器打开报错 查看器已终止,网络已中断 原因:这个问题是java报错,用火狐打开报错 解决方法: 用IE打开就没问题,IE要用较高版本的,楼主的是win10-IE11

  4. Java 函数式接口

    目录 Java 函数式接口 1. 函数式接口 1.1 概念 1.2 格式 1.3 函数式接口的使用 2. 函数式编程 2.1 Lambda的延迟执行 性能浪费的日志案例 使用Lambda表达式的优化 ...

  5. 10_CSS入门和高级技巧(8)

    图片透明 先来复习一下盒子的透明问题: opacity:0.6; 介于0~1之间,为了让IE兼容,我们要使用IE自己的滤镜: filter:alpha(opacity=60); 盒子的透明,会让里面的 ...

  6. iOS开发--性能调优记录

    CPU VS GPU 关于绘图和动画有两种处理的方式:CPU(中央处理器)和GPU(图形处理器).但是由于历史原因,我们可以说CPU所做的工作都在软件层面,而GPU在硬件层面 对于图像处理,通常用硬件 ...

  7. [c++ IO加速]快速输入输出

    自己封装的FastIO类,效率虽有所损失,不过实用性提高很多. 测试,写10000000个整数(86M): printf 2.7s cout 27s FastIO 1s 测试,读10000000个整数 ...

  8. [hdu5316]线段树

    题意:给一个array,有两种操作,(1)修改某一个位置的值,(2)询问区间[L,R]内的最大子段和,其中子段需满足相邻两个数的位置的奇偶性不同 思路:假设对于询问操作没有奇偶性的限制,那么记录区间的 ...

  9. 🏃‍♀️点亮你的Vue技术栈,万字Nuxt.js实践笔记来了~

    前言 作为一位 Vuer(vue开发者),如果还不会这个框架,那么你的 Vue 技术栈还没被点亮. Nuxt.js 是什么 Nuxt.js 官方介绍: Nuxt.js 是一个基于 Vue.js 的通用 ...

  10. java学习笔记之原型模式及深浅拷贝

    一.原型模式的基本介绍 在聊原型模式之前,我们来思考一个小问题,传统的方式我们是如何克隆对象呢? 那我们以多利羊(Sheep)为例,来说明上述这个问题,具体代码见下面: 多利羊(Sheep) publ ...