我想检查ControllerAdvice
中是否存在用户,如果用户存在则将用户视为@ModelAttribute。另一方面,我还想直接访问@Controller
中的用户对象。所以我在@RequestMapping方法的参数上添加@ModelAttribute
注释。
我正在使用@ControllerAdvice:
@ControllerAdvice
public class UserAdvice {
@Autowired
private UserService userService;
@ModelAttribute("user")
public User user(@PathVariable("username") String username) {
User user = userService.findByUsername(username);
if (user != null) {
return user;
}
user = userService.findById(username);
if (user == null) {
throw new ResourceNotFoundException("user not found");
}
return user;
}
}
和UserController
赞:
@RestController
@RequestMapping("/users/{username}")
public class UserController {
public static final Logger logger = LoggerFactory.getLogger(UserCourseListController.class);
@Autowired
private CourseService courseService;
@RequestMapping(value = "", method = RequestMethod.GET)
public void getUser(@ModelAttribute("user") User user, Model model) {
logger.info("{}", user);//user is null
logger.info("{}", model.asMap().get("user"));// not null
}
}
但是现在,使用@ModelAttribute注释的参数user
为null,而模型映射中有“user”obj。
我在这种情况下是否有任何错误?或者对@ModelAttribute
和@ControllerAdvice
非常感谢!
一旦出现在模型中,参数的字段应该从具有匹配名称的所有请求参数中填充。
因此,我们无法将@ModelAttribute
直接添加到由@RequestMapping
注释的方法参数,因为Spring将根据请求(而非Model
)进行数据绑定。
最后我找到了一个解决方案 - HandlerMethodArgumentResolver
。它可以解析每个@RequestMapping
方法的方法参数,并在解析参数方面做一些工作。 Java Config的一个例子如下:
public class Config extends WebMvcConfigurerAdapter {
@Bean(name = "auditorBean")
public AuditorAware<User> auditorAwareBean() {
return () -> null;
}
@Bean
public HttpMessageConverters customConverters() {
return new HttpMessageConverters(new MappingJackson2HttpMessageConverter());
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new HandlerMethodArgumentResolver() {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().equals(User.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
return mavContainer.getDefaultModel().get(parameter.getParameterName());
}
});
}
}
我们通过parameter.getParameterName()
从模型中解析方法参数。这意味着方法参数(user
)的名称必须等于@ControllerAdvice
中定义的@ModelAttrubute的值。您还可以使用任何其他命名约定来实现绑定。