上篇文章我们讲解了使用Hibernate Validation来校验数据,当校验完数据后,如果发生错误我们需要给客户返回一个错误信息,因此这节我们来讲解一下SpringBoot默认的错误处理机制以及如何自定义异常来处理请求错误。
一、SpringBoot默认的错误处理机制
我们在发送一个请求的时候,如果发生404 SpringBoot会怎么处理呢?我们来发送一个不存在的请求来验证一下看看页面结果。如下所示:
当服务器内部发生错误的时候,页面会返回什么呢?
@GetMapping("/user/{id:\\d+}") public User get(@PathVariable String id) { throw new RuntimeException(); }
我们会发现无论是发生什么错误,SpringBoot都会返回一个状态码以及一个错误页面,这个错误页面是怎么来的呢?
我们来看看SpringBoot错误处理模块的源码就会非常清楚,默认的发生错误,它会将请求转发到BasicErrorController控制器来处理请求,下面是该controller类的源码:
@Controller @RequestMapping("${server.error.path:${error.path:/error}}") public class BasicErrorController extends AbstractErrorController { private final ErrorProperties errorProperties; /** * Create a new {@link BasicErrorController} instance. * @param errorAttributes the error attributes * @param errorProperties configuration properties */ public BasicErrorController(ErrorAttributes errorAttributes, ErrorProperties errorProperties) { this(errorAttributes, errorProperties, Collections.<ErrorViewResolver>emptyList()); } /** * Create a new {@link BasicErrorController} instance. * @param errorAttributes the error attributes * @param errorProperties configuration properties * @param errorViewResolvers error view resolvers */ public BasicErrorController(ErrorAttributes errorAttributes, ErrorProperties errorProperties, List<ErrorViewResolver> errorViewResolvers) { super(errorAttributes, errorViewResolvers); Assert.notNull(errorProperties, "ErrorProperties must not be null"); this.errorProperties = errorProperties; } @Override public String getErrorPath() { return this.errorProperties.getPath(); } @RequestMapping(produces = "text/html") public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) { HttpStatus status = getStatus(request); Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes( request, isIncludeStackTrace(request, MediaType.TEXT_HTML))); response.setStatus(status.value()); ModelAndView modelAndView = resolveErrorView(request, response, status, model); return (modelAndView == null ? new ModelAndView("error", model) : modelAndView); } @RequestMapping @ResponseBody public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) { Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.ALL)); HttpStatus status = getStatus(request); return new ResponseEntity<Map<String, Object>>(body, status); }
从上面的源码我们可以看到,它有两个RequestMapping方法来映射错误请求,为什么会是两个呢?其实errorHtml方法映射的是浏览器发送来的请求,而error方法映射的是不是浏览器而是其他软件app客户端发送的错误请求。
看了上面的源码后,我们是否可以自己定义404或者500的错误页面返回给客户端呢?当然可以,我们可以在src/main/resources路径下新建文件夹reources/error文件夹,然后新建404.html和500.html然后编写自己的错误内容即可:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>404</title> </head> <body> 亲,您所访问的页面不存在 </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>500</title> </head> <body> 服务器内部错误 </body> </html>
不过注意的是上面的这种自定义页面的方式只在浏览器端有效,而不是浏览器发送的请求不会生效。因此下面我们就讲一下如何自定义异常处理来解决这个问题。
二、自定义异常处理
怎么自定义异常处理客户端发送的错误信息呢?如果我们查询一个用户,该用户不存在,我们是否可以将不存在的用户的id返回给客户呢?这样的效果不是给客户更好地体验吗?下面我们来实现这个功能。
首先我们需要编写一个exception类继承RuntimeException类:
package cn.shinelon.exception; /** * @author Shinelon * */ public class UserNotExistException extends RuntimeException{ /** * */ private static final long serialVersionUID = 1L; private String id; public UserNotExistException(String id) { super("user not exist"); this.id=id; } public void setId(String id) { this.id = id; } public String getId() { return id; } }
接着我们需要编写一个handler类处理controller层抛出的异常:
/** * */ package cn.shinelon.exception; import java.util.HashMap; import java.util.Map; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; /** * 控制器的异常处理类 * @author Shinelon * */ //这个注解是指这个类是处理其他controller抛出的异常 @ControllerAdvice public class ControllerExceptionHandler { //这个注解是指当controller中抛出这个指定的异常类的时候,都会转到这个方法中来处理异常 @ExceptionHandler(UserNotExistException.class) //将返回的值转成json格式的数据 @ResponseBody //返回的状态码 @ResponseStatus(value=HttpStatus.INTERNAL_SERVER_ERROR) //服务内部错误 public Map<String,Object> handlerUserNotExistException(UserNotExistException ex){ Map<String,Object> result=new HashMap<String,Object>(); result.put("id", ex.getId()); result.put("message", ex.getMessage()); return result; } }
这个类加上@ControllerAdvice注解将会处理controller层抛出的对应的异常,这里我们处理controller抛出的UserNotExistException自定义异常,并且将错误信息以及用户id以json串的格式返回给客户。
接着,我们在controller的请求方法中抛出这个异常,会看到在浏览器中的异常是我们自定义的异常返回的json数据。
Controller层代码:
@GetMapping("/user/{id:\\d+}") //@RequestMapping(value="/user/{id:\\d+}",method=RequestMethod.GET) @JsonView(User.DetailJsonView.class) public User get(@PathVariable String id) { throw new UserNotExistException(id); }
到这里,我们就介绍了SpringBoot默认的错误处理机制以及我们自定义异常来处理错误请求,这更有利于我们的开发,带给用户更佳的使用效果。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍SpringBoot 错误处理机制与自定义错误处理实现详解,包括了SpringBoot 错误处理机制与自定义错误处理实现详解的使用技巧和注意事项,需要的朋友参考一下 【1】SpringBoot的默认错误处理 ① 浏览器访问 请求头如下: ② 使用“PostMan”访问 请求头如下: 总结:如果是浏览器访问,则SpringBoot默认返回错误页面;如果是其他客户端访问,则默认返回JSO
本文向大家介绍ASP.NET MVC中异常处理&自定义错误页详析,包括了ASP.NET MVC中异常处理&自定义错误页详析的使用技巧和注意事项,需要的朋友参考一下 一、应用场景 对于B/S应用程序,在部署到正式环境运行的过程中,很有可能出现一些在前期测试过程中没有发现的一些异常或者错误,或者说只有在特定条件满足时才会发生的一些异常,对于使用ASP.NET MVC开发的应用程序站点,在部署到IIS上
所有的错误最终都会被 Tango.ErrHandler 进行处理。 你可以自定义你的错误处理方式来替代默认的。例如: var ( prefix = "<html><head>tango</head><body><div>" suffix = fmt.Sprintf("</div><div>version: %s</div></body></html>", tango.Version
404和500错误客户端和服务端都会通过error.js组件处理。如果你想改写它,则新建_error.js在文件夹中: import React from 'react' export default class Error extends React.Component { static getInitialProps({ res, err }) { const statusCod
本文向大家介绍springboot全局异常处理详解,包括了springboot全局异常处理详解的使用技巧和注意事项,需要的朋友参考一下 一、单个controller范围的异常处理 说明: 在controller中加入被@ExceptionHandler修饰的类即可(在该注解中指定该方法需要处理的那些异常类) 该异常处理方法只在当前的controller中起作用 二、全部controller范围内起
当程序出现错误或者异常时,我们一般会希望在开发时输出报错信息,在生产环境时隐藏详细的信息。 在 imi 中,提供了 Http 服务的错误异常默认处理器支持。 默认 Http 错误处理器:Imi\Server\Http\Error\JsonErrorHandler 指定默认处理器 配置文件中: return [ 'beans' => [ 'HttpErrorHan