mvc模型的处理流程
对于一个mvc
程序,流程是下面几步:
- 发出一个请求(可以是在
view
中) - 发出请求后请求到达
controller
层 - 获取数据(
model
) - 将数据返回到
view
层
在上面的几步中mvc
是如何将数据带到view中的呢,一般来说有一下几种方式
ModelAndView, ModelMap, Map, Model
(这几种方式都是将数据放在了request
域中,而且这几种也是常用的几种方式)。@SessionAttributes, @ModelAttribute
返回ModelAndView
controller
@RequestMapping(value="testModel")
public ModelAndView testModelAndView() {
// 通过构造参数设置view,这里也是配置了前缀和后缀
ModelAndView mView = new ModelAndView("success");
Student student = new Student();
student.setId(111);
student.setName("hello Spring");
// 通过addObject方法设置数据(也就是model),这里就相当于是request.setAttribute("student", student);
mView.addObject("student", student);
return mView;
}
设置view
的时候是在springmvc.xml
配置文件中配置了前缀和后缀,配置如下:
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
所以这里实际上设置的view
是webContent
目录下面的views
下的success.jsp
页面。
前端页面
<body>
${requestScope.student.id},${requestScope.student.name}
</body>
上面已经说过了使用ModelAndView
的形式实际上数据是存放在request
域中的。所以在前端可以直接从request
域中获取数据。
返回view(String)
上面的例子中返回的是ModelAndView
对象,该对象包含的是视图和数据两方面的信息,现在如果方法中只是返回视图,也就是一个String
的话,那设置数据就可以使用常用的三种方式来设置。
ModelMap
@RequestMapping(value="testModelMap")
public String testModelMap(ModelMap modelMap) {
Student student = new Student();
student.setId(111);
student.setName("ModelMap");
modelMap.put("student", student);
return "success";
}
这里返回的只是视图,对于数据是通过ModelMap
对象来进行设置的,当使用ModelMap.put()
;方法时会自动将数据存放的request
域中。
Map
@RequestMapping(value="testMap")
public String testMap(Map<String, Object> map) {
Student student = new Student();
student.setId(111);
student.setName("Map");
map.put("student", student);
return "success";
}
使用Map
与ModelMap
是类似的。也是自动将数据放入到request
域中。
Model
@RequestMapping(value="testModel")
public String testModel(Model model) {
Student student = new Student();
student.setId(111);
student.setName("model");
model.addAttribute("student", student);
return "success";
}
使用Model
时存入数据的方法不是使用put
,而是使用addAttribute
,其余的也是类似。
将数据存放在session域中
上面所讲述的几个例子中返回的数据都是放在request
中,如果想要将数据放在request
域中的同时也放入到session
中可以使用@sessionAttributes
注解,该注解是加载类上面的。
存放一个值
@SessionAttributes(value="student1") // 该注解表示如果要在request域中存放student1对象,则同时将其存放在session域中
@RequestMapping(value="testModel")
public String testModel(Model model) {
Student student = new Student();
student.setId(111);
student.setName("model");
model.addAttribute("student1", student);
return "success";
}
存放多个值
package top.twolovelypig.controller;
// 该注解表示如果想要的request域中存放student1和student2对象,则同时也将其放入到session当中
@SessionAttributes(value= {"student1", "student2"})
@Controller
public class HelloWorld {
@RequestMapping(value="testModelMap")
public String testModelMap(ModelMap modelMap) {
Student student = new Student();
student.setId(111);
student.setName("ModelMap");
modelMap.put("student1", student);
return "success";
}
@RequestMapping(value="testMap")
public String testMap(Map<String, Object> map) {
Student student = new Student();
student.setId(111);
student.setName("Map");
map.put("student2", student);
return "success";
}
@RequestMapping(value="testModel")
public String testModel(Model model) {
Student student = new Student();
student.setId(111);
student.setName("model");
model.addAttribute("student3", student);
return "success";
}
}
使用类型
上面无论是存放一个值还是使用多个值都是使用的value,只是一个值的的时候就是一个字符串,如果是多个值时候就是使用数组,还有另外一种方式是使用type,代码如下:
package top.twolovelypig.controller;
// 该注解表示如果想要在request域中存放Student类型的对象,同时也会存放在session域中
@SessionAttributes(type=Student.class)
//如果是有多个类型,就是使用数组形式
//@SessionAttributes(type={Student.class,Address.class})
@Controller
public class HelloWorld {
@RequestMapping(value="testModelMap")
public String testModelMap(ModelMap modelMap) {
Student student = new Student();
student.setId(111);
student.setName("ModelMap");
modelMap.put("student1", student);
return "success";
}
@RequestMapping(value="testMap")
public String testMap(Map<String, Object> map) {
Student student = new Student();
student.setId(111);
student.setName("Map");
map.put("student2", student);
return "success";
}
@RequestMapping(value="testModel")
public String testModel(Model model) {
Student student = new Student();
student.setId(111);
student.setName("model");
model.addAttribute("student3", student);
return "success";
}
}
ModelAttribute注解
对于使用ModelAttribute注解的方法会在每一次请求之前调用一次,该方法含有一个参数Map,代码如下:
package top.twolovelypig.controller;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import top.twolovelypig.entity.Student;
@Controller
public class HelloWorld {
@ModelAttribute
public void queryStudentById(Map<String, Object> map) {
Student student = new Student();
student.setId(22);
student.setName("测试");
map.put("stu", student);
}
@RequestMapping(value="testModelMap")
public String testModelMap(@ModelAttribute("stu")Student student) {
student.setName(student.getName());
System.out.println(student.getName());
return "success";
}
}
需要注意的有以下几点:
- 使用@ModelAttribute注解的方法的参数map中的key应该是其余方法的参数的类型的小写模式
- 如果不是一致的,比如上面的代码中就是不一致的,在map中存放的是stu,但是下面方法的参数类型是Student,此时就需要在方法参数前面加上@ModelAttribute(“map中的值”)来修饰一下
- 该注解的作用是将该方法的map中的值赋值给下面方法的形参(这一点还没有明白,还需要看一下)