Hander处理器的几种用法Model,ModelAndView和 ModeMap


Model,ModelAndView和 ModeMap

ModelMap对象主要用于传递控制方法传递数据到结果页面。类似于request的setAttribute方法的作用

Model

model是”模型“的意思,是MVC架构中的”M“部分,是用来传输数据的。
model的使用
Model是一个接口,它的实现类为ExtendedModelMap,继承ModelMap类

public class ExtendedModelMap extends ModelMap implements Model

查看Model的源码发现,里面比较重要的就是前4个。

package org.springframework.ui;
import java.util.Collection;
import java.util.Map;
import org.springframework.lang.Nullable;
/**
 * Java-5-specific interface that defines a holder for model attributes.
 * Primarily designed for adding attributes to the model.
 * Allows for accessing the overall model as a {@code java.util.Map}.
 *
 * @author Juergen Hoeller
 * @since 2.5.1
 */
public interface Model { 
    /**
     * Add the supplied attribute under the supplied name.
     * @param attributeName the name of the model attribute (never {@code null})
     * @param attributeValue the model attribute value (can be {@code null})
     */
    Model addAttribute(String attributeName, @Nullable Object attributeValue);
    /**
     * Add the supplied attribute to this {@code Map} using a
     * {@link org.springframework.core.Conventions#getVariableName generated name}.
     * <p><i>Note: Empty {@link java.util.Collection Collections} are not added to
     * the model when using this method because we cannot correctly determine
     * the true convention name. View code should check for {@code null} rather
     * than for empty collections as is already done by JSTL tags.</i>
     * @param attributeValue the model attribute value (never {@code null})
     */
    Model addAttribute(Object attributeValue);
 
    /**
     * Copy all attributes in the supplied {@code Collection} into this
     * {@code Map}, using attribute name generation for each element.
     * @see #addAttribute(Object)
     */
    Model addAllAttributes(Collection<?> attributeValues);
    /**
     * Copy all attributes in the supplied {@code Map} into this {@code Map}.
     * @see #addAttribute(String, Object)
     */
    Model addAllAttributes(Map<String, ?> attributes);
 
    /**
     * Copy all attributes in the supplied {@code Map} into this {@code Map},
     * with existing objects of the same name taking precedence (i.e. not getting
     * replaced).
     */
    Model mergeAttributes(Map<String, ?> attributes); 
    /**
     * Does this model contain an attribute of the given name?
     * @param attributeName the name of the model attribute (never {@code null})
     * @return whether this model contains a corresponding attribute
     */
    boolean containsAttribute(String attributeName); 
    /**
     * Return the attribute value for the given name, if any.
     * @param attributeName the name of the model attribute (never {@code null})
     * @return the corresponding attribute value, or {@code null} if none
     * @since 5.2
     */
    @Nullable
    Object getAttribute(String attributeName);
    /**
     * Return the current set of model attributes as a Map.
     */
    Map<String, Object> asMap(); 
}

Model addAttribute(String attributeName, @Nullable Object attributeValue)
Model addAttribute(Object attributeValue);
Model addAllAttributes(Collection<?> attributeValues); Model addAllAttributes(Map

package com.cat.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
/*
 * controller 负责提供访问应用程序的行为,通常通过接口定义或者注解定义两种方法实现。
 * 控制器负责解析用户的请求并将其转换为一个模型。
 * */
@Controller  //代表这个类会被spring接管,被这个注解的类中所有方法,如果返回值是string,并且有具体的页面可以跳转,那么就会被视图解析器解析
public class IndexController {     
    @RequestMapping("/hello")   //意为请求 localhost:8080/hello 
    public String hello(Model model){
        //封装数据(向模型中添加数据,可以jsp页面直接取出并渲染)
        model.addAttribute("name","张三");
        model.addAttribute("sex","男");
        model.addAttribute("age",23);
        System.out.println(model);
        //会被视图解析器处理
        return "hello";   //返回到哪个页面     
    }
}

jsp写法(注意和路径对应)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
hello.jsp页面
<p>姓名:${name}</p>
<p>性别:${sex}</p>
<p>年龄:${age}</p>
</body>
</html>

如下所示:
在这里插入图片描述

具体用法2:返回一个对象
model方法是可以返回一个对象的。我们创建一个对象Person实体类,至少要加上get方法。不然前端取不到数据

package com.cat.domain;
 
public class Person {
    public  String name;
    public  String sex;
    public  int age;
 
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    } 
    public String getSex() {
        return sex;
    } 
    public void setSex(String sex) {
        this.sex = sex;
    } 
    public int getAge() {
        return age;
    } 
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                '}';
    }
}

