SpringMVC(3)学习笔记

本文深入解析SpringMVC中的参数绑定机制,包括基本类型、POJO、数组、List和Map的绑定,以及@RequestParam注解的使用。同时,详细介绍了@Controller的返回值类型,如ModelAndView、void和String,及其应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引入:在实际开发中,控制层需要接收从浏览器提交的数据,通过该数据调用服务层去处理。那么,其是如何实现的呢?

1.SrpingMvc的参数绑定

理解:当浏览器选择提交(GET/POST等)方式,究竟提交的是哪些东西?

1)GET方式提交

GET /day09/testMethod.html?name=eric&password=123456 HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,en-us;q=0.8,zh;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/day09/testMethod.html
Connection: keep-alive
  • a)地址栏(URI)会跟上参数数据。以?开头,多个参数之间以&分割。
  • b)GET提交参数数据有限制,不超过1KB。
  • c)GET方式不适合提交敏感密码。
  • d)注意: 浏览器直接访问的请求,默认提交方式是GET方式

2)POST方式提交

POST /day09/testMethod.html HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,en-us;q=0.8,zh;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://localhost:8080/day09/testMethod.html
Connection: keep-alive

name=eric&password=123456

  • a)参数不会跟着URI后面。参数而是跟在请求的实体内容中。没有?开头,多个参数之间以&分割。
  • b)POST提交的参数数据没有限制。
  • c)POST方式提交敏感数据。
1.1基本参数类型(int,double,Integer,String…)

1.可以使用request获取参数

  • View对象可以使用String返回值代替
  • 【ModelMap:使用效果与Model相同,是Model接口的实现类,如果使用的是Model,springmvc会将其实例化】
  • 【不管是Model还是ModelAndView,其本质都是使用Request对象向jsp传递数据】
	@RequestMapping("itemEdit")
	public String queryItemById(HttpServletRequest request,Model model){
		Integer id = Integer.parseInt(request.getParameter("id"));
		Item item = itemService.queryItemById(id);
		//将商品数据放在模型中
		model.addAttribute("item", item);
		//要返回的视图对象(返回到哪一个jsp页面)
		return "itemEdit";
}

但是我们一直使用request获取麻烦了,当请求参数名称处理器形参参数名称一致时,将会请求参数进行绑定

  • (参数绑定)接收简单的参数传递(每次都从Request获取比较麻烦)
  • 其他基本类型 String Integer Double Float。。
  • 说明:对于布尔类型的参数,请求的参数值为true或false。或者1/0
  • 请求url:http://localhost:8080/xxx.action?id=2&status=false
  • 处理器方法:public String editItem(Model model,Integer id,Boolean status)
  • 【注:必须要求处理器形参与表单中的提交name字段名称相同】后面介绍不同如何处理
@RequestMapping("itemEdit")
	public String queryItemById(int id,Model model){
		Item item = itemService.queryItemById(id);
		//将商品数据放在模型中
		model.addAttribute("item", item);
		//要返回的视图对象(返回到哪一个jsp页面)
		return "itemEdit";
}

那么问题来了,当我们处理器形参参数与请求参数不一致时咋办呢?

  • @RequestParam
  • value:参数名字,需要与表单提交的名字相同
<a href="${pageContext.request.contextPath }/itemEdit.action?id123=${item.id}">
  • required:默认true,Request请求中一定要有相应的参数,找不到将报错400
  • defaultValue:默认值,如果找不到给其一个默认值
@RequestMapping("itemEdit")
public String queryItemById(@RequestParam(value="id123",required=true,defaultValue="1")int ids,Model model){
		Item item = itemService.queryItemById(ids);
		//将商品数据放在模型中
		model.addAttribute("item", item);
		//要返回的视图对象(返回到哪一个jsp页面)
		return "itemEdit";
	}
1.2 POJO类型(对象类型)

如果我们一次性提交的参数很多,我们可以使用一个对象来接收

要求:pojo对象的属性名与表单中的input的name一致

  • 需求:将页面修改后的商品保存在数据库中
  • 请求url:/updateItem.action
  • 响应内容:给一个更新成功的提示
@RequestMapping("/updateItem.action")
public String queryItemById(Model model,Item item){
		itemService.update(item);
		//将商品数据放在模型中
		model.addAttribute("item", item);
		//返回一个成功的信息
		model.addAttribute("msg", "商品信息更新成功");
		//要返回的视图对象(返回到哪一个jsp页面)
		return "itemEdit";
}
1.3封装的POJO(自定义实体类)

封装类:

public class QueryVo {
	private Item item;
	private String message;
	private List<Item> items;
  .
  .
  .get/set方法...
  • 通过成员.属性来访问
  • 需要更改表单的传递形式
@RequestMapping("/queryItem")
	public String queryItem(Model model,QueryVo item){
		//直接输出返回的封装对象的值
		System.out.println(item.getItem().getName());
		System.out.println(item.getItem().getPrice());
		System.out.println(item.getMessage());
		List<Item> list = itemService.queryItemList();
		model.addAttribute("itemList", list);
		return "itemList";
}

对应的表单:

<c:forEach items="${itemList }" var="item">
   <tr>
		<td>${item.name }</td>
		<td>${item.price }</td>
		<td><fmt:formatDate value="${item.createtime}"pattern="yyyy-MM-dd HH:mm:ss" /></td>
		<td>${item.detail }</td>
    <td><a href="${pageContext.request.contextPath }/itemEdit.action?id=${item.id}">修改</a></td>
    </tr>
</c:forEach>
1.4数组

情景:列表中每个商品前有一个checkbook,选中多个商品后点击删除按钮,把商品id传递给Controller,得到一个ids[]

springmvc参数绑定数组jsp

