Spring ContollerAdvice 没有将正文添加到返回的错误中
Spring ContollerAdvice does not add body to returned error
我是 spring 的新手,我正在尝试了解全局异常处理。我想在这里实现的是当使用不存在的主键发出请求时,我想 return 一个 HTTP_NO_CONTENT 正文包括时间戳和给定的所述请求的 id。
这是我的控制器建议
@ControllerAdvice
public class ControllerAdvisor {
@ExceptionHandler(NoLevelFoundException.class)
public ResponseEntity<ResponseBody> handleNoLevelFoundException( NoLevelFoundException ex) {
ex.printStackTrace();
ResponseBody error = new ResponseBody();
error.setTime(Timestamp.from(Instant.now()));
error.setMessage(ex.getMessage());
return new ResponseEntity<>(error, HttpStatus.NO_CONTENT);
}
}
这些是我的自定义异常和 respondBody
public class NoLevelFoundException extends RuntimeException{
public NoLevelFoundException(int id) {
super("No level with id " + id + " found!");
}
}
public class ResponseBody {
private Timestamp time;
private String message;
...
}
当我通过邮递员向一个不存在的项目发出请求时,我收到了这个。
使用 return ResponseEntity.noContent().build();
我仍然得到正确的状态代码,但我找不到任何方法来添加正文。
这段代码我也试过了
ResponseBody error = new ResponseBody();
error.setTime(Timestamp.from(Instant.now()));
error.setMessage(ex.getMessage());
return ResponseEntity.status(HttpStatus.NO_CONTENT).body(error);
使用这种样式,我明确添加了正文,但结果仍然相同。正确的 HTTP 状态,但正文为空。
#编辑
这就是我首先抛出错误的方式
第一个请求被 RestContorller 捕获
@RestController
@RequestMapping("/levels")
public class LevelRestApi {
private ServiceLayer service;
@Autowired
public LevelRestApi(ServiceLayer service, LevelRepository repo) {
this.service = service;
}
@GetMapping("/{stage}")
public Level getLevel(@PathVariable int stage){
return service.getLevel(stage);
}
}
调用检查项目是否存在的服务层。我在这里抛出错误。
@Service
public class AlienInvadersServiceLayer implements ServiceLayer {
JpaRepository levelRepository;
@Autowired
public AlienInvadersServiceLayer(@Qualifier(value = "levelRepository") JpaRepository levelRepository) {
this.levelRepository = levelRepository;
}
@Override
public Level getLevel(int levelId) {
Optional<Level> result = levelRepository.findById(levelId);
if (result.isPresent()){
return result.get();
}
else {
throw new NoLevelFoundException(levelId);
}
}
}
问题出在 return new ResponseEntity<>(error, HttpStatus.NO_CONTENT);
handleNoLevelFoundException
方法。
当您说 NO_CONTENT
时,它只会清空您的响应正文并且确实有意义。
我建议改用 HttpStatus.NOT_FOUND
。
因此您的代码应如下所示
@ExceptionHandler(NoLevelFoundException.class)
public ResponseEntity<ResponseBody> handleNoLevelFoundException( NoLevelFoundException ex) {
// other code
return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
}
我是 spring 的新手,我正在尝试了解全局异常处理。我想在这里实现的是当使用不存在的主键发出请求时,我想 return 一个 HTTP_NO_CONTENT 正文包括时间戳和给定的所述请求的 id。
这是我的控制器建议
@ControllerAdvice
public class ControllerAdvisor {
@ExceptionHandler(NoLevelFoundException.class)
public ResponseEntity<ResponseBody> handleNoLevelFoundException( NoLevelFoundException ex) {
ex.printStackTrace();
ResponseBody error = new ResponseBody();
error.setTime(Timestamp.from(Instant.now()));
error.setMessage(ex.getMessage());
return new ResponseEntity<>(error, HttpStatus.NO_CONTENT);
}
}
这些是我的自定义异常和 respondBody
public class NoLevelFoundException extends RuntimeException{
public NoLevelFoundException(int id) {
super("No level with id " + id + " found!");
}
}
public class ResponseBody {
private Timestamp time;
private String message;
...
}
当我通过邮递员向一个不存在的项目发出请求时,我收到了这个。
使用 return ResponseEntity.noContent().build();
我仍然得到正确的状态代码,但我找不到任何方法来添加正文。
这段代码我也试过了
ResponseBody error = new ResponseBody();
error.setTime(Timestamp.from(Instant.now()));
error.setMessage(ex.getMessage());
return ResponseEntity.status(HttpStatus.NO_CONTENT).body(error);
使用这种样式,我明确添加了正文,但结果仍然相同。正确的 HTTP 状态,但正文为空。
#编辑
这就是我首先抛出错误的方式
第一个请求被 RestContorller 捕获
@RestController
@RequestMapping("/levels")
public class LevelRestApi {
private ServiceLayer service;
@Autowired
public LevelRestApi(ServiceLayer service, LevelRepository repo) {
this.service = service;
}
@GetMapping("/{stage}")
public Level getLevel(@PathVariable int stage){
return service.getLevel(stage);
}
}
调用检查项目是否存在的服务层。我在这里抛出错误。
@Service
public class AlienInvadersServiceLayer implements ServiceLayer {
JpaRepository levelRepository;
@Autowired
public AlienInvadersServiceLayer(@Qualifier(value = "levelRepository") JpaRepository levelRepository) {
this.levelRepository = levelRepository;
}
@Override
public Level getLevel(int levelId) {
Optional<Level> result = levelRepository.findById(levelId);
if (result.isPresent()){
return result.get();
}
else {
throw new NoLevelFoundException(levelId);
}
}
}
问题出在 return new ResponseEntity<>(error, HttpStatus.NO_CONTENT);
handleNoLevelFoundException
方法。
当您说 NO_CONTENT
时,它只会清空您的响应正文并且确实有意义。
我建议改用 HttpStatus.NOT_FOUND
。
因此您的代码应如下所示
@ExceptionHandler(NoLevelFoundException.class)
public ResponseEntity<ResponseBody> handleNoLevelFoundException( NoLevelFoundException ex) {
// other code
return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
}