Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 了解模型解析的工作原理_Java_Spring_Spring Mvc - Fatal编程技术网

Java 了解模型解析的工作原理

Java 了解模型解析的工作原理,java,spring,spring-mvc,Java,Spring,Spring Mvc,我是Spring MVC的新手。设法让一些应用程序运行,但我对某些方面的工作方式有一些疑问,无法找到我想要的解释。特别是在这种方法中: @Controller @RequestMapping("/hello") public class HelloController{ @RequestMapping(method = RequestMethod.GET) public String printHello(ModelMap model) { model.addAttri

我是Spring MVC的新手。设法让一些应用程序运行,但我对某些方面的工作方式有一些疑问,无法找到我想要的解释。特别是在这种方法中:

@Controller
@RequestMapping("/hello")
public class HelloController{

   @RequestMapping(method = RequestMethod.GET)
   public String printHello(ModelMap model) {
      model.addAttribute("message", "Hello Spring MVC Framework!");
      return "hello";
   }

}
我知道Hello Spring MVC框架!正在将“名称下”消息传递给视图。但有两件事让我担心,我觉得有点不寻常:

为什么模型被声明为printHello方法的输入参数?而不是说作为局部变量? 模型没有被显式地传递到视图中,那么这种情况是在幕后发生的吗? 您提供的@RequestMapping注释神奇地实现了这一点。我从字面和隐喻的意义上都这么说。它基本上消除了手工布线通常会涉及的混乱

该模型是许多可选输入参数之一。如果你愿意,你可以提供更多,或者更少,或者没有。在本例中,您想使用ModalMap,所以您说,我想通过包含参数来使用ModalMap。如果您有来自请求的参数,例如在标头中,您可以将这些参数添加到中并强制转换到它们

这类似于Spring的@Autowire。当您自动连接一个服务时,您不会在任何地方明确地说new FooService,但它是由Spring自动为您创建和管理的。基本上,您将大部分布线工作卸载到Spring,它处理所有样板文件,同时您完全处理您需要它处理的内容

在本例中,您将从get请求向客户端传递一个带有值的ModalMap,然后将该值加载到页面上

附加阅读+来源:

一个由SpringMVC框架为每个请求创建的新模型对象。这就是为什么它不是一个局部变量。由于对象本身是由框架创建的,因此它也有一个引用,所以框架负责将其传递给视图。

将模型对象作为参数传递,类似于我在下面的代码中添加的HttpServletRequest对象。Spring生成一个在整个请求生命周期中都可用的隐式模型对象,类似于JSP可用的隐式请求对象。因此,在每个请求生命周期中,此隐式模型对象将在控制器和视图之间共享

@Controller
@RequestMapping("/hello")
public class HelloController{

   @RequestMapping(method = RequestMethod.GET)
   public String printHello(ModelMap model, HttpServletRequest req) {
      model.addAttribute("message", "Hello Spring MVC Framework!");
      return "hello";
   }

}
下面是来自的描述。其中提到了传递给@RequestMapping注释的方法的输入参数的意义是什么

Map/Model/ModelMap,用于丰富将要创建的隐式模型 向web视图公开

为什么模型被声明为printHello方法的输入参数?而不是说作为局部变量

如果需要,可以将其声明为局部变量并返回:

@RequestMapping("/hello")
public ModelMap printHello() {
    return new ModelMap("message", "Hello Spring MVC Framework!");
}
但这样,您就不会利用Spring的数据绑定请求属性查询参数来获取对模型的请求

同样,通过这种方式,您不提供任何视图名称,因为在原始示例中返回hello,所以Spring MVC将使用默认的DefaultRequestToViewNameTranslator来推断它,该转换器使用没有控制器后缀的控制器名称作为逻辑视图名称。在您的示例中,它将是hello,因为您的控制器是HelloController。有关更多信息,请参阅

还可以返回新的ModelAndView实例,而不仅仅是Model或ModelMap。在这种情况下,可以显式设置视图名称和模型属性

但将模型用作处理程序方法参数的主要优点是数据绑定

当您提供模型和一些模型属性以将请求绑定为方法参数时,您将获得已添加并使用request params Model属性填充到您的模型的模型实例,然后您可以在需要时向其添加其他属性

@RequestMapping(path = "/hello", method = RequestMethod.GET)
public String printHello(Model model, @ModelAttribute("form") SearchForm form, BindingResult result) {
    model.addAttribute("anotherUsefulValue", myService.getSomeValue());
    // 'hello' view will get the model with both 'form' and 'anotherUsefulValue' attributes
    // and 'form' attribute will have 'text' field filled from request's
    // query parameter 'text'.
    return "hello";
}

class SearchForm {
    private String text;
    // ... getter and setter
}
使用此方法,您可以使用名为text的文本字段从某个html表单获取请求,当您提交此表单时,您的模型将包含属性表单,该表单的值为实例化的SearchForm对象。此对象的字段文本将以文本查询参数作为值

示例使用:

或者只需输入URL/hello?text=12345。您将看到该模型将具有文本字段等于12345的form属性,并且还具有另一个有用的value属性。您刚刚将Spring的数据绑定与自定义模型属性结合起来

当然,您可以手动创建新模型,并从方法的表单参数中设置另一个有用值和表单属性。但它只是更多的样板

模型没有被显式地传递到视图中,那么这种情况是在幕后发生的吗

当然。Spring的DispatcherServlet让我们为您做这件事以及其他许多事情。这些都在本文中描述


前端控制器只知道您的控制器方法返回了什么,并且可以理解它是新模型还是您的方法没有返回任何模型,然后前端控制器使用它传递给控制器方法的模型作为参数。

当DispatcherServlet咨询HandlerMapping时,我的想法是这样的
调用适当的控制器,也许它构造自己的ModelMap对象,以便将对象传递给方法的参数。如果您通过本地实例化显式地构造它,那么对象不受处理程序管理,因此不会发生绑定。所以,可以把它看作是约定/协议之类的东西。我的观点是:1,我把模型看作输入参数,而我看不到的2明显地被传递给视图,这是很奇怪的。另外,在这种情况下,视图上显示的唯一文本是我在代码中显示的文本,因此我假设没有收到其他数据,例如GET。关于2,它与此类似。Foo Foo=新Foo;字符串s=doSomethingfoo;在本例中,Spring仍然引用foo。它不需要返回foo,也不需要返回到帮助页面加载的位置。因为它是唯一映射的GET方法,并且没有参数,所以您可以随意调用该方法,并且它仍然是响应的目标方法。
<form:form method="GET" action="/hello" modelAttribute="form">
    <form:input path="text" />
    <input type="submit">
</form>