您的位置:首页 > 编程语言 > Java开发

springMVC之处理模型数据

2016-11-05 00:00 501 查看
SpringMVC提供了以下几种途径输出模型数据:

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

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

·@SessionAttributes:将模型中某个属性暂存到HttpSession中,以便多个请求之间可以共享这个属性

·ModelAttribute:方法入参标注注解后,入参的对象就会放到数据模型中

ModelAndView

·控制器处理方法的返回值如果为ModelAndView,则其既包含视图信息,也包含模型信息。

·添加模型数据:

-ModelAndView addObject(String attributeName,Object attributeValue)

-ModelAndView addAllObject(Map<Stirng,?>modelMap)

·设置视图

-void setView(View view)

-void setViewName(String viewName)

SpringMVC.java

package com.f145a.springmvc.handlers;

import java.util.Date;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {

private static final String SUCCESS="success";

/**
* 目标方法的返回值可以是ModelAndView类型
* 其中可以包含视图和模型信息
* SpringMVC会把ModelAndView的model中数据放入到request域对象中去
*/
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
String viewName=SUCCESS;
ModelAndView modelAndView = new ModelAndView(viewName);
//添加模型数据到ModelAndView中
modelAndView.addObject("time",new Date());
return modelAndView;
}
}

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>
<a href="springmvc/testModelAndView">testModelAndView</a>
</body>
</html>

success.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>
<h4>成功页面!</h4>
time:${requestScope.time}
</body>
</html>

Map及Model

·SpringMVC在内部使用了一个org.springframework.ui.Model接口存储模型数据

·具体步骤

-SpringMVC在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器。

-如果方法的入参为Map或Model类型。SpringMVC会将隐含模型的引用传递给这些入参。在方法体内,开发者可以通过这个入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据。

SpringMVC.java

package com.f145a.springmvc.handlers;

import java.util.Arrays;
import java.util.Date;
import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {

private static final String SUCCESS="success";

/**
* 目标方法可以添加Map类型(实际上也可以是Model类型或ModelMap类型)的参数
*/
@RequestMapping("/testMap")
public String testMap(Map<String,Object>map){
System.out.println(map.getClass().getName());
map.put("names",Arrays.asList("Tom","Jerry","Mike"));
return SUCCESS;
}
}

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>
<a href="springmvc/testMap">testMap</a>
</body>
</html>

success.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>
<h4>成功页面!</h4>
<br>
names:${requestScope.names}
</body>
</html>

@SessionAttributes

·若希望在多个请求之间共用某个模型属性数据,则可以在控制器类上标注一个@SessionAttributes,springMVC将在模型中对应的属性暂存到HttpSession中

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

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

-@SessionAttributes(value={“user1”,”user2”})

-@SessionAttributes(types={User.class,Dept.class})

-@SessionAttributes(value={“user1”,”user2”},types={Dept.class})

User.java

package com.f145a.springmvc.entities;

public class User {

private String username;
private String password;
private String email;
private int age;

public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password + ", email=" + email
+ ", age=" + age + "]";
}
public User(String username, String password, String email, int age) {
super();
this.username = username;
this.password = password;
this.email = email;
this.age = age;
}

public User(){

}
}

SpringMVC.java

package com.f145a.springmvc.handlers;

import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
import com.f145a.springmvc.entities.User;;

@SessionAttributes(value={"user"},types={String.class})
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {

private static final String SUCCESS="success";

/**
* @SessionAttributes除了可以通过属性名指定需要放到会话中的属性外(实际上使用的是value属性值)
* 还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中(实际上使用的是types属性值)
* 注意:该注解只能放类上,而不可放方法上
*
*/
@RequestMapping("/testSessionAttributes")
public String testSessionAttributes(Map<String,Object> map){
User user=new User("Tom","qwer","tom@qq.cpm",23);
map.put("user", user);
map.put("school", "beida");
return SUCCESS;
}
}

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>
<a href="springmvc/testSessionAttributes">testSessionAttributes</a>
</body>
</html>

success.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>
<h4>成功页面!</h4>
<br>
request user:${requestScope.user}
<br>
session user:${sessionScope.user}
<br>
request school:${requestScope.school}
<br>
session school:${sessionScope.school}
</body>
</html>

ModelAttribute



User.java

package com.f145a.springmvc.entities;

public class User {

private Integer id;
private String username;
private String password;
private String email;
private int age;

public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}

@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password=" + password + ", email=" + email + ", age="
+ age + "]";
}

public User(Integer id, String username, String password, String email, int age) {
super();
this.id = id;
this.username = username;
this.password = password;
this.email = email;
this.age = age;
}
public User(String username, String password, String email, int age) {
super();
this.username = username;
this.password = password;
this.email = email;
this.age = age;
}

