zoukankan      html  css  js  c++  java
  • Spring MVC中的模型数据处理

    一、综述
    Spring MVC 提供了以下途径来输出模型数据:
    1、ModelAndView
    当处理方法返回值类型为 ModelAndView时, 方法体即可通过该对象添加模型数据到请求域。
    2、Map 及 Model
    输入参数为org.springframework.ui.Model、org.springframework.ui.ModelMap 或 java.uti.Map 时,处理方法返回时,Map中的数据会自动添加到模型中。
    3、@SessionAttributes 
    该注解将模型中的某个属性暂存到HttpSession 中,以便多个请求之间可以共享这个属性。
    4、@ModelAttribute: 方法输入参数标注该注解后, 入参的对象就会放到数据模型中。


    二、ModelAndView和Map&Model
    ModelAndView对象中包含了一个model属性和一个view属性。
    model:是一个ModelMap的类型。而ModelMap又是一个LinkedHashMap的子类。
    view:包含了一些视图信息。
    实现原理:
    当视图解释器解析ModelAndVIew类型的参数时,其中model是一个Map的实现类的子类,视图解析器将model中的每个元素都通过request.setAttribute(name, value)方法,添加request请求域中。这样就可以在JSP页面中通过EL表达式来获取对应的值
    操作方法:
    添加模型数据:
    MoelAndView addObject(String attributeName, Object attributeValue)
    ModelAndView addAllObject(Map<String, ?> modelMap)
    设置视图:
    void setView(View view)
    void setViewName(String viewName)
    示例演示:
    1、编写处理函数
    //导入相应的包
    @Controller
    public class SpringMVCTest {
    
    
        public MAVTest() {
            // TODO Auto-generated constructor stub
        }
    
    
        @RequestMapping(value = "login")
        public ModelAndView login() {//返回值为ModelAndView类型
            System.out.println("login()....");
            ModelAndView mav = new ModelAndView();
            mav.setViewName("welcome");//设置相应的视图名称为welcome,
            mav.addObject("msg", "hello Spring MVC");//直接存入参数值
    
    
            // List
            List<String> list = new ArrayList<String>();
            list.add("java");
            list.add("hadoop");
            list.add("Mysql");
            mav.addObject("bookList", list);//存入List类型的数据
    
    
            // Map
            Map<String, String> map = new HashMap<String, String>();
            map.put("zhangsan", "北京");
            map.put("lisi", "上海");
            map.put("wangwu", "深圳");
            mav.addObject("map", map);//存入Map型数据
    
    
            return mav;//返回ModelAndView对象
        }
    
    
    }

    2、编写jsp页面
    <%@ page language="java" contentType="text/html; charset=UTF-8"
    	pageEncoding="UTF-8"%>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    	<!-- 输出普通字符 -->
    	${msg}
    	<br />
    	<!-- 输出List -->
    	<p>书籍列表</p>
    	<c:forEach items="${bookList}" var="node">
    		<c:out value="${node}"></c:out>
    	</c:forEach>
    	<br />
    	<br />
    
    
    	<!-- 输出Map -->
    	<c:forEach items="${map}" var="node">  
            姓名:<c:out value="${node.key}"></c:out>  
            住址:<c:out value="${node.value}"></c:out>
    		<br />
    	</c:forEach>
    </body>
    </html>

    这样,当我们请求连接为“login”时,我们将转到welcome.jsp页面,并显示我们在ModelAndView中存放的数据。

    二、@SessionAttributes
    如果我们希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注一个 @SessionAttributes, Spring MVC 将把模型中对应的属性暂存到 HttpSession 中。
    使用方法:
    @SessionAttributes(value={"xxx"}, types={xxxx.class})
    @SessionAttributes 除了可以通过属性名来指定放到会话中的属性外,还可以通过模型属性的对象类型指定哪些模型属性被放到会话中。
    使用举例:
    @SessionAttributes(types=User.class) 
    这个注解表示将隐含模型中所有类型为 User.class 的属性添加到会话中。
    @SessionAttributes(value={“user1”, “user2”}) 、
    添加两个属性
    @SessionAttributes(types={User.class, Dept.class})
    添加所有User.class和Dept.class类型的属性
    @SessionAttributes(value={“user1”, “user2”},types={Dept.class})
    添加两个属性,并添加所有Dept.class类型的属性。
    注意: 该注解只能放在类的上面. 而不能修饰放方法。
    使用示例:
    1、编写处理函数
    @SessionAttributes(value={"user"}, types={String.class})
    //该注解把名为user的属性放到了会话中,并把所有String类型的属性放到会话中。
    @Controller
    public class SpringMVCTest {
            @RequestMapping("/testSessionAttributes")
    	public String testSessionAttributes(Map<String, Object> map){
                    //假设已经定义了一个User,有姓名,密码,邮箱和年龄四个属性。
    		User user = new User("kang", "123456", "kang@qq.com", 24);
    		map.put("user", user);
    		map.put("school", "CETC");
    		return SUCCESS;
    	}
    }
    2、编写jsp页面
    这里不做描述,原理十分简单。

    三@ModelAttribute
    使用方式:
    1、在方法定义上使用 @ModelAttribute 注解,那么Spring MVC在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute 的方法。
    2、在方法的入参前使用 @ModelAttribute 注解,那么Spring MVC可以从隐含对象中获取到隐含的模型数据,并从中获取对象,再将请求参数绑定到对象中,再传入入参。从而将方法入参对象添加到模型中。
    使用示例:
    @Controller
    public class SpringMVCTest {
            @ModelAttribute
    	public void getUser(@RequestParam(value="id",required=false) Integer id, 
    			Map<String, Object> map){
    		System.out.println("modelAttribute method");
    		if(id != null){
    			//模拟从数据库中获取对象
    			User user = new User(1, "kang", "123456", "kang@qq.com", 24);
    			System.out.println("从数据库中获取一个对象: " + user);
    			
    			map.put("user", user);
    		}
    	}
            @RequestMapping("/testModelAttribute")
    	public String testModelAttribute(User user){
    		System.out.println("修改: " + user);
    		return SUCCESS;
            }
    }
    3、运行流程
    1)执行 @ModelAttribute 注解修饰的方法: 从数据库中取出对象, 把对象放入到了 Map 中。键为: user。
    2) SpringMVC 从 Map 中取出 User 对象, 并把表单的请求参数赋给该 User 对象的对应属性。
    3). SpringMVC 把上述对象传入目标方法的参数. 
    注意:在 @ModelAttribute 修饰的方法时, 放入到 Map 时的键(user)需要和目标方法入参类型(User)的第一个字母小写的字符串一致!
    4、SpringMVC 确定目标方法 POJO 类型入参的过程
    -----------如何确定一个 key---------
    1). 若目标方法的 POJO 类型的参数没有使用 @ModelAttribute 作为修饰, 则 key 为 POJO 类名第一个字母的小写。
    2). 若使用了  @ModelAttribute 来修饰, 则 key 为 @ModelAttribute 注解的 value 属性值。 
    -----------在 implicitModel 中查找 key 对应的对象-----------
    1)若存在, 则作为入参传入目标方法。
    2)若在 @ModelAttribute 标记的方法中在 Map 中保存过, 且 key 和 1 确定的 key 一致, 则会获取到。 
    3)若 implicitModel 中不存在 key 对应的对象, 则检查当前的 Handler 是否使用 @SessionAttributes 注解修饰。
    ---若使用了该注解, 且 @SessionAttributes 注解的 value 属性值中包含了 key, 则会从 HttpSession 中来获取 key 所对应的 value 值。若存在则直接传入到目标方法的入参中,若不存在则将抛出异常。
    ---若 Handler 没有标识 @SessionAttributes 注解或 @SessionAttributes 注解的 value 值中不包含 key, 则会通过反射来创建 POJO 类型的参数, 传入为目标方法的参数。
    最后SpringMVC 会把 key 和 POJO 类型的对象保存到 implicitModel 中, 进而会保存到 request 中。 


  • 相关阅读:
    pat 1034 Head of a Gang (30分)
    pta坑点
    Devc++ 编译 c++11
    Invitation Cards dijkstra法
    Cube Stacking
    畅通工程
    蚂蚁上树
    洛谷 P1439 【模板】最长公共子序列
    Recursive sequence
    A Simple Math Problem
  • 原文地址:https://www.cnblogs.com/kangsir/p/6653213.html
Copyright © 2011-2022 走看看