  • 可以直接接收或使用pojo属性接收,前者相当于是用一个数组接收了多个ids(JSP里的name属性),后者是直接对应pojo的属性
@RequestMapping("/queryItem")
	public String queryItem(Model model,int[]ids,QueryVo vo){
		if(vo.getItem()!=null){
			System.out.println(vo);
		}
		//问题:checkbox如果不选,则返回空指针异常,不知道咋整
		//直接输出返回的封装对象的值
		if(ids.length>0 && ids!=null){
			for (Integer integer : ids) {
				System.out.println(integer);
			}
		}
		List<Item> list = itemService.queryItemList();
		model.addAttribute("itemList", list);
		return "itemList";
}
1.5List、Map类型

场景需求:在类表中实现批量修改提交后的商品数据

  • 定义pojo
public class QueryVo {
	private Item item;
	private String message;
	private List<Item> items;
  ...
  • 修改jsp
    name属性必须是list属性名+下表+元素属性
    注:此处日期类型无妨自动绑定,需要自定义参数绑定日期类型
<c:forEach items="${itemList }" var="item" varStatus="s">
  <tr>
    <td><input type="checkbox" name="ids" value="${item.id }" /></td>
    <td><input type="text" name="items[${s.index}].name"value="${item.name }" /></td>
    <td><input type="text" name="items[${s.index}].price" value="${item.price }" /></td>
    <td><input type="text" name="items[${s.index}].createtime"value='<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss" />' /></td>
    <td><input type="text" name="items[${s.index}].detail" value="${item.detail }" /></td>
    <td><a href="${pageContext.request.contextPath }/itemEdit.action?id=${item.id}">修改</a></td>
  </tr>
</c:forEach>

返回的是一个List的集合,在jsp显示中,需要先将单个对象取出,故需要加下标访问。

@RequestMapping(value="/queryItem",method={RequestMethod.POST})
	public String queryItem(Model model,QueryVo vo){
		List<Item> items = vo.getItems();
		//注意:如果进行更新操作,那么需要更改jsp,把id传给vo中的item,不然没有主键无法更新
		for (Item item : items) {
			itemService.update(item);
			System.out.println(item);
		}
		List<Item> itemList = itemService.queryItemList();
		model.addAttribute("itemList", itemList);
		//这个return是跳转到/WEB-INF/下面的jsp页面,而不是跳转到控制器的URL因是个很
		return "itemList";
	}

2.@RequestMapping

作用:通过@RequestMapping注解可以定义不同的处理器映射规则

  • URL路径映射

value的值是数组,将多个url映射到同一个方法上

@RequestMapping(value={"/itemList","/itemList2"})
  • 添加在类上

作用:指定通用请求前缀,可对url进行分类管理

此时访问地址为:http://localhost:8080/item/itemList.action

@RequestMapping("/item")
public class ItemController {
	//绑定请求地址
	@RequestMapping(value={"/itemList","/itemList2"})
	public ModelAndView queryItemList(){
  • 限定请求方法
@RequestMapping(value="/queryItem",method={RequestMethod.POST})

3.Controller的返回值

3.1返回ModelAndView
@RequestMapping("/itemList")
	public ModelAndView queryItemList(){
		List<Item> list = itemService.queryItemList();
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject("itemList",list);
		//设置逻辑视图,告诉要返回到哪一个jsp
		modelAndView.setViewName("itemList");
		return modelAndView;
	}
3.2返回void
  • request

不经过视图解析器的,返回路径必须是全路径

@RequestMapping("/itemReturn1")
	public void MyReturn1(HttpServletRequest request,HttpServletResponse response) throws Exception{
	//通过request请求转发,不会改变URL的地址栏
	request.getRequestDispatcher("/WEB-INF/jsp/itemList.jsp").forward(request, response);
}
  • response

    • 通过response请求重定向
    • 【注:】response.sendRedirect("");
    • 参数是URL,即浏览器中的地址

response是响应,而Model返回,经过视图解析器,springmvc已经帮我们解码了,区别:一个是直接找到jsp,另外一个是找到一个控制类/

@RequestMapping("/itemReturn1")
	public void MyReturn1(HttpServletRequest request,HttpServletResponse response) throws Exception{
		response.sendRedirect("/itemList.action");
	}
3.3返回String
  • 返回视图名字(逻辑视图名)

返回的通过视图解析器解析为物理视图地址
/WEB-INF/jsp/itemList.jsp
return “itemList”

    • Model传递数据(向jsp)
    • View对象可以使用String返回值代替
    • ModelMap:使用效果与Model相同,是Model接口的实现类,如果使用的是Model,springmvc会将其实例化
    • 不管是Model还是ModelAndView,其本质都是使用Request对象向jsp传递数据】
@RequestMapping("itemEdit")
	public String queryItemById(HttpServletRequest request,Model model){
		Integer id = Integer.parseInt(request.getParameter("id"));
		Item item = itemService.queryItemById(id);
		//将商品数据放在模型中
		model.addAttribute("item", item);
		//要返回的视图对象(返回到哪一个jsp页面)
		return "itemEdit";
}
  • redirect与forward

实现从一个控制器跳转到另外一个控制器

@RequestMapping("/itemReturn2")
	public String MyReturn2(){
      //相当于走的视图解析器,直接访问jsp页面
      //return "itemList";
      //相当于走的视图解析器,直接访问jsp页面
      //return "forward:/WEB-INF/jsp/itemList.jsp";
      /**
      * 这种形式是直接跳转到另外控制器Controller
      */
      return "forward:/itemList2.action";//请求地址不会变
      //return "redirect:/itemList2.action";
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值