Abstruct
The three methods of exception handling in SpringBoot are described below.
- How to handle exceptions for each Controller
- How to handle exceptions across all Controllers
- How to handle exceptions by implementing ErrorController
1. How to handle exceptions for each Controller
The Point is @ExceptionHandler(Pattern1Exception.class)
.
1.1. Pattern1Exception
1
2
3
4
5
|
public class Pattern1Exception extends Exception{
public Pattern1Exception(String msg){
super(msg);
}
}
|
1.2. Pattern1RestController
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
|
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class Pattern1RestController {
@RequestMapping("/pattern1")
public String test() throws Pattern1Exception {
throwExceptionMethod();
return "ok";
}
private void throwExceptionMethod() throws Pattern1Exception {
throw new Pattern1Exception("pattern1");
}
@ExceptionHandler(Pattern1Exception.class)
public String pattern1ExceptionHandle(Pattern1Exception e) {
log.error("pattern1 exception handle : ", e);
return "ng";
}
}
|
2. How to handle exceptions across all Controllers
The Point is @RestControllerAdvice
and @ExceptionHandler(Pattern2Exception.class)
.
2.1. Pattern2ControllerAdvice
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
@Slf4j
public class Pattern2ControllerAdvice {
@ExceptionHandler(Pattern2Exception.class)
public String pattern2ExceptionHandle(Pattern2Exception e) {
log.error("pattern2 exception handle : ", e);
return "ng";
}
}
|
2.2. Pattern2Exception
1
2
3
4
5
|
public class Pattern2Exception extends Exception{
public Pattern2Exception(String msg){
super(msg);
}
}
|
2.3. Pattern2RestController1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class Pattern2RestController1 {
@RequestMapping("/pattern2-1")
public String test() throws Pattern2Exception {
throwExceptionMethod();
return "ok";
}
private void throwExceptionMethod() throws Pattern2Exception {
throw new Pattern2Exception("pattern2-1");
}
}
|
2.4. Pattern2RestController2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class Pattern2RestController2 {
@RequestMapping("/pattern2-2")
public String test() throws Pattern2Exception {
throwExceptionMethod();
return "ok";
}
private void throwExceptionMethod() throws Pattern2Exception {
throw new Pattern2Exception("pattern2-2");
}
}
|
3. How to handle exceptions by implementing ErrorController
BasicErrorController.java was used as a reference.
The points are as follows.
implements ErrorController
public ResponseEntity<String> error(HttpServletRequest request)
- for http request (@RestController)
public ModelAndView errorHtml(HttpServletRequest req, ModelAndView mav)
- for http page (@Controller)
3.1. MyBasicErrorController
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController;
import org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorViewResolver;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class MyBasicErrorController implements ErrorController {
@RequestMapping
public ResponseEntity<String> error(HttpServletRequest request) {
var returnData = "my basic error controller";
return new ResponseEntity<>(returnData, HttpStatus.BAD_REQUEST);
}
@RequestMapping
public ModelAndView errorHtml(HttpServletRequest req, ModelAndView mav) {
log.error("MyErrorController : RequestURL = {}", req.getRequestURL());
mav.setStatus(HttpStatus.NOT_FOUND);
// Thymeleaf template src/main/resources/templates/error.html
mav.setViewName("error");
return mav;
}
@Override
public String getErrorPath() {
return "/error";
}
}
|
3.2. Pattern3Exception
1
2
3
4
5
|
public class Pattern3Exception extends Exception{
public Pattern3Exception(String msg){
super(msg);
}
}
|
3.3. Pattern3RestController
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class Pattern3RestController {
@RequestMapping("/pattern3")
public String test() throws Pattern3Exception {
throwExceptionMethod();
return "ok";
}
private void throwExceptionMethod() throws Pattern3Exception {
throw new Pattern3Exception("pattern3");
}
}
|
4. build.gradle
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
28
29
30
31
32
33
|
plugins {
id 'org.springframework.boot' version '2.4.1'
id 'io.spring.dependency-management' version '1.0.10.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// for thymeleaf
compile "org.springframework.boot:spring-boot-starter-thymeleaf"
}
test {
useJUnitPlatform()
}
|
5. Reference