# 5.错误处理

均在模板引擎FreeMarker下测试

## 一．错误的处理

### 方法一：Spring Boot 将所有的错误默认映射到/error， 实现

![](/files/-LfnTMTeQvCGSOn3sAxR)

①BaseErrorController

```java
package com.demotm.example.controller;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping(value = "error")
public class BaseErrorController implements ErrorController {
    private static final Logger logger = LoggerFactory.getLogger(BaseErrorController.class);

    @Override
    public String getErrorPath() {
    logger.info("出错啦！进入自定义错误控制器");
    return "error/error";
    }

    @RequestMapping
    public String error() {
        return getErrorPath();
    }

}
```

②创建error模板error.ftl

```markup
<!DOCTYPE html>
<html>
<head lang="en">
    <title>Spring Boot Demo - FreeMarker</title>
</head>
<body>
<h1>error-系统出错，请联系后台管理员</h1>
</body>
</html>
```

### 方法二：添加自定义的错误页面

* 2.1 html静态页面：在resources/public/error/ 下定义

  如添加404页面： resources/public/error/404.html页面，中文注意页面编码
* 2.2 模板引擎页面：在templates/error/下定义

  如添加5xx页面： templates/error/5xx.ftl

  注：templates/error/ 这个的优先级比较 resources/public/error/高

src\main\resources\templates\error\5xx.ftl

```markup
<!DOCTYPE html>
<html>
<head lang="en">
    <title>Spring Boot Demo - FreeMarker</title>
</head>
<body>
    <h1>5xx-系统错误</h1>
    <h1>${exception}</h1>
</body>
</html>
```

controller中加入

```java
@RequestMapping(value = "error")
public String error(ModelMap map) {
    throw new RuntimeException("测试异常");
}
```

### 方法三：使用注解@ControllerAdvice

```java
/**
 * 统一异常处理
 * 
 * @param exception
 *            exception
 * @return
 */
@ExceptionHandler({ RuntimeException.class })
@ResponseStatus(HttpStatus.OK)
public ModelAndView processException(RuntimeException exception) {
    logger.info("自定义异常处理-RuntimeException");
    ModelAndView m = new ModelAndView();
    m.addObject("roncooException", exception.getMessage());
    m.setViewName("error/500");
    return m;
}

/**
 * 统一异常处理
 * 
 * @param exception
 *            exception
 * @return
 */
@ExceptionHandler({ Exception.class })
@ResponseStatus(HttpStatus.OK)
public ModelAndView processException(Exception exception) {
    logger.info("自定义异常处理-Exception");
    ModelAndView m = new ModelAndView();
    m.addObject("roncooException", exception.getMessage());
    m.setViewName("error/500");
    return m;
}
```

实例：

![](/files/-LfnTMTmlVkqx9NPbXci)

ErrorExceptionHandler

```java
package com.demotm.example.handler;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;

/**
 * 异常处理类
 *
 * @version 1.0
 */
@ControllerAdvice
public class ErrorExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(ErrorExceptionHandler.class);

    /**
     * 统一异常处理
     *
     * @param exception
     *            exception
     * @return
     */
    @ExceptionHandler({ RuntimeException.class })
    @ResponseStatus(HttpStatus.OK)
    public ModelAndView processException(RuntimeException exception) {
        logger.info("自定义异常处理-RuntimeException");
        ModelAndView m = new ModelAndView();
        m.addObject("roncooException", exception.getMessage());
        m.setViewName("error/500");
        return m;
    }

    /**
     * 统一异常处理
     *
     * @param exception
     *            exception
     * @return
     */
    @ExceptionHandler({ Exception.class })
    @ResponseStatus(HttpStatus.OK)
    public ModelAndView processException(Exception exception) {
        logger.info("自定义异常处理-Exception");
        ModelAndView m = new ModelAndView();
        m.addObject("roncooException", exception.getMessage());
        m.setViewName("error/500");
        return m;
    }

}
```

src\main\resources\templates\error\500.ftl

```markup
<!DOCTYPE html>
<html>
<head lang="en">
    <title>Spring Boot Demo - FreeMarker</title>
</head>
<body>
    <h1>500-系统错误</h1>
    <h1>${exception}</h1>
</body>
</html>
```

备注当Rest风格情况下返回的json，可以参考以下写法

```java
@RestControllerAdvice
public class ExceptionHandlerController {

    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(HttpStatus.OK)
    public Map<String, Object> handleException(RuntimeException exception) {

        Map<String, Object> result = new HashMap<>();
        result.put("result", "fail");
        result.put("errMsg", exception.getMessage());

        return result;
    }


}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://spring-boot.shujuwajue.com/webying-yong-kai-fa/5cuo-wu-chu-li.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
