Spring Context中未加载Spring Boot全局控制器建议

时间:2018-08-08 05:57:51

标签: java spring spring-boot

我有一个控制器来接收POST请求并返回JSON输出。在controller类内部实现的异常处理程序工作正常。

我尝试添加带有@ControllerAdvice批注的Global异常处理,但这在我的解决方案中不起作用。我不认为正在加载全局异常处理程序类。

下面是我的控制器类:

package hello;

@Controller
@RequestMapping("/v1")
public class MyController {

  @RequestMapping(value = "/saveEmployee", method = RequestMethod.POST, produces = "application/json")
  @ResponseBody
  public String saveEmployee(@Valid @RequestBody Employee employee) {
    return "{ \"name\":\"" + employee.getEmail() + "\"}";
  }
}

下面是全局异常处理程序类:

package util;

@ControllerAdvice
public class MyControllerAdvice {

  @ExceptionHandler(MethodArgumentNotValidException.class)
  // @ResponseStatus(HttpStatus.BAD_REQUEST)
  @ResponseBody
  public String processValidationError(MethodArgumentNotValidException ex) {
    BindingResult result = ex.getBindingResult();
    FieldError fieldError = result.getFieldError();
    String code = fieldError.getCode();
    String field = fieldError.getField();
    String message = fieldError.getDefaultMessage();
    message = "{ \"Code\":\"" + code + "\",\"field\":\"" + field + "\",\"Message\":\"" + message + "\"}";
    return message;
  }
}

以下是我的配置:

package hello;

@SpringBootApplication
public class Application {

    @Bean
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasename("classpath:messages");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }

    @Bean
    public LocalValidatorFactoryBean validator() {
        LocalValidatorFactoryBean bean = new LocalValidatorFactoryBean();
        bean.setValidationMessageSource(messageSource());
        return bean;
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

春季启动版本:2.0.3.RELEASE

3 个答案:

答案 0 :(得分:2)

我认为您遇到的问题正是您所确定的。 MyControllerAdvice类未加载。从您发布的代码中,我推断您的项目结构看起来像:

src
  main
    java
      hello
        Application.java
        MyController.java
      util
        MyControllerAdvice.java

由于在SpringBootApplication类上具有Application批注,因此Spring Boot将其作为创建bean的起点,并查找带有@Controller和{ {1}}(以及其他)添加到上下文中。

有许多不同的配置方式,但是,如果您是刚开始或从事一个相对较小的项目,最简单的方法是将其重组以适合Spring在这里的建议:

https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-structuring-your-code.html

该页面非常简短,值得一读,以获取背景知识,但是本质是,您希望@ControllerAdvice注释的类与要Spring管理的所有类位于同一包或父包中,上面的页面给出了以下示例:

@SpringBootApplication

因此,在您的情况下,这意味着将com +- example +- myapplication +- Application.java | +- customer | +- Customer.java | +- CustomerController.java | +- CustomerService.java | +- CustomerRepository.java | +- order +- Order.java +- OrderController.java +- OrderService.java +- OrderRepository.java 软件包移到util下,例如:

hello

或者为src main java hello Application.java MyController.java util MyControllerAdvice.java hello创建父包,然后将util移至该包,例如:

Application

答案 1 :(得分:0)

尝试: Connection conn = DriverManager.getConnection("jdbc:sqlite:file:memorydb.db?mode=memory&cache=shared"); Statement stmt = conn.createStatement(); File tmpFile = File.createTempFile(name, ".db"); stmt.executeUpdate("backup to " + tmpFile.getAbsolutePath()); tmpFile.deleteOnExit(); stmt.close();

根据@ControllerAdvice("hello")的文档:

  

将包含属于那些基本包或其子包的控制器,例如:@ControllerAdvice(basePackages =“ org.my.pkg”)或@ControllerAdvice(basePackages = {“ org.my.pkg”,“ org.my.other.pkg“})。   value是此属性的别名,只是允许更简洁地使用批注。   还可以考虑将basePackageClasses()用作基于字符串的软件包名称的类型安全替代方法。

答案 2 :(得分:-1)

您确定它抛出MethodArgumentNotValidException吗?像这样设置默认处理程序

@ExceptionHandler(value = {Exception.class})
public ResponseEntity<Object> exception(Exception exception) {
    return new ResponseEntity<>(exception, HttpStatus.BAD_REQUEST)
}