public User(){

}
}

SpringMVC.java

package com.f145a.springmvc.handlers;

import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
import com.f145a.springmvc.entities.User;;

@SessionAttributes(value={"user"},types={String.class})
@RequestMapping("/springmvc")
@Controller
public class SpringMVCTest {

private static final String SUCCESS="success";

/**
* 1.有@ModelAttribute标记的方法,会在每个目标方法执行之前被SpringMVC调用!
* 2.@ModelAttribute注解也可以用来修饰目标方法POJO类型的入参,其属性值有如下的作用:
* >1.springMVC会使用value属性值在implicitModel中查找对应的对象,若存在则会直接传入到目标方法的入参中
* >2.springMVC会以value为key,POJO类型对象为value,存入到request中
*/
@ModelAttribute
public void getUser(@RequestParam(value="id",required=false)Integer id,
Map<String,Object> map){
if(id!=null){
//模拟从数据库中获取对象
User user=new User(1,"Tom","123456","tom@qq.com",23);
System.out.println("从数据库中获取一个对象:"+user);
map.put("user", user);
}
}

/**
* 运行流程:
* 1.执行@ModelAttribute注解修饰的方法:从数据库中取出对象,把对象放入到了Map中。键为:user
* 2.springMVC从Map中取出User对象,并把表单的请求参数赋给该User对象的对应属性
* 3.spring把上述对象传入目标方法的参数
* 注意:在@ModelAttribute修饰的方法中,放入到Map时的键需要和目标方法入参类型的第一个字母小写的字符串一致!
*
* springMVC确定目标方法POJO类型入参的过程
* 1.确定一个key
* >1.若目标方法的POJO类型的参数没有使用@ModelAttribute作为修饰,则key为POJO类名第一个字母的小写
* >2.若使用了@ModelAttribute来修饰,则key为@ModelAttribute注解的value属性值
* 2.在implicitModel中查找key对应的对象,若存在,则作为入参传入
* >1。若在@ModelAttribute标记的方法在Map中保存过,且key和已确定的key一致,则会获取到
* 3.若impliciyModel中不存在key对应的对象,则检查当前的Handler是否使用@SessionAttributes注解修饰,
* 若使用了该注解,且@SessionAttributes注解的value属性值中包含了key,则会从HttpSession中来获取key所
* 对应的value值,若存在则直接传入到目标方法的入参中,若不存在则将抛出异常
* 4.若Handler没有标示@SessionAttributes注解或@SessionAttributes注解的value值中不包含key,则
* 会通过反射来创建POJO类型的参数,传入为目标方法的参数
* 5.springMVC会把key和POJO类型的对象保存到implicitModel中,进而会保存到request中
*
* 源代码分析的流程
* 1.调用@ModelAttribute注解修饰的方法,实际上把@ModelAttribute方法中Map中的数据放在了implicitModel中,
* 2.解析请求处理器的目标参数,实际上该目标参数来自WebDataBinder对象的target属性
* >1.创建WebDataBinder对象:
* (1)确定objectName属性:若传入的attrName属性值为"",则objectName为类名第一个字母小写
* 注意:attrName,若目标方法的POJO属性使用了@ModelAttribute来修饰,则attrName值即为@ModelAttribute的value属性值
* (2)确定target属性:
* >在implicitModel中查找attrName对应的属性值,若存在,OK;*若不存在:则验证当前Handler是否使用了@SessionAttribute进行
* 修饰,若使用了,则尝试从Session中获取AttrName所对应的属性值,若session中没有对应的属性值,则抛出异常;若Handler没有使用
* @SessionAttribute进行修饰,或@SessionAttribute中没有使用value值指定的key和attrName相匹配,则通过反射创建POJO对象
* >2.springMVC把表单的请求参数赋给了WebDataBinder的target对应的属性
* >3.*springMVC会把WebDataBinder的attrName和target给implicitModel,进而传给request域对象中
* >4.把WebDataBingder的target作为参数传递给目标方法的入参
*/
@RequestMapping("/testModelAttribute")
public String testModelAttribute(User user){
System.out.println("修改:"+user);
return SUCCESS;
}
}

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>
<!-- 模拟修改操作
1.原始数据为:1,Tom,123456,tom@qq.com,23
2.密码不能被修改
3.表单回显,模拟操作直接在表单填写对应的属性值
-->
<form action="springmvc/testModelAttribute" method="post">
<input type="hidden" name="id" value="1" />
<br>
username:<input type="text" name="username" value="Tom" />
<br>
email:<input type="text" name="email" value="tom@qq.com"/>
<br>
age:<input type="text" name="age" value="23"/>
<br>
<input type="submit" value="submit">
</form>
</body>
</html>

欢迎访问我的个人博客http://www.chengzequn.top
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  springMVC