我使用Spring Boot作为一个简单的REST API,并希望在出现故障时返回正确的HTTP状态代码.
@RequestMapping(value="/rawdata/", method = RequestMethod.PUT)
@ResponseBody
@ResponseStatus( HttpStatus.OK )
public RestModel create(@RequestBody String data) {
// code ommitted..
// how do i return a correct status code if something fails?
}
Run Code Online (Sandbox Code Playgroud)
作为Spring和Spring Boot的新手,基本的问题是,当某些东西正常或失败时,我如何返回不同的状态代码?
我的 Spring Boot 应用程序提供以下 REST 控制器:
@RestController
@RequestMapping("/api/verify")
public class VerificationController {
final VerificationService verificationService;
Logger logger = LoggerFactory.getLogger(VerificationController.class);
public VerificationController(VerificationService verificationService) {
this.verificationService = verificationService;
}
@GetMapping
public void verify(
@RequestParam(value = "s1") String s1,
@RequestParam(value = "s2") String s2) {
try {
verificationService.validateFormat(s1, s2);
} catch (InvalidFormatException e) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, e.getMessage());
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果validateFormat()抛出,InvalidFormatException客户端会得到一个正确的 HTTP 400。然而,默认的 JSON 响应正文如下所示:
{
"timestamp": "2020-06-18T21:31:34.911+00:00",
"status": 400,
"error": "Bad Request",
"message": "",
"path": "/api/verify"
} …Run Code Online (Sandbox Code Playgroud) Spring Web 堆栈上有一个应用程序。升级到最新版本后,我遇到了一个不寻常的问题Spring Boot 2.6.1。
下面的代码
@RestController
@RequestMapping("sample")
class SampleController {
@PostMapping
fun doSomething(@RequestBody body: Any): Any {
error("Error!")
}
}
Run Code Online (Sandbox Code Playgroud)
用于在早期版本中产生以下错误
{
"timestamp": "2020-05-27T13:44:58.032+00:00",
"status": 500,
"error": "Internal Server Error",
"message": "Error!",
"path": "/sample"
}
Run Code Online (Sandbox Code Playgroud)
但升级后整个响应体是空的。不是message可以通过server.error.inclide-message: always标志设置来固定的字段,而是整个主体。该include-binding-errors: always标志也没有效果。
我在 Spring Boot 变更日志中没有发现有关该行为的注释
在我的请求处理程序中,如果传入的内容accountId无法转换为有效的,ObjectId我想捕获错误并发回有意义的消息;但是,这样做会导致返回类型不兼容,并且我无法弄清楚如何实现这个非常简单的用例。
我的代码:
@GetMapping("/{accountId}")
public Mono<ResponseEntity<Account>> get(@PathVariable String accountId) {
log.debug(GETTING_DATA_FOR_ACCOUNT, accountId);
try {
ObjectId id = new ObjectId(accountId);
return repository.findById(id)
.map(ResponseEntity::ok)
.switchIfEmpty(Mono.just(ResponseEntity.notFound().build()));
} catch (IllegalArgumentException ex) {
log.error(MALFORMED_OBJECT_ID, accountId);
// TODO(marco): find a way to return the custom error message. This seems to be currently
// impossible with the Reactive API, as using body(message) changes the return type to
// be incompatible (and Mono<ResponseEntity<?>> does not seem to cut it).
return Mono.just(ResponseEntity.badRequest().build());
}
}
Run Code Online (Sandbox Code Playgroud)
该body(T …