只是开始研究Spring并制作了FizzBuzz rest api。当我添加ControllerAdvice
时,我意识到它不会捕获我抛出的任何异常,而是将它们转到默认处理程序。我尝试了许多建议,但到目前为止没有任何效果。我是在做错什么还是不做某事?
package com.fizzbuzz;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import com.fizzbuzz.Exceptions.ForbiddenUseException;
import com.fizzbuzz.Exceptions.IllegalParameterException;
import helpers.*;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@ControllerAdvice
public class ErrorHandler extends ResponseEntityExceptionHandler {
org.slf4j.Logger log = LoggerFactory.getLogger(ErrorHandler.class);
/** Just exploring how global exception handlers operate **/
@ExceptionHandler(ForbiddenUseException.class)
public final ResponseEntity<ApiError> GeneralError(ForbiddenUseException ex){
ApiError error = new ApiError(ex.getMessage(), "FRB-123");
return new ResponseEntity<ApiError>(error, new HttpHeaders(), HttpStatus.FORBIDDEN);
}
@ExceptionHandler(IllegalParameterException.class)
public final ResponseEntity<ApiError> ParameterError(IllegalParameterException ex){
ApiError error = new ApiError(ex.getMessage(), "PAR-123");
return new ResponseEntity<ApiError>(error, new HttpHeaders(), HttpStatus.BAD_REQUEST);
}
@ExceptionHandler(Exception.class)
public final ResponseEntity<ApiError> InternalServerError (Exception ex){
/** Log
* Add stack trace or anything deemed useful here
**/
log.debug("Internal server error: " + ex.getMessage());
/** don't show any specifics about the exceptions here should be logged instead **/
ApiError error = new ApiError("Whoops something nasty happened, check server logs for details.", "IS-001");
return new ResponseEntity<ApiError>(error, new HttpHeaders(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
这是控制器
package com.fizzbuzz.Controllers;
import java.util.ArrayList;
import java.util.List;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.fizzbuzz.Exceptions.ForbiddenUseException;
import com.fizzbuzz.Exceptions.IllegalParameterException;
import helpers.*;
@RestController
public class FizzBuzzControllers {
/**
* FizzBuzz crashes in case of bad input or cast
* Exception handling in global handler @ErrorHandler
* @throws ForbiddenUseException When parameter is empty or null
* @throws IllegalParameterException list contains something other than numbers
**/
@PostMapping("/FizzBuzz")
String FizzBuzz(@RequestBody String list) throws ForbiddenUseException, IllegalParameterException {
List<String> response = new ArrayList<String>();
if(list == null || list.isEmpty())
throw new ForbiddenUseException("The list of numbers cannot be empty or null.");
for (String token : list.split(",")) {
try
{
response.add(Helpers.FizzBuzz(Integer.parseInt(token)));
} catch(NumberFormatException ex) {
/** Found some nonsense in the list throw an exception **/
throw new IllegalParameterException("The list can't contain anything other than numbers.");
}
}
return String.join(",", response);
}
/**
* FizzBuzz v2 tries to recover from bad input by adding N/A when encountering incorrect entries
* w/e other exception is handled @ErrorHandler as 500 internal server error
* @throws ForbiddenUseException When parameter is empty or null
**/
@PostMapping("/FizzBuzzV2")
String FizzBuzzv2(@RequestBody String list) throws ForbiddenUseException {
List<String> response = new ArrayList<String>();
if(list == null || list.isEmpty())
throw new ForbiddenUseException("The list of numbers cannot be empty or null.");
for (String token : list.split(",")) {
try
{
response.add(Helpers.FizzBuzz(Integer.parseInt(token)));
} catch(NumberFormatException ex) {
/** Found some nonsense in the list add N/A and continue **/
response.add("N/A");
}
}
return String.join(",", response);
}
}
这两个自定义异常在构造函数中只有super(message)
。除了异常处理之外的所有其他东西都很好。
我已将其添加到main方法中以显示所有bean,并且确实显示了其中的异常处理程序,所以我想这意味着spring知道了。
for (String beanName : applicationContext.getBeanDefinitionNames()) {
System.out.println(beanName);
}