在 spring 启动时发送响应的最佳实践
Best practice to send response in spring boot
我正在 spring 引导中编码 REST Api-s。我想确保使用 swagger API 开发工具 (Swagger) 的前端开发人员可读我的代码。例如
@GetMapping("/getOne")
public ResponseEntity<?> getOne(@RequestParam String id) {
try {
return new ResponseEntity<Branch>(branchService.getOne(id), HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<FindError>(new FindError(e.getMessage()), HttpStatus.BAD_REQUEST);
}
}
如果请求成功,响应是一个分支对象,如果失败,响应是一个FindError 对象,它只有一个属性(message)。所以两者能否进行取决于响应。但是 swagger UI 没有显示应该如何显示响应,因为我使用 "?" 作为 通用类型 。这是捕获错误的最佳做法吗? (这个编码文档 swagger 对前端开发人员没有用,因为它没有显示响应对象)。或者针对上述问题的任何最佳实践?
有很多 return 不同对象的方法,例如 Branch。提前致谢
我建议这样做。
@GetMapping("/getOne")
public Response getOne(@RequestParam String id) {
ResponseEntity<Branch> resbranch;
ResponseEntity<FindError> reserror;
try {
resbranch=new ResponseEntity<Branch>(branchService.getOne(id), HttpStatus.OK);
return Response.status(200).entity(resbranch).build();
} catch (Exception e) {
reserror=new ResponseEntity<FindError>(new FindError(e.getMessage()), HttpStatus.BAD_REQUEST);
return Response.status(400).entity(reserror).build();
}
}
200 表示正常,400 表示错误请求。这里不会再有模棱两可的类型了..
首先,您应该遵循 RESTful API 的最佳实践。不要使用动词,而是使用名词 URL.So 而不是 @GetMapping("/getOne")
,你可以写
它作为 @GetMapping("/branch/{id}")
。
你可以参考这篇博客https://blog.mwaysolutions.com/2014/06/05/10-best-practices-for-better-restful-api/
@2ndly,不要 return 通用类型 ? ,而是可以使用特定类型,这里是 Branch 并进行中央异常处理。
以下代码片段可以帮助您:
@GetMapping("/branch/{id}")
public ResponseEntity<Branch> getBranch(@Pathvariable String id) {
{
Branch branch = branchService.getOne(id);
if(branch == null) {
throw new RecordNotFoundException("Invalid Branch id : " + id);
}
return new ResponseEntity<Branch>(branch, HttpStatus.OK);
}
RecordNotFoundException.java
@ResponseStatus(HttpStatus.NOT_FOUND)
public class RecordNotFoundException extends RuntimeException
{
public RecordNotFoundException(String exception) {
super(exception);
}
}
CustomExceptionHandler.java
@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler
{
@ExceptionHandler(Exception.class)
public final ResponseEntity<Object> handleAllExceptions(Exception ex, WebRequest request) {
List<String> details = new ArrayList<>();
details.add(ex.getLocalizedMessage());
ErrorResponse error = new ErrorResponse("Server Error", details);
return new ResponseEntity(error, HttpStatus.INTERNAL_SERVER_ERROR);
}
@ExceptionHandler(RecordNotFoundException.class)
public final ResponseEntity<Object> handleRecordNotFoundException(RecordNotFoundException ex, WebRequest request) {
List<String> details = new ArrayList<>();
details.add(ex.getLocalizedMessage());
ErrorResponse error = new ErrorResponse("Record Not Found", details);
return new ResponseEntity(error, HttpStatus.NOT_FOUND);
}
}
ErrorResponse.java
public class ErrorResponse
{
public ErrorResponse(String message, List<String> details) {
super();
this.message = message;
this.details = details;
}
private String message;
private List<String> details;
//Getter and setters
}
以上 class 处理多个异常,包括 RecordNotFoundException,您也可以自定义负载验证。
测试用例:
1) HTTP GET /branch/1 [VALID]
HTTP Status : 200
{
"id": 1,
"name": "Branch 1",
...
}
2) HTTP GET /branch/23 [INVALID]
HTTP Status : 404
{
"message": "Record Not Found",
"details": [
"Invalid Branch id : 23"
]
}
我正在 spring 引导中编码 REST Api-s。我想确保使用 swagger API 开发工具 (Swagger) 的前端开发人员可读我的代码。例如
@GetMapping("/getOne")
public ResponseEntity<?> getOne(@RequestParam String id) {
try {
return new ResponseEntity<Branch>(branchService.getOne(id), HttpStatus.OK);
} catch (Exception e) {
return new ResponseEntity<FindError>(new FindError(e.getMessage()), HttpStatus.BAD_REQUEST);
}
}
如果请求成功,响应是一个分支对象,如果失败,响应是一个FindError 对象,它只有一个属性(message)。所以两者能否进行取决于响应。但是 swagger UI 没有显示应该如何显示响应,因为我使用 "?" 作为 通用类型 。这是捕获错误的最佳做法吗? (这个编码文档 swagger 对前端开发人员没有用,因为它没有显示响应对象)。或者针对上述问题的任何最佳实践?
有很多 return 不同对象的方法,例如 Branch。提前致谢
我建议这样做。
@GetMapping("/getOne")
public Response getOne(@RequestParam String id) {
ResponseEntity<Branch> resbranch;
ResponseEntity<FindError> reserror;
try {
resbranch=new ResponseEntity<Branch>(branchService.getOne(id), HttpStatus.OK);
return Response.status(200).entity(resbranch).build();
} catch (Exception e) {
reserror=new ResponseEntity<FindError>(new FindError(e.getMessage()), HttpStatus.BAD_REQUEST);
return Response.status(400).entity(reserror).build();
}
}
200 表示正常,400 表示错误请求。这里不会再有模棱两可的类型了..
首先,您应该遵循 RESTful API 的最佳实践。不要使用动词,而是使用名词 URL.So 而不是 @GetMapping("/getOne")
,你可以写
它作为 @GetMapping("/branch/{id}")
。
你可以参考这篇博客https://blog.mwaysolutions.com/2014/06/05/10-best-practices-for-better-restful-api/
@2ndly,不要 return 通用类型 ? ,而是可以使用特定类型,这里是 Branch 并进行中央异常处理。 以下代码片段可以帮助您:
@GetMapping("/branch/{id}")
public ResponseEntity<Branch> getBranch(@Pathvariable String id) {
{
Branch branch = branchService.getOne(id);
if(branch == null) {
throw new RecordNotFoundException("Invalid Branch id : " + id);
}
return new ResponseEntity<Branch>(branch, HttpStatus.OK);
}
RecordNotFoundException.java
@ResponseStatus(HttpStatus.NOT_FOUND)
public class RecordNotFoundException extends RuntimeException
{
public RecordNotFoundException(String exception) {
super(exception);
}
}
CustomExceptionHandler.java
@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler
{
@ExceptionHandler(Exception.class)
public final ResponseEntity<Object> handleAllExceptions(Exception ex, WebRequest request) {
List<String> details = new ArrayList<>();
details.add(ex.getLocalizedMessage());
ErrorResponse error = new ErrorResponse("Server Error", details);
return new ResponseEntity(error, HttpStatus.INTERNAL_SERVER_ERROR);
}
@ExceptionHandler(RecordNotFoundException.class)
public final ResponseEntity<Object> handleRecordNotFoundException(RecordNotFoundException ex, WebRequest request) {
List<String> details = new ArrayList<>();
details.add(ex.getLocalizedMessage());
ErrorResponse error = new ErrorResponse("Record Not Found", details);
return new ResponseEntity(error, HttpStatus.NOT_FOUND);
}
}
ErrorResponse.java
public class ErrorResponse
{
public ErrorResponse(String message, List<String> details) {
super();
this.message = message;
this.details = details;
}
private String message;
private List<String> details;
//Getter and setters
}
以上 class 处理多个异常,包括 RecordNotFoundException,您也可以自定义负载验证。
测试用例:
1) HTTP GET /branch/1 [VALID]
HTTP Status : 200
{
"id": 1,
"name": "Branch 1",
...
}
2) HTTP GET /branch/23 [INVALID]
HTTP Status : 404
{
"message": "Record Not Found",
"details": [
"Invalid Branch id : 23"
]
}