Java Spring引导全局控制器建议未加载到Spring上下文中
我有一个控制器来接收POST请求并返回JSON输出。在控制器类内部实现的异常处理程序工作正常 我尝试使用Java Spring引导全局控制器建议未加载到Spring上下文中,java,spring,spring-boot,Java,Spring,Spring Boot,我有一个控制器来接收POST请求并返回JSON输出。在控制器类内部实现的异常处理程序工作正常 我尝试使用@ControllerAdvice注释添加全局异常处理,但这在我的解决方案中不起作用。我认为没有加载全局异常处理程序类 下面是我的控制器类: package hello; @Controller @RequestMapping("/v1") public class MyController { @RequestMapping(value = "/saveEmployee", meth
@ControllerAdvice
注释添加全局异常处理,但这在我的解决方案中不起作用。我认为没有加载全局异常处理程序类
下面是我的控制器类:
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;
@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);
}
}
Spring boot版本:2.0.3.发行版试试这个:
@ControllerAdvice(“hello”)
根据控制器建议的文档
:
将包括属于这些基本包或其子包的控制器,例如:@ControllerAdvice(basePackages=“org.my.pkg”)或@ControllerAdvice(basePackages={“org.my.pkg”,“org.my.other.pkg”})。
值是该属性的别名,只允许更简洁地使用注释。
还可以考虑使用BasePkAgCeCaseSe()作为基于字符串的包名的类型安全替代。
你确定它会引发MethodArgumentNotValidException吗?将默认处理程序设置为如下所示
@ExceptionHandler(value = {Exception.class})
public ResponseEntity<Object> exception(Exception exception) {
return new ResponseEntity<>(exception, HttpStatus.BAD_REQUEST)
}
@ExceptionHandler(值={Exception.class})
公共响应异常(异常){
返回新的响应属性(异常,HttpStatus.BAD_请求)
}
我想你这里的问题正是你所发现的。未加载MyControllerAdvice类。根据您发布的代码,我推断您的项目结构如下:
src
main
java
hello
Application.java
MyController.java
util
MyControllerAdvice.java
因为在应用程序
类上有SpringBootApplication
注释,所以springboot使用该注释作为创建bean的起点,并且它查找带有@Controller
和@ControllerAdvice
等注释的类,以添加到其上下文中
有许多不同的方法来配置它,但如果您刚开始或正在处理一个相对较小的项目,最简单的方法是重新调整它以符合Spring的建议:
该页面非常短,值得阅读以了解背景信息,但本质上是您希望@springbootplication
注释类与您希望Spring管理的所有类位于同一个包或父包中,上面的页面给出了以下示例:
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
移动到该包,如:
src
main
java
example
Application.java
hello
MyController.java
util
MyControllerAdvice.java
这是我在传递给控制器“[nio-8080-exec-2].w.s.m.s.DefaultHandlerExceptionResolver:由处理程序执行引起的已解决异常:org.springframework.web.bind.MethodArgumentNotValidException:方法中索引0处的参数验证失败:@Piotr Rogowski您可以发布所述控制器的Spring配置吗?我看到控制器位于名为
hello
的包中,而异常处理程序位于名为util
的包中。我的第一个想法是,您没有将异常处理程序引入上下文。我已经尝试过了。但没有区别。我观察到的是“DefaultHandlerExceptionResolver:由处理程序执行引起的已解决异常:org.springframework.web.bind.MethodArgumentNotValidException:@HankTry将MyControllerAdvice
放入同一个MyController
包中。我可以重现你的问题,并通过我的解决方案来解决。是的。我只是试了一下你提到的方法,效果很好。谢谢但是,您是否确定了不在其他包中使用MyControllerAdvice的任何原因@Hank@DaveyDaveDave他的回答解释了我的观点。Spring使用@SpringBootApplication
类的包作为默认根包,并扫描该根包下的bean/配置。这就是为什么Spring在开始时找不到您的@ControllerAdvice
:)。但也请注意,仅将@springbootplication
拉到更高级别是不够的,@ControllerAdvice
仅在默认情况下影响@Controller
的相同包(和子包),除非您正确配置了基本包。这是一个很好的建议。我正确配置了基本包并对问题进行了排序。@HankNo。这不管用。是的,我确信它触发了MethodArgumentNotValidException@GerNikThis,如果它没有被其他处理程序捕获,它可以帮助我获得见解。是的。这很有效。我已经重新构建了整个项目。现在,Spring boot在上下文中添加了@ControllerAdvice。谢谢