知识库 知识库
首页
  • Hyperskill - Java

    • Java basic
    • Java OOP
    • 应知
    • 扩展
    • IO & Stream
    • Error & Exception
    • Algorithm & Data structure
    • Design pattern
    • Web
    • Spring boot
  • 练习题

    • 选择题 & 填空题
    • 代码题
  • Frank - Java与生活 (OOP)

    • 参考资料
    • Java基础
    • OOP上半部分
    • OOP下半部分
  • Frank - Java API进阶

    • Base API
    • Unit Test and main function
  • 学习笔记
  • 学习笔记

    • 数据库
  • Frank - MySQL删库跑路

    • 安装、连接、配置
    • 基本操作——数据库
    • 基本操作——表
    • 基本操作——数据
    • 数据类型
    • 列属性完整性
    • 数据库设计思维
    • 单表查询
    • 多表查询
  • 学习笔记

    • 其它
  • Frank - Linux现代方法

    • 必知
    • 命令
    • 技巧
  • 技术文档
  • Git
  • GitHub技巧
  • 前端
  • Khan Academy - 语法
  • Monthly
  • 阅读
  • Others
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 标签
  • 归档
GitHub (opens new window)

Jim FuckPPT

Java小学生
首页
  • Hyperskill - Java

    • Java basic
    • Java OOP
    • 应知
    • 扩展
    • IO & Stream
    • Error & Exception
    • Algorithm & Data structure
    • Design pattern
    • Web
    • Spring boot
  • 练习题

    • 选择题 & 填空题
    • 代码题
  • Frank - Java与生活 (OOP)

    • 参考资料
    • Java基础
    • OOP上半部分
    • OOP下半部分
  • Frank - Java API进阶

    • Base API
    • Unit Test and main function
  • 学习笔记
  • 学习笔记

    • 数据库
  • Frank - MySQL删库跑路

    • 安装、连接、配置
    • 基本操作——数据库
    • 基本操作——表
    • 基本操作——数据
    • 数据类型
    • 列属性完整性
    • 数据库设计思维
    • 单表查询
    • 多表查询
  • 学习笔记

    • 其它
  • Frank - Linux现代方法

    • 必知
    • 命令
    • 技巧
  • 技术文档
  • Git
  • GitHub技巧
  • 前端
  • Khan Academy - 语法
  • Monthly
  • 阅读
  • Others
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
收藏
  • 标签
  • 归档
GitHub (opens new window)
  • Hyperskill - Java

    • Java basic

    • Java OOP

    • 应知

    • 扩展

    • IO & Stream

    • Error & Exception

    • Algorithm & Data structure

    • Design pattern

    • Web

      • Theory:World Wide Web
      • Theory:HTTP
      • Theory:HTTP URL
      • Theory:HTTP messages
      • Theory:MVC
      • Theory:Introduction to Spring Web MVC
      • Theory:REST
      • Theory:Postman
      • Theory:Getting data from REST
      • Theory:Posting and deleting data via REST
      • Theory:REST Exception handling
        • Controller preparation
        • ResponseStatusException
        • Custom exceptions
        • Conclusion
      • Theory:Handling requests with bodies
      • Theory:Domains
      • Theory:HTTP Basic Auth
      • Theory:IP
      • Theory:Authentication and Authorization
      • Theory:OAuth
      • Theory:Java 11 HTTP client
    • Spring boot

  • 练习题

  • Frank - Java与生活

  • Frank - Java API进阶

  • 学习笔记

  • Java
  • Hyperskill - Java
  • Web
Jim
2022-08-01
目录

Theory:REST Exception handling

Returning errors to a user is crucial during web application development. When users send an incorrect request that cannot be processed or want to get information on a non-existing object, your web application should let them know what is wrong. There are different general HTTP status codes, for example, 400 for Bad Request or 404 for Not Found. Handling errors is very important, as it allows users to understand what is wrong right away.

Here you will find two ways to return an error message in Spring Boot applications. You can either use the ResponseStatusException Spring class or create your own exception using the @ResponseStatus annotation. Let's write a simple code and show how it works.

# Controller preparation

Imagine a web app that returns information about a flight by its number. It would look like this in JSON:

{
  "id" : 3,
  "from": "Berlin Tegel",
  "to": "Stuttgart",
  "gate": "D80"
}
1
2
3
4
5
6

In the example below, we create a simple FlightInfo class with information about the airport, city, and gate. We do not provide the flight date and time for the sake of brevity:

public class FlightInfo {

    private int id;
    private String from;
    private String to;
    private String gate;
 
    // constructor
 
    // getters and setters
 
}
1
2
3
4
5
6
7
8
9
10
11
12

Now we can implement a simple FlightController controller with a list of flights. We will also use a method that returns a FlightInfo object from the flightInfoList list to get information about the specific flight:

@RestController
public class FlightController {

    private final List<FlightInfo> flightInfoList = new ArrayList<>();

