(6)Spring Boot web开发 --- 错误处理页面
处理时间(Date)类型
Spring Boot 进行参数绑定使用的是 SpringMvc ,涉及 Date 类型的参数绑定的时候,默认是时间格式是 yyyy/MM/dd ,我们可以自定义格式,只需要配置文件里面配置下:
# 日期格式
spring.mvc.date-format=yyyy.MM.dd
thymeleaf 页面拼接字符串
表达式之间直接使用 + 拼接,比如 :@{/emp/} + ${emp.id} ;
映射路径占位符
在映射路径中可以使用占位符的 @GetMapping(/emp/{id}) ;这样参数传入 id 就会被放到
使用 put、delete 方法
表单 仅支持两种方法提交,POST ,GET ;
如果想要使用其他方法,则需要进行一番操作;
SpringMvc配置HiddenHttpMethodFilter(Spring Boot已经自动配置好了,美滋滋);页面创建一个表单
创建一个
input项,type为hidden,·name属性值必须为_method,然后value属性的值,就写我们想要使用的方法:<input type="hidden" name="_method" value="put">
错误处理机制
Spring Boot默认返回一个白板页面;自定义错误响应
定制错误的页面
有模板引擎
将错误页面放在 类路径 的
templates/error文件夹下面,命名为 状态码.html ,这样发生错误的时候,就会去寻找状态码对应的页面;当然这样很傻,那么多状态码,需要写很多页面,因此,还可以直接创建
4xx.html、5xx.html,这样发生404,402,403这些4xx的错误的时候,由于没有对应的页面,就会退而其次,匹配4xx.html页面,5xx也是同样的道理 ;如果
4xx.html、404.html同时存在,这时候发生404错误,会匹配上404.html,精确优先 ;在页面中还可以获取一些信息:
timestamp(时间戳)、status(状态码)、error(错误提示)、exception(异常对象),message(异常消息),errors(JSR303数据校验的错误信息)没有模板引擎
没有模板引擎,就去静态资源文件夹下面,寻找对应的
4xx.html ,5xx.html;以上两种情况都没有
那就莫得选择了,只能使用
Spring Boot的默认错误提示页面 ;
定制错误
JSON自定义异常处理器,使用
@ControllerAdvice标注类,然后在方法上,使用@ExceptionHandler标注要处理什么异常,然后只要发生了对应的异常,该方法就会得到调用,方法参数可以写一些我们自己想要获得的对象;@ControllerAdvice
public class MyExceptionController { @ResponseBody
@ExceptionHandler({UserNotExistException.class})
public Map<String,Object> handlerUserNotExist(Exception e){
Map<String,Object> map = new HashMap<>();
map.put("code","Test Exception");
map.put("message",e.getMessage());
return map ;
}
}方法的返回值,就会被送到页面,但是这样有个缺点,丢失自适应效果(本来浏览器和终端方法,
Spring Boot会显示不同的效果的,浏览器显示 白板错误页面,终端显示JSON串 ),无论是浏览器还是终端,都显示JSON串;进行改动下,转发到
/error炸,就可以自适应了:@ExceptionHandler({UserNotExistException.class})
public String handlerUserNotExistAdaptive(Exception e){
Map<String,Object> map = new HashMap<>();
map.put("code","Test Exception");
map.put("message",e.getMessage());
// 转发到 /error
return "forward:/error" ;
}
但是 又有新问题了:发生异常以后,状态码,就会变成
4xx ,5xx,然后被我上面的方法捕捉到以后,来了一个转发,异常被吞咽了,异常链断掉了,状态码已经变了,变为正常的200,因为转发又没发生异常;虽然转发到
/error,但是状态码已经变了,此时去/error下面,没有对应的页面了,就只能找默认的页面了;因此,我们在转发之前,设置下状态码:
request.setAttribute("javax.servlet.error.status_code",400);,键不是瞎写的,是必须是这个:@ExceptionHandler({UserNotExistException.class})
public String handlerUserNotExistAdaptive(Exception e, HttpServletRequest request){
request.setAttribute("javax.servlet.error.status_code",400);
Map<String,Object> map = new HashMap<>();
map.put("code","Test Exception");
map.put("message",e.getMessage());
// 转发到 /error
return "forward:/error" ;
}
现在还有最后一个问题,我们在转发的时候,带过去的数据,页面其实拿不到的,现在要解决这个问题:
页面上能用的数据,或者
JSON返回能用的数据,其实都是在ErrorAttributes.class类里面的,通过getErrorAttibutes获取的,因此,我们只需要获取到getErrorAttibutes方法的返回值,然后再返回值里面添加上我们自己的数据即可 ;@Component
public class MyErrorAttributes extends DefaultErrorAttributes { @Override
public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, includeStackTrace);
errorAttributes.put("message","Test");
return errorAttributes;
}
}
如果我们在别的地方也有数据想要带到页面,需要向下面这样做:
首先在转发之前,将我们的数据放到域里面;
@ExceptionHandler({UserNotExistException.class})
public String handlerUserNotExistAdaptive(Exception e, HttpServletRequest request){
request.setAttribute("javax.servlet.error.status_code",400); Map<String, Object> myErrorAttributesMap = new HashMap<>();
myErrorAttributesMap.put("message","sasasa");
myErrorAttributesMap.put("code","Test Exception");
request.setAttribute("errorAttributesMap",myErrorAttributesMap); // 转发到 /error
return "forward:/error" ;
}
然后在
getErrorAttibutes方法,从域里面取出来,然后添加到getErrorAttibutes方法的返回值中;
@Override
public Map<String, Object> getErrorAttributes(WebRequest webRequest, boolean includeStackTrace) {
// 数字代表域,0 是 request , 1 是 session ,
Map<String, Object> errorAttributesMap = (Map<String, Object>) webRequest.getAttribute("errorAttributesMap", 0);
Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, includeStackTrace);
errorAttributes.put("message","Test");
errorAttributes.put("error",errorAttributesMap);
return errorAttributes;
}
(6)Spring Boot web开发 --- 错误处理页面的更多相关文章
- Springboot 系列(七)Spring Boot web 开发之异常错误处理机制剖析
前言 相信大家在刚开始体验 Springboot 的时候一定会经常碰到这个页面,也就是访问一个不存在的页面的默认返回页面. 如果是其他客户端请求,如接口测试工具,会默认返回JSON数据. { &quo ...
- Springboot 系列(五)Spring Boot web 开发之静态资源和模版引擎
前言 Spring Boot 天生的适合 web 应用开发,它可以快速的嵌入 Tomcat, Jetty 或 Netty 用于包含一个 HTTP 服务器.且开发十分简单,只需要引入 web 开发所需的 ...
- Springboot 系列(六)Spring Boot web 开发之拦截器和三大组件
1. 拦截器 Springboot 中的 Interceptor 拦截器也就是 mvc 中的拦截器,只是省去了 xml 配置部分.并没有本质的不同,都是通过实现 HandlerInterceptor ...
- 四、Spring Boot Web开发
四.Web开发 1.简介 使用SpringBoot: 1).创建SpringBoot应用,选中我们需要的模块: 2).SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可 ...
- 4.Spring Boot web开发
1.创建一个web模块 (1).创建SpringBoot应用,选中我们需要的模块: (2).SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来 (3).自己编 ...
- Spring Boot Web 开发注解篇
本文提纲 1. spring-boot-starter-web 依赖概述 1.1 spring-boot-starter-web 职责 1.2 spring-boot-starter-web 依赖关系 ...
- (5)Spring Boot web开发 --- Restful CRUD
文章目录 `@RestController` vs `@Controller` 默认访问首页 设置项目名 国际化 登陆 & 拦截 Restful 风格 @RestController vs @ ...
- spring boot系列(二)spring boot web开发
json 接口开发 在以前的spring 开发的时候需要我们提供json接口的时候需要做如下配置: 1 添加jackjson等jar包 2 配置spring controller扫描 3 对接的方法添 ...
- Spring Boot Web 开发@Controller @RestController 使用教程
在 Spring Boot 中,@Controller 注解是专门用于处理 Http 请求处理的,是以 MVC 为核心的设计思想的控制层.@RestController 则是 @Controller ...
随机推荐
- ubuntu16.04解决文件中文乱码问题
1.查看当前系统使用的字符编码 ~$ locale LANG=en_US LANGUAGE=en_US: LC_CTYPE="en_US" LC_NUMERIC="en_ ...
- 数据库blob图片文件,多图片打包下载
数据库存储blob图片文件,前端打包下载 数据库图片文件实体类 package com.cmrh.mspserver.pos.dto; import java.io.Serializable; imp ...
- vim 文本替换讲解
在VIM中进行文本替换: 1. 替换当前行中的内容: :s/from/to/ (s即substitude) :s/from/to/ : 将当前行中的第一个from,替换成to.如果当前行含有多个 fr ...
- Java设计模式之三建造者模式和原型模式
建造者模式 简介 建造者模式是属于创建型模式.建造者模式使用多个简单的对象一步一步构建成一个复杂的对象.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式.简单的来说就是将一个复杂的东西 ...
- Assignment3:白盒测试以及测试框架简介
一. 白盒测试简介 白盒测试又称结构测试.透明盒测试.逻辑驱动测试或基于代码的测试.白盒测试是一种测试用例设计方法,盒子指的是被测试的软件,白盒指的是盒子是可视的,你清楚盒子内部的东西以及 ...
- Binder 原理剖析***
一. 前言 希望更加深入理解 Binder 实现机制的,可以阅读文末的参考资料以及相关源码. 二. Binder 概述 简单介绍下什么是 Binder.Binder 是一种进程间通信机制,基于开源的 ...
- Python中if __name__ == '__main__':的作用和原理
if __name__ == '__main__':的作用 一个python文件通常有两种使用方法,第一是作为脚本直接执行,第二是 import 到其他的 python 脚本中被调用(模块重用)执行. ...
- (转)golang获取当前时间、时间戳和时间字符串及它们之间的相互转换
原文连接: https://blog.csdn.net/skh2015java/article/details/70051512 1.获取当前时间 currentTime:=time.Now() // ...
- Spring中好玩的注解和接口
测试中: 一.unit中集中基本注解,是必须掌握的. @BeforeClass – 表示在类中的任意public static void方法执行之前执行 @AfterClass – 表示在类中的任意p ...
- ES6深入浅出-6 ES 6 模块-1.模块化速学
把模块先默认认为是豆腐块 为什么前端需要模块? 没有模块的方式 预览这个html页面 一共200行js代码 前100行在做一件事 ,另外100行在做另一件事,这样就是两个模块 main.js来 ...