我有一个已经实现的控制器方法,该方法返回一个值或引发异常。
@Override
@PostMapping(Endpoint.SUB_RESOURCE)
@ResponseStatus(HttpStatus.CREATED)
public EmployeeBankAccountOutputDto createBankAccount(@ApiParam("Account data") @RequestBody final EmployeeBankAccountInputDto accountCreationDto) {
try {
return service.createBankAccount(accountCreationDto);
} catch (InvalidAccountDataException ex) {
throw new InvalidAccountDataResponseException(ex, ex.getErrors());}
} catch (CountryNotFoundException ex) {
throw new CountryNotFoundResponseException(ex.getCountryCode(), ex);
}
}
在这段代码中,我只想在警告级别记录异常消息,而不抛出异常,因为我不想看到类似这样的东西:
14:37:02,610 ERROR [] c.m.w.ApiExceptionHandler:135 - Account API error occurred: 400
所以,如果我只放
log.warn(ex.getMessage());
到第一个catch语句,它给出
通常,该catch块的缺少返回声明
错误。那么,由于方法的返回类型是dto,如何处理不向调用api抛出异常而只是发送正确的异常消息呢?
答案 0 :(得分:3)
如果您没有从第一个catch块抛出异常,并且在这种情况下抛出并捕获了异常,该方法应该返回什么?
这就是为什么出现编译器错误的原因,因为将没有返回值,因为缺少return语句或未引发异常,这将导致执行流突然停止,因此您可以执行以下:
public EmployeeBankAccountOutputDto createBankAccount(@ApiParam("Account data") @RequestBody final EmployeeBankAccountInputDto accountCreationDto) {
EmployeeBankAccountInputDto employeeBankAccountInputDto = null;
try {
employeeBankAccountInputDto = service.createBankAccount(accountCreationDto);
} catch (InvalidAccountDataException ex) {
log.warn(ex.getMessage());
} catch (CountryNotFoundException ex) {
throw new CountryNotFoundResponseException(ex.getCountryCode(), ex);
}
return employeeBankAccountInputDto;
}
您 应该 最好将返回的对象包装在ResponseEntity
中,并添加消息和响应代码(如davidxxx在其评论中所述)。
public ResponseEntity<EmployeeBankAccountOutputDto> createBankAccount(@ApiParam("Account data") @RequestBody final EmployeeBankAccountInputDto accountCreationDto) {
EmployeeBankAccountInputDto employeeBankAccountInputDto = null;
try {
employeeBankAccountInputDto = service.createBankAccount(accountCreationDto);
} catch (InvalidAccountDataException ex) {
log.warn(ex.getMessage());
return new ResponseEntity(employeeBankAccountInputDto, HttpStatus.BAD_REQUEST);
} catch (CountryNotFoundException ex) {
throw new CountryNotFoundResponseException(ex.getCountryCode(), ex);
}
return new ResponseEntity(employeeBankAccountInputDto, HttpStatus.OK);
}
答案 1 :(得分:3)
如果无法创建帐户,则不希望返回任何内容。
至少您要返回400
错误响应,以将问题告知客户端。
您可以使用ResponseEntity
作为方法的返回类型来表示响应代码。这也意味着您还必须在成功的情况下更改返回对象的方式。
如果您不想传送特定的错误消息,而只传送错误代码,则可以按这种方式更改方法:
public ResponseEntity<EmployeeBankAccountOutputDto> createBankAccount(@ApiParam("Account data") @RequestBody final EmployeeBankAccountInputDto accountCreationDto) {
try {
return ResponseEntity.ok(service.createBankAccount(accountCreationDto));
} catch (InvalidAccountDataException ex) {
log.warn(ex.getMessage());
return ResponseEntity.badRequest();
}
}
如果您还想发送特定的错误消息,则可以使用响应的正文:
public ResponseEntity<EmployeeBankAccountOutputDto> createBankAccount(@ApiParam("Account data") @RequestBody final EmployeeBankAccountInputDto accountCreationDto) {
try {
return ResponseEntity.ok(service.createBankAccount(accountCreationDto));
} catch (InvalidAccountDataException ex) {
log.warn(ex.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ex.getMessage());
}
}
请注意,如果您需要在多个控制器中执行此处理,则可能意味着异常处理程序将是一种更整洁的方法。
例如,以统一的方式处理InvalidAccountDataException
:
@ControllerAdvice
public class MyExceptionHandler extends ResponseEntityExceptionHandler {
Logger LOGGER = LoggerFactory.getLogger(MyExceptionHandler.class);
@ExceptionHandler(value = { InvalidAccountDataException.class })
protected ResponseEntity<Object> handleGenericExceptions(InvalidAccountDataException ex, WebRequest request) {
log.warn(ex.getMessage());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ex.getMessage());
}
}
如果需要,您可以添加更多方法来处理更多类型的异常。