SpringMVC 模型数据

Spring MVC 通过 @RequestMapping 将请求引导到处理方法上,使用合适的方法签名将请求消息绑定到入参中。方法入参绑定请求消息只是处理方法的第一步,还有更重要的任务等待完成,即根据入参执行相应的逻辑,产生模型数据,导向到特定视图中。

如何将模型数据暴露给视图是 SpringMVC 框架的一项重要工作,SpringMVC 提供了多种途径输出模型数据:

1. @ModelAndView:处理方法返回值类型为 ModelAndView时,方法体即可通过该对象添加模型数据。

2. @ModelAttribute:方法入参标注该注解后,入参的对象就会放到数据模型中。

3. @Map 及 Model入参为 org.springframework.ui.Model、org.soringframework.ui.ModelMap 或 java.util.Map 时,处理方法返回时,Map中的数据会自动添加到模型中。

4. @SessonAttribute将模型中的某个属性暂时存到 HttpSession 中,以便多个请求之间可以共享这个属性。

 

一、ModelAndView

控制器处理方法的返回值如果为 ModelAndView,则其既包含视图信息,也包含模型数据信息,这样 SpringMVC 就可以使用视图对模型数据进行渲染了。可以简单地将模型数据看成一个 Map<String, Object>对象。

在处理方法的方法体中,可以使用如下方法添加模型对象:

1. ModelAndView addObject(String attributeName, Object attributeValue)

2. ModelAndView addAllObject(Map<String, ?> modelMap)

可以通过如下方法设置视图

1. void setView(View view):指定一个具体的视图对象

2. void setViewName(String viewName):指定一个逻辑视图名

测试:


@RequestMapping("/springmvc")
@Controller
public class SpringTest
{    
    //SpringMVC 会把 ModelAndView 的模型数据放到请求域中去
    @RequestMapping("/testModelAndView")
    public ModelAndView testModelAndView()
    {
        String viewName = "success";
     //指定跳转的逻辑视图名为 success
        ModelAndView modelAndView = new ModelAndView(viewName);
        //添加模型数据到ModelAndView
        modelAndView.addObject("time", new Date());
        return modelAndView;
    }
}


<body>
    <a href="springmvc/testModelAndView">Test ModelAndView</a>
</body>


<body>
    <h4>Success Page</h4>
    
    time: ${requestScope.time }
</body>

 

二、Map 及 Model

SpringMVC 在内部使用一个 org.springframework.ui.Model 接口存储模型数据,它的功能类似于 java.util.Map,但它比Map易用。org.springframework.ui.ModelMap实现了 Map 接口,而 org.springframework.ui.ExtendedModelMap 继承于 ModelMap 同时实现了 Model 接口。

SpringMVC 在调用方法前会创建一个隐含的模型对象,作为模型数据的存储容器,我们称之为 “隐含模型”。如果处理方法的入参为 Map 或 Model 类型,SpringMVC 会将隐含模型的引用传递给这些入参。在方法体内,开发者可以通过这个入参对象访问到模型中的所有数据,也可以向模型数据中添加新的属性数据。

测试:

//目标方法可以添加 Map 类型的参数,也可以是 Model 类型或者 ModelMap 类型的参数
    @RequestMapping("/testMap")
    public String testMap(Map<String, Object> map)
    {
        map.put("names", Arrays.asList("tom", "jack", "mike"));
        return "success";
    }



<a href="springmvc/testMap">Test Map</a>



map: ${requestScope.names }

SpringMVC 一旦发现处理方法有 Map 或 Model 类型的入参,就会请求内在的隐含模型对象传递给这些参数,因此在方法体中可以通过这个入参对模型对象的数据进行读写操作。

二,@ModelAttribute

在方法定义上使用 @ModelAttribute 注解:SpringMVC 在调用目标处理方法前,会逐个调用在方法上标注了 @ModelAttribute 的方法

在方法的入参前使用 @ModelAttribute 注解:

1. 可以从隐含对象中获取隐含的模型数据对象,再将请求参数绑定到对象中,再传入入参

2. 将方法入参对象添加到模型中

如果希望将方法入参对象添加到模型中,仅需在相应的入参前使用@ModelAttribute注解即可,

public String list(@ModelAttribute("teachet") Teacher teachet){  

        Teacher teacher = new Teacher();  

        teacher.setAge(24);  

        teacher.setId(1);  

        teacher.setName("json");  

        return "teacher/list";  

    }  

SpringMVC将请求消息绑定到Teacher对象中,然后再以“teacher”为键将Teacher对象放到隐藏模型中,最后在视图对象list.jsp中就可以使用${teacher.name}取值显示了。

@ModelAttribute也可以在方法上使用,SpringMVC在调用目标方法前,会先逐个调用在方法级上标注了@ModelAttribute的方法,并将这些方法的返回值添加到隐藏模型中。

注意:在②处,当获得整合版本的user对象后,会将其添加到模型中。

 

四,@SessionAttributes

如果希望在多个请求之间共用某个模型属性数据,则可以在控制器类标注个 @SessionAttributes,SpringMVC 会将模型中对应的属性暂存到 HTTPSession 中。

@SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中。

1. @SessionAttributes(types=User.class)会将隐含模型中所有类型为 User 的属性添加到会话中

2. @SessionAttributes(value={"user1", "user2"})将名为 user1 和 user2 的模型属性添加到会话中

3. @SessionAttributes(types={"User.class", "Dept.class"})将模型中所有类型为 User 及 Dept 的属性添加到会话中

4. @SessionAtributes(value={"user1", "user2"}, types={Dept.class})将名为 user1 和 user2 的模型属性添加到会话中,同时将所有类型为 Dept 的模型属性添加到会话中

@SessionAttributes(value={"user"}, types={String.class})
@RequestMapping("/springmvc")
@Controller
public class SpringTest
{
    private static final String SUCCESS = "success";
    
  @RequestMapping("/testSessionAttributes")
    public String testSessionAttributes(Map<String, Object> map)
    {
        User user = new User("Jack", "123");
        map.put("user", user);
        map.put("msg", "hello");
        return SUCCESS;
    }
}



<a href="springmvc/testSessionAttributes">Test SessionAttributes</a>



request user: ${requestScope.user }
<br><br>
request msg: ${requestScope.msg }
<br><br>
session user: ${sessionScope.user }
<br><br>
session msg: ${sessionScope.msg }

由结果可以看出,被 @SessionAttributes 注解修饰后,模型属性不仅存在于请求域还存在于会话域。需要注意的是@SessionAttributes 注解只能用于修饰类而不能用于方法上

补充:

如果Model中没有key为user的属性,并且没写@ModelAttribute("user"),由于参数列表中有User user对象入参,则Spring会将该对象放入model,并且key值为首字母小写的类名,也就是说对于方法:
 @RequestMapping(value="/helloworld")
 public String helloWorld(User user)
 {
     return "helloworld";
 }

框架提前帮你写了一句model.addAttribute("user",user)。
而且特别需要注意注意,无论model中是否有key为user的属性,都要求User类有无参构造方法

转载于:https://my.oschina.net/lin546/blog/1631504

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值