SpringMVC-输出模型数据

1.传入servlet原生API作为参数

可以在SpringMVC方法传入原生的HttpServletRequest和HttpSession
使用setAttribute(String name,Object o)、getAttribute(String name)来携带数据,在JSP处输出

demo

@RequestMapping("testServletApi")
public String testServletApi(HttpServletRequest request, HttpSession session){
	request.setAttribute("msg", "这是request");
	session.setAtribute("msg", "这是session");
	return "success"
}

在 success.jsp中
request: ${requestScope.msg}<br/>
session: ${sessionScope.msg}<br/>

2.传入Map、Model或者ModelMap

可以在方法传入Map、Model或者ModelMap作为参数
通过setAttribute(String name,Object o)、getAttribute(String name)来携带参数

给这些参数里面保存的所有数据都会放在request请求域中,可以在页面获取

Map、Model与ModelMap之间的关系:
在这里插入图片描述
在这里插入图片描述

无论传入的参数是Map, Model或ModelMap,其最终都是BindingAwareModelMap在工作
相当于BindingAwareModelMap中保存的东西会被放在request请求域中

3.ModelAndView

控制器处理方法的返回值如果为 ModelAndView, 则其既包含视图信息,也包含模型数据信息,且数据是放在request请求域中

  • 添加模型数据
    MoelAndView addObject(String attributeName, Object attributeValue)

  • 设置视图
    void setViewName(String viewName)

demo:

@RequestMapping("/hello")
public ModelAndView handle_hello(){
	ModelAndView mv = new ModelAndView();
	mv.setViewName("success");
	/*
		使用有参构造器传入view名称 ModelAndView mv = new ModelAndView("success");可以省略设置视图
		return String 返回的叫做视图名,视图解析器会帮助我们拼接处最终的页面真实地址009
	*/
	mv.addObject("msg","你好鸭");
}

4.ModelAttribute注解

使用场景:书城的图书修改为例

  1. 网页端
    显示要修改的图书信息

  2. servlet收到修改请求,调用dao
    String sql="update bs_book set bname=?, author=?
    , price=? ,sales=?, stock=?, img_path=?
    where id=? "

  3. 并不是全部字段都修改,有些信息属于不可变的(例如书名bname)
    1).不修改的字段可以在页面进行展示但不要提供修改输入框
    2).为了简单,Contrller直接在参数位置来写Book对象(传入一个javabean,由SpringMVC自动根据请求参数来对javabean属性赋值)
    3).SpringMVC为我们自动封装book(请求中没有带的值为null)
    4).如果接下来调用一个全字段更新的DAO操作,可能会导致某个字段为Null

针对上述问题,解决方案有:

  1. 为每个请求编写一个特定的dao,但这样会出现大量冗余代码
  2. 在html页面的input标签中带上这些字段,设置type=“hidden”,但引入的新的漏洞(在浏览器中更改了该字段的值,或者更严重的是在REST风格中将post或put请求方法修改成delete请求方法)
  3. 使用ModelAttribute注解

在这里插入图片描述

ModelAttribute注解让SpringMVC在封装请求参数的Book对象时,不是new出来,而是先从数据库中读取数据,赋值给JavaBean,然后再根据请求参数对其覆盖,保证不会出现null

@ModelAttribute注解到方法上,这个方法就会提前于目标方法先运行
因此可在注解的方法中先创建JavaBean,并从数据库中读取数据进行赋值,然后将这个JavaBean对象放入Map(或 Model 或 ModelMap)中

demo:

//类范围变量 Object globle_01

@ModelAttribute
public void testModelAttribute(Map<String, Object> map) {
	Book book = new Book();
	/*
		从数据库中查询数据,并赋值给book
	*/
	map.put("test1", book);
	globle_01 = map;
}




@RequestMapping("/testModelAttribute")
public String handle(@ModelAttribute("test1")Book book, Model model){
	/*
		@ModelAttribute("test1") Book book 注解到参数上表示
		告诉SpringMVC,该book对象不必new,而是从BindingAwareModelMap以key="test1"取出
		并自动将请求中携带的参数赋值(覆盖)给book
	*/
	
	System.out.println("map == model ?" + (globle_01 == model));
	/*
		结果为true
	*/
	
	Object haha = model.getAttribute("test1");
	System.out.println("book == haha ?" + (book == haha));
	/*
  		结果为true
	 */
 
}

注意:

  1. ModelAttribute标注的方法会运行在controller方法之前,所以controller可以从参数列表获取的参数,ModelAttribute方法也可以以同样的方法获取
  2. ModelAttribute方法运行在所有controller方法之前,所以需要从请求时获取参数时,推荐使用@RequestParam且required=false确保请求中没有携带该属性时不会保存

5.BindingAwareModelMap的一个细节

在一次请求中,无论是使用Map、Model或者ModelMap创建一个请求域的map,或者@ModelAttribute(“xxx”) Obecjt object来告诉SpringMVC从 BindingAwareModelMap 中获取object对象,其本质都是在对同一 BindingAwareModelMap 实例进行存取

即一个请求中只会创建一个 BindingAwareModelMap 实例

6.SpringMVC确定自定义参数值的流程

  1. 标注解:保存注解的信息;最终得到这个注解应该对应解析的值(如@Autowire)
  2. 没标注解:
    • 看是否是原生API(如HttpServletRequest)
    • 看是否是Model或者是Map(赋值BindingAwareModelMap)
    • 都不是,看是否是简单类型
    • 也不是,那么
      1).先去隐含模型中(BindingAwareModelMap中)查找,如果标注了@ModelAttribute(“xxx”),那么就按key=xxx去查找;没有标注,就使用key=参数的类型首字母小写查找
      2).如果标注了@SessionAttribute(),那么就去session中查找(这里找不到会报异常,慎用)
      3).没找到,那么就通过反射创建一个
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值