    public FlightController() {
        flightInfoList.add(
                new FlightInfo(1, "Delhi Indira Gandhi", "Stuttgart", "D80"));
        flightInfoList.add(
                new FlightInfo(2, "Tokyo Haneda", "Frankfurt", "110"));
        flightInfoList.add(
                new FlightInfo(3, "Berlin Schönefeld", "Tenerife", "15"));
        flightInfoList.add(
                new FlightInfo(4, "Kilimanjaro Arusha", "Boston", "15"));
    }

    @GetMapping("flights/{id}")
    public FlightInfo getFlightInfo(@PathVariable int id) {
        for (FlightInfo flightInfo : flightInfoList) {
            if (flightInfo.getId() == id) {
                return flightInfo;
            }
        }
        throw new RuntimeException();
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

Finally, we are ready to focus on handling exceptions!

# ResponseStatusException

The first way to return an error is to use the ResponseStatusException class introduced in Spring 5 for basic error handling as part of org.springframework.web.server package. It's RuntimeException and that's why we don't need to add it to a method signature.

There are three constructors in Spring to generate ResponseStatusException:

ResponseStatusException(HttpStatus status)
ResponseStatusException(HttpStatus status, java.lang.String reason)
ResponseStatusException(
        HttpStatus status, 
        java.lang.String reason, 
        java.lang.Throwable cause
)
1
2
3
4
5
6
7

We have created an instance providing HttpStatus and, optionally, the reason and cause. The reason is a simple message that explains the exception. The cause is a nested exception.

So, what HttpStatus types are there? The most common are 200 OK, 404 NOT_FOUND, 400 BAD_REQUEST, 403 FORBIDDEN, and 500 INTERNAL_SERVER_ERROR.

Let's change our getFlightInfo method and write a code that generates an instance of ResponseStatusException. Let's say users are looking for some information about a flight from the Berlin Schönefeld airport, but the airport is closed for maintenance. In this situation, we should return ResponseStatusException with BAD_REQUEST status and reason message:

@GetMapping("flights/{id}")
public static FlightInfo getFlightInfo(@PathVariable int id) {
    for (FlightInfo flightInfo : flightInfoList) {
        if (flightInfo.getId() == id) {
            if (Objects.equals(flightInfo.getFrom(), "Berlin Schönefeld")) {
                throw new ResponseStatusException(HttpStatus.BAD_REQUEST, 
                        "Berlin Schönefeld is closed for service today");
            } else {
                return flightInfo;
            }
        }
    }

    throw new RuntimeException();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

If we try to test it, we will see the standard error info format as a response:

img

This JSON instance provides more information about the situation than a specified message — the timestamp, error name, status code, and the REST path of the request.

注意

By default, Spring Boot doesn't include the message field in a response. To enable it, add this line in the application.properties file: server.error.include-message=always

Let's talk about the pros and cons of ResponseStatusException.

It has many benefits, allowing us to:

  • process exceptions of the same type separately;
  • set different status codes for the response;
  • avoid creating any additional exception classes;
  • throw an exception at any place;

The disadvantage is the code duplication since we have to write the same code in several controllers.

注意

If your application throws an uncaught exception like RuntimeException or any other that doesn't have explicit details on the HTTP code, it will be converted to 500 Internal Server Error. This status code indicates that something is bad with your server, and it should be fixed because the user requests cannot be processed properly.

# Custom exceptions

It is also possible to set the response code and status for the custom exception. We can write a class that extends RuntimeException and add the @ResponseStatus annotation to the exception like this:

@ResponseStatus(code = HttpStatus.BAD_REQUEST)
class FlightNotFoundException extends RuntimeException {
    
    public FlightNotFoundException(String cause) {
        super(cause);
    }
}
1
2
3
4
5
6
7

Now, we can throw this exception in the same way as ResponseStatusException. The status will be set automatically.

For example, in the flight controller:

@GetMapping("flights/{id}")
public FlightInfo getFlightInfo(@PathVariable int id) {
    for (FlightInfo flightInfo : flightInfoList) {
        if (flightInfo.getId() == id) {
            return flightInfo;
        }
    }

    throw new FlightNotFoundException("Flight not found for id =" + id);
}
1
2
3
4
5
6
7
8
9
10

If we test this exception with a nonexistent id=1111, we get a response with the new status code 400.

img

The main advantage is that we can create our own specific exceptions and keep our code more readable.

On the other hand, custom exceptions require implementing additional classes.

# Conclusion

Remember that bad exception processing may result in bugs and low readability. We have considered two ways of handling exceptions in Spring. Now you can:

  • throw ResponseStatusException
  • create custom exceptions using the @ResponseStatus annotation and throw them like ResponseStatusException

Each way has its advantages and disadvantages. Use the second option for specific exceptions or the first one to avoid additional exception classes.

编辑 (opens new window)
#REST#Exception#Spring boot
上次更新: 2022/10/12, 17:01:25
Theory:Posting and deleting data via REST
Theory:Handling requests with bodies

← Theory:Posting and deleting data via REST Theory:Handling requests with bodies→

最近更新
01
《挪威的森林》
04-14
02
青钢影
04-14
03
Processing strings
02-18
更多文章>
Theme by Vdoing | Copyright © 2022-2023 Jim Frank | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式