IndexController代码改成下面这样。

package com.cat.controller;
import com.cat.domain.Person;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; 
@Controller
@RequestMapping
public class IndexController {
    @RequestMapping("/hello")
    public String hello(Model model){
        Person person =new Person();
        person.name="张三";
        person.age=16;
        person.sex="男";
        System.out.println(person);
        model.addAttribute("person",person);
        return "hello";
    }
}

hello.jsp改成下面这样子。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
hello.jsp页面
<p>姓名:${person.name}</p>
<p>性别:${person.sex}</p>
<p>年龄:${person.age}</p>
</body>
</html>

页面重新请求后变成下面样子说明请求成功
返回map和collection类型暂时不做演示。

ModelAndView

如果翻译过来就是”模型和视图“,可以理解成MVC架构中的”M“和”V“,其中包含”Model“和”view“两部分,ModelAndView其实就是两个作用,一个是指定返回页面,另一个是在返回页面的同时添加属性;分别如下说明
①设置转向地址
(这也是ModelAndView和ModelMap的主要区别)

将底层获取的数据进行存储(或者封装)最后将数据传递给View,把controller方法中处理的数据传到jsp页面,在controller方法中把jsp界面需要的数据放到ModelAndView对象中即可。然后return mv。它的作用类似request对象的setAttribute方法
构造方法:
ModelAndView() //默认构造函数豆式的用法:填充bean的属性,而不是将在构造函数中的参数。
ModelAndView(String viewName) //方便的构造时,有没有模型数据暴露。
ModelAndView(String viewName, Map model) //给出创建一个视图名称和模型新的ModelAndView。
ModelAndView(String viewName, String modelName, Object modelObject) //方便的构造采取单一的模式对象。
ModelAndView(View view) //构造方便在没有模型数据暴露。
ModelAndView(View view, Map model) //创建给定一个视图对象和模型,新的ModelAndView。
ModelAndView(View view, String modelName, Object modelObject) //方便的构造采取单一模式对象。

类方法
ModelAndView addAllObjects(Map modelMap) //添加包含在所提供的地图模型中的所有条目。
ModelAndView addObject(Object modelObject) //添加对象使用的参数名称生成模型。
ModelAndView addObject(String modelName,ObjectmodelObject) //对象添加到模型中。
void clear() //清除此ModelAndView对象的状态。
Map getModel() //返回的模型图。
protectedMap getModelInternal() //返回的模型图。
ModelMap getModelMap() //返回底层ModelMap实例(从不为null)。
View getView() //返回View对象,或者为null,如果我们使用的视图名称由通过一个ViewResolverDispatcherServlet会得到解决。
String getViewName() //返回视图名称由DispatcherServlet的解决,通过一个ViewResolver,或空,如果我们使用的视图对象。
boolean hasView() //指示此与否的ModelAndView有一个观点,无论是作为一个视图名称或作为直接查看实例。
boolean isEmpty() //返回此ModelAndView对象是否为空,即是否不持有任何意见,不包含模型。
boolean isReference() //返回,我们是否使用视图的参考,i.e.
void setView(Viewview) //设置此ModelAndView的视图对象。
void setViewName(StringviewName) //此ModelAndView的设置视图名称,由通过一个ViewResolverDispatcherServlet会得到解决。
String toString() //返回这个模型和视图的诊断信息。
boolean wasCleared()?? //返回此ModelAndView对象是否为空的调用的结果,以清除(),即是否不持有任何意见,不包含模型。

