我是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 Framework!"
(名称message
)正在传递给视图。但有两件事让我感到担忧,并发现有点不寻常:
model
被printHello
方法声明为输入参数?而不是说作为局部变量?model
无法传递给视图显式,这是否会以某种方式在幕后发生?答案 0 :(得分:2)
为什么
model
被声明为printHello
方法的输入参数?而不是说作为局部变量?
您可以将其声明为局部变量,并在需要时返回:
@RequestMapping("/hello")
public ModelMap printHello() {
return new ModelMap("message", "Hello Spring MVC Framework!");
}
但是这样你就不会利用Spring的数据绑定(绑定请求属性(GET请求的查询参数)来建模)。
此外,您不提供任何视图名称(如原始示例return "hello"
中所示),因此Spring MVC将使用默认DefaultRequestToViewNameTranslator
推断它,该默认Controller
使用不带hello
后缀的控制器名称逻辑视图名称(在您的示例中,它将是HelloController
,因为您的控制器是ModelAndView
)。有关详细信息,请参阅documentation。
此外,您可以返回新的Model
个实例,而不仅仅是ModelMap
或@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
}
。在这种情况下,您可以显式设置视图名称和模型属性。
但使用Model作为处理程序方法参数的主要优点是数据绑定。
当您提供Model 和某些模型属性(将请求绑定到)作为方法参数时,您将获得已经添加(并使用请求参数填充)模型属性的模型实例到您的模型然后如果需要,可以为其添加其他属性。
form
使用此方法,您可以使用名为text
的文本字段从某些html form
执行GET请求,当您提交此表单时,您的模型将包含已实例化SearchForm
的属性text
1}}对象作为值。此对象的字段text
将<form:form method="GET" action="/hello" modelAttribute="form">
<form:input path="text" />
<input type="submit">
</form>
查询参数作为值。
使用spring-form JSP Tag Library的示例:
/hello?text=12345
或者只输入网址model
。并且您会看到form
将text
属性12345
字段等于anotherUsefulValue
和它还具有您的anotherUsefulValue
属性。您只需将Spring的数据绑定与自定义模型属性结合起来。
当然,您可以手动创建新模型,并在方法的form
参数中设置form
和model
属性。但它只是更多的样板。
DispatcherServlet
无法传递给视图显式,所以这会在幕后以某种方式发生吗?
当然。 Spring的Front Controller
为你做了很多其他事情。这一切都在documentation中描述。
Front Controller
只知道你的控制器方法返回了什么,并且可以理解它是新模型还是你的方法没有返回任何模型然后send
使用它传递给你的控制器方法的模型作为参数。
答案 1 :(得分:1)
您提供的@RequestMapping
注释会神奇地。我在文字和隐喻意义上都这么说。它基本上可以减少一切通常涉及的混乱的手工布线。
该模型是许多可选输入参数之一。如果您愿意,您可以提供更多,更少或更少。在这种情况下,你想使用ModalMap,所以你说,&#34;我想使用ModalMap&#34;通过包括论点。如果您有来自请求的参数,例如标题中的参数,您可以添加参数并转换为它们。
这类似于Spring的@Autowire
。当您自动装配服务时,您从不在任何地方明确说出new FooService()
,但Spring会自动为您创建和管理它。您基本上将大部分布线工作卸载到Spring,并且它处理所有样板,同时您处理完全需要它处理的内容。
在这种情况下,您将一个带有值的ModalMap从get请求传递给客户端,然后在页面上加载该值。
答案 2 :(得分:1)
将model
对象视为参数传递,类似于我在代码中添加的HttpServletRequest
对象。 Spring生成一个隐式模型对象,该对象在整个请求生命周期中都可用,类似于JSP可用的隐式request
对象。因此,根据单个请求生命周期,此隐式模型对象将在控制器和视图之间共享。
@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";
}
}
以下是spring docs的说明。在哪里提到传递给使用@RequestMapping注释的方法的输入参数的重要性
Map / Model / ModelMap用于丰富将要的隐式模型 暴露在网络视图中。
答案 3 :(得分:0)
Spring-MVC框架为每个请求创建的新 model
对象。这就是为什么它不是本地变量的原因。由于框架创建的对象本身也已经有了引用,因此框架负责将其传递给View。