Spring在@RequestMappings之间的通用方法
Spring在@RequestMappings之间的通用方法
在Spring的@Controller中,您可以在每个方法中使用@RequestMapping注解来实现类似于Servlet中的@Override service方法的功能。具体来说,在Controller中的每个方法中,您需要确保一个实体(在此情况下是一个产品)存在,否则需要重定向。您可以通过以下方式实现这一点:
@Controller
@RequestMapping("/product/{prod_id}/attribute")
public class AttributeController {
@Autowired
private AttributeService attributeService;
// 在每个方法之前添加一个拦截器,检查产品是否存在
@ModelAttribute
public void checkProductExists(Model model, @PathVariable Long prod_id) {
Product product = attributeService.getProduct(prod_id);
if (product == null) {
// 重定向到产品列表页面
throw new ProductNotFoundException();
}
model.addAttribute("product", product);
}
@RequestMapping(value = "/add", method = RequestMethod.GET)
public String add(Model model, @PathVariable Long prod_id) {
model.addAttribute("attribute", new Attribute());
return "products/attribute_add";
}
@RequestMapping(value = "/add", method = RequestMethod.POST)
public String save(Model model, @PathVariable Long prod_id, @Valid Attribute attribute, BindingResult result) {
// ...
}
// ...
}
Spring中的@Controller和@RequestMapping注解是常用的注解,用于处理HTTP请求。在处理请求的方法中,有时我们希望在每个方法中都可以使用相同的对象,而不需要再次从数据库中检索该对象。那么,有没有办法实现这个需求呢?
答案是可以的。可以使用Spring提供的HandlerInterceptor来实现这个功能。只需要继承HandlerInterceptorAdapter类,并通过WebMvcConfigurer的addInterceptors方法注册拦截器。可以选择在所有的映射方法中使用拦截器,也可以在某些特定的映射方法中使用拦截器。
另外,HandlerInterceptor不仅可以用于存储对象,还可以用于一些通用的操作,比如日志记录、添加头部信息、身份验证等。但是对于与业务相关的操作,建议使用ControllerAdvice和自定义的业务异常。可以在ControllerAdvice中定义一个方法,从数据库中获取Product对象,如果未找到则抛出自定义异常。
如果需要在每个方法中都可以使用Product对象,可以使用ServletRequest的方法将对象存储在请求中。
需要注意的是,HandlerInterceptor是一个标准的Spring bean,可以自动装配任何Spring bean。但是在拦截器中操作数据库是非常奇怪的,因为拦截器主要用于一些通用和实用的操作,如日志记录、身份验证、欺诈保护等。但是如果确实需要,在拦截器中注入自己的bean即可。确保不要将拦截器自动装配到服务类中,并在上下文配置中将拦截器声明为Spring bean。
使用HandlerInterceptor可以实现在每个方法中都可以使用相同的对象,而不需要再次从数据库中检索该对象。这是一种简洁、优雅的解决方案。如果你觉得这个答案有用,请接受并点赞。感谢!