在Controller中添加一个新的方法。

package com.cat.controller;
 
import com.cat.domain.Person;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
 
@Controller
@RequestMapping
public class IndexController {
//    @RequestMapping("/hello")
//    public String hello(Model model){
//        Person person =new Person();
//        person.name="张三";
//        person.age=16;
//        person.sex="男";
//        System.out.println(person);
//        model.addAttribute("person",person);
//        return "hello";
//    }
        @RequestMapping("/hello2")
        public ModelAndView hello(){
 
            ModelAndView modelAndView = new ModelAndView();
            modelAndView.setViewName("hello");  //返回到那个文件
            modelAndView.addObject("name","派大星");
            modelAndView.addObject("sex","男");
            modelAndView.addObject("age",53);
            System.out.println(modelAndView);
            return modelAndView;
        }
}

hello.jsp改成

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
hello.jsp页面
<p>姓名:${name}</p>
<p>性别:${sex}</p>
<p>年龄:${age}</p>
</body>
</html>

请求新的地址后发现数据没有问题。

ModelMap

**ModelMap继承LinkedHashMap,Spring框架自动创建modelmap的实例,并作为controller方法的参数传入,用户无需自己创建对象。
**

public class ModelMap extends LinkedHashMap

ModelMap对象主要用于把controller方法处理的数据传递到jsp界面,在controller方法中把jsp界面需要的数据放到ModelMap对象中即可。它的作用类似request对象的setAttribute方法
通过以下方法向页面传递参数:
addAttribute(String key,Object value);

Modelmap本身不能设置页面跳转的url地址别名或者物理跳转地址,那么我们可以通过控制器方法的返回值来设置跳转url地址别名或者物理跳转地址,
实现

@Controller
public class User2Controller{
    private static final Log logger = LogFactory.getLog(User2Controller.class);
    
    @ModelAttribute
    public void userMode2(String loginname,String password,
             ModelMap modelMap){
        logger.info("userMode2");
        // 创建User对象存储jsp页面传入的参数
        User2 user = new User2();
        user.setLoginname(loginname);
        user.setPassword(password);
        // 将User对象添加到ModelMap当中
        modelMap.addAttribute("user", user);
    }
    
    @RequestMapping(value="/login2")
     public String login2(ModelMap modelMap){
        logger.info("login2");
        // 从ModelMap当中取出之前存入的名为user的对象
        User2 user = (User2) modelMap.get("user");
        System.out.println(user);
        // 设置user对象的username属性
        user.setUsername("测试");
        return "result2";
    }

Model和ModelAndView ModelMap区别?

Model和ModelAndView区别

1.Model只是用来传输数据的,并不会进行业务的寻址。ModelAndView 却是可以进行业务寻址的,就是设置对应的要请求的静态文件,这里的静态文件指的是类似jsp的文件。
2.Model是每次请求中都存在的默认参数,利用其addAttribute()方法即可将服务器的值传递到jsp页面中;ModelAndView包含model和view两部分,使用时需要自己实例化,利用ModelMap用来传值,也可以设置view的名称。
3.Model是每一次请求可以自动创建,但是ModelAndView 是需要我们自己去new的。

ModelAndView和ModelMap区别

ModelMap继承LinkedHashMap,spring框架自动创建实例并作为controller的入参,用户无需自己创建,ModelAndView的实例是开发者自己手动创建的,这也是和ModelMap主要不同点之一
Model和ModelMap区别

Model和ModelMap区别

两个都不需要自己创建,不需要new 直接放在方法的参数中。ModelMap跟model的用法一模一样
①Model是一个接口,其实现类为ExtendedModelMap,继承了ModelMap类,只有寥寥几个方法只适合用于储存数据,简单方便理解使用
②ModelMap是一个类,为Map结构,可以使用Key/Value形式存储值。继承了 LinkedMap ,除了实现了自身的一些方法,同样的继承 LinkedMap 的方法和特性


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值