【问题标题】:Spring MVC: Is it necessary to test if a @ModelAttribute is null?Spring MVC:是否有必要测试@ModelAttribute 是否为空?
【发布时间】:2014-08-25 11:56:12
【问题描述】:

我正在处理 Spring 3 项目,并且总是检查 @ModelAttribute 是否为空,如果是,我将用户重定向到错误页面。

@Controller
@SessionAttributes({"myCommand"})
public class MyController {
  @ModelAttribute("myCommand")
  public MyCommand populate(HttpServletRequest request) {
    return new MyCommand();
  }
  @RequestMapping(value="/user/saveFoo", method=RequestMethod.POST)
  public String saveFoo(HttpServletRequest request, @ModelAttribute("myCommand") MyCommand myCommand) {
    if(myCommand == null) {
      // Add invalid session error here.
      return "error.htm";
    }
    ...
    ...
  }
}

我想知道是否有必要进行此项检查。该命令是一个会话属性,必要时使用控制器的填充方法创建。因此,只要会话处于活动状态,该命令就永远不会为空。

我不知道会话过期时会发生什么。控制器是否再次创建模型属性?如果是这样,那么无论会话的状态如何,命令对象都不能为空。

感谢您的帮助。

【问题讨论】:

  • 我相信如果 @ModelAttribute 来自会话并且您没有 @ModelAttribute 方法来创建 MyCommand 并且您的会话已超时,那么它可能会是null。但是,这是一个很容易看到的测试。打开你的应用程序,在你点击这个处理程序之前,让它静置,比如说,一个小时或任何你设置会话超时的时间。继续,看看你是否在那里得到一个空值(可能想在那里放一个 SOP,这样你就知道它是空的)。

标签: java spring session spring-mvc modelattribute


【解决方案1】:

Spring MVC 为所有方法参数创建新实例,最大限度地降低控制器方法中出现空指针异常的潜在风险! 但请注意,这不适用于具有自定义 HandlerMethodArgumentResolver 的包装器类型和类,它们可以产生 null 作为返回值。

为了回答您的问题,Spring MVC 会实例化您的模型类的新实例,即使会话已过期。它永远不能为空!

引用ModelAttributeMethodProcessorjavadoc:

模型属性是从模型中获得的,或者如果没有找到可能 如果可用,则使用默认构造函数创建。

如果没有可用的默认构造函数Spring MVC 会抛出BeanInstantiationException 异常

org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [entity.Product]: No default constructor found

您可以安全地删除所有空指针检查。

要了解Spring MVC 默认情况下可以在控制器方法中处理的内容,您应该查看spring-web 工件包org.springframework.web.method.annotation 和spring-webmvc 工件包org.springframework.web.servlet.mvc.method.annotation 中的代码和javadoc。

【讨论】:

    【解决方案2】:

    其实你可以有以下:

    @ModelAttribute("isNull")
    public T returnNull() {
        return null;
    }
    
    @RequestMapping("/")
    public String go(@ModelAttribute("isNull") T isNull) {
        return isNull ? "isNull" : "isNotNull";
    }
    

    和isNotNull 视图将被返回。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-22
      • 1970-01-01
      • 1970-01-01
      • 2022-06-30
      • 2013-09-03
      相关资源
      最近更新 更多