
这种错误交给前端无法处理。
- 需要自定义一些错误响应类给前端
 
package cn.yam.bloomfilter.exception;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import java.util.HashMap;
import java.util.Map;
@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public ResponseEntity<Map<String, Object>> handleAllExceptions(Exception ex) {
        Map<String, Object> response = new HashMap<>();
        response.put("status", HttpStatus.INTERNAL_SERVER_ERROR.value());
        response.put("message", "服务器内部错误");
        return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
 
- 创建一个全局异常处理类。
 - 使用 
@ControllerAdvice和@ExceptionHandler注解。| - 定义返回 JSON 格式的错误响应
 
处理完成之后,就变成如下图所示。

如何自定义发现的异常
以请求参数错误为例子:
- 定义一个 异常类
InvalidParameterException 
package cn.yam.bloomfilter.exception;
public class InvalidParameterException extends RuntimeException {
    public InvalidParameterException(String message) {
        super(message);
    }
}
 
- 抛出
 
@RestController
@RequestMapping("/api/users")
public class UserController {
    @Autowired
    private UserService userService;
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userService.getUserById(id);
        if (user == null) {
            throw new InvalidParameterException("用户ID: " + id);
        }
        return ResponseEntity.ok(user);
    }
}
 
- 全局异常异常处理器
 
package cn.yam.bloomfilter.exception;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap;
import java.util.Map;
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(InvalidParameterException.class)
    public ResponseEntity<Map<String, Object>> handleInvalidParameterException(InvalidParameterException ex) {
        Map<String, Object> response = new HashMap<>();
        response.put("status", HttpStatus.BAD_REQUEST.value());
        response.put("message", "参数错误: " + ex.getMessage());
        return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
    }
}
 
探究 ResponseEntity作用
 
场景描述
假设我们有一个 /resource/{id} 接口,用于根据 ID 查找资源。如果资源不存在,返回 404 Not Found 和错误信息;如果资源存在,返回 200 OK 和资源数据。
- 不加 
ResponseEntity的例子 
package cn.yam.bloomfilter.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class ResourceController {
    @GetMapping("/resource/{id}")
    public Map<String, Object> getResource(@PathVariable int id) {
        Map<String, Object> response = new HashMap<>();
        // 模拟资源查找
        if (id == 1) {
            response.put("data", "Resource Data");
        } else {
            response.put("status", 404);
            response.put("message", "资源未找到");
        }
        return response;
    }
}
 
测试结果
- 请求 
/resource/1:- 响应体:
 
 
{
  "data": "Resource Data"
}
 
- 状态码: `200 OK`(默认状态码)
 
- 请求 
/resource/2:- 响应体:
 
 
{
  "status": 404,
  "message": "资源未找到"
}
 
- 状态码: `200 OK`(默认状态码)
 
问题
- 即使资源未找到,状态码仍然是 
200 OK,这不符合 RESTful API 的设计规范。 - 客户端无法通过状态码快速判断请求是否成功。
 
- 加 
ResponseEntity的例子 
package cn.yam.bloomfilter.controller;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class ResourceController {
    @GetMapping("/resource/{id}")
    public ResponseEntity<Map<String, Object>> getResource(@PathVariable int id) {
        Map<String, Object> response = new HashMap<>();
        // 模拟资源查找
        if (id == 1) {
            response.put("data", "Resource Data");
            return new ResponseEntity<>(response, HttpStatus.OK);
        } else {
            response.put("status", 404);
            response.put("message", "资源未找到");
            return new ResponseEntity<>(response, HttpStatus.NOT_FOUND);
        }
    }
}
 
测试结果
- 请求 
/resource/1:- 响应体:
 
 
{
  "data": "Resource Data"
}
 
- 状态码: `200 OK`
 
- 请求 
/resource/2:- 响应体:
 
 
{
  "status": 404,
  "message": "资源未找到"
}
 
- 状态码: `404 Not Found`
 
优点
- 状态码和响应体都符合 RESTful API 的设计规范。
 - 客户端可以通过状态码快速判断请求是否成功。
 
- 对比总结
 
| 特性 | **不加 **ResponseEntity | **加 **ResponseEntity | 
|---|---|---|
| 状态码控制 | 无法动态设置状态码,默认返回 200 OK。 | 可以动态设置状态码(如 200 OK、404 Not Found)。 | 
| 响应体 | 可以返回自定义 JSON 数据。 | 可以返回自定义 JSON 数据。 | 
| 是否符合 RESTful 规范 | 不符合,状态码无法反映实际错误。 | 符合,状态码和响应体都能正确反映请求结果。 | 
| 客户端处理 | 客户端需要解析响应体才能判断是否出错。 | 客户端可以通过状态码快速判断是否出错。 | 

常见异常总结:
- 参数错误
 
// 访问的是http://localhost:8080/api/users/id
// id 默认是1-5 ,测试访问http://localhost:8080/api/users/999
 
- 定义
InvalidParameterException异常类 
package cn.yam.bloomfilter.exception;
public class InvalidParameterException extends RuntimeException {
    public InvalidParameterException(String message) {
        super(message);
    }
}
 
- 在控制层抛出
InvalidParameterException 
@RestController
@RequestMapping("/api/users")
public class UserController {
    @Autowired
    private UserService userService;
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userService.getUserById(id);
        if (user == null) {
            throw new InvalidParameterException("用户ID: " + id);
        }
        return ResponseEntity.ok(user);
    }
}
 
- 在全局异常拦截类中拦截
 
package cn.yam.bloomfilter.exception;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap;
import java.util.Map;
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public Object handleAllExceptions(Exception ex) {
        Map<String, Object> response = new HashMap<>();
        response.put("status", HttpStatus.INTERNAL_SERVER_ERROR.value());
        response.put("message", ex.getMessage());
        return response;
    }
    @ExceptionHandler(InvalidParameterException.class)
    public ResponseEntity<Map<String, Object>> handleInvalidParameterException(InvalidParameterException ex) {
        Map<String, Object> response = new HashMap<>();
        response.put("status", HttpStatus.BAD_REQUEST.value());
        response.put("message", "参数错误: " + ex.getMessage());
        return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST);
    }
}
 

- 路径匹配错误
 
// 访问的是http://localhost:8080/ap##??djjd
 
- 补充 
yml配置 
spring:
  mvc:
    throw-exception-if-no-handler-found: true
  web:
    resources:
      add-mappings: false
 

- 用来兜底处理所有未被特定异常处理器捕获的异常。
 
package cn.yam.bloomfilter.exception;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.http.ResponseEntity;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.HashMap;
import java.util.Map;
@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    public Object handleAllExceptions(Exception ex) {
        Map<String, Object> response = new HashMap<>();
        response.put("status", HttpStatus.INTERNAL_SERVER_ERROR.value());
        response.put("message", ex.getMessage());
        return response;
    }
}
                


















