springmvc详解(三):注解开发基础和参数绑定

springmvc详解(三):注解开发基础和参数绑定

目录

springmvc详解(三):注解开发基础和参数绑定

一、什么是参数绑定

二、修改商品参数案例

2.1、功能需求

2.2、持久层开发(开发mapper.java和mapper.xml)

2.3、业务层开发(开发service接口和对应的实现类)

2.3.1、service接口

2.3.2、service接口的实现类

2.4、表现层(开发controller和jsp)

2.4.1、开发controller

2.4.2、开发jsp

三、参数绑定的类型

3.1、spring参数绑定过程

3.2、默认支持的参数绑定类型

3.3、简单类型

3.4、pojo类型

3.4.1、绑定规则:

3.4.2、自定义参数绑定实现日期类型绑定

3.5、包装pojo

3.6、集合类型

3.6.1、数组绑定

3.6.2、list绑定

3.6.3、map绑定

四、参数绑定总结


springmvc详解(二):springmvc和mybatis整合文章中我们已经初步完成了完成的配置和代码的编写,实现了请求查询商品的功能。接下来,我们将以在客户端修改商品参数并提交到后台的案例为媒介,讲解参数绑定的内容。

一、什么是参数绑定

客户在浏览器端会提交一些参数到服务器端,比如用户的登录等,就会传username 和 password过来,springmvc则通过参数绑定组件将请求参数的内容进行数据转换,然后将转换后的值赋给controller方法的形参,这就是参数绑定的过程,其实,springmvc就是使用controller方法形参来接收请求的参数。

二、修改商品参数案例

2.1、功能需求

springmvc详解(二):springmvc和mybatis整合文章中我们已经完成了商品的查询功能,现在我们在查询得到的商品页面上实现修改商品品参数的功能,即点击相应的修改按钮进入修改页面,修改结束后将所修改的结果提交到数据库并进行更新。

操作流程如下:

1、进入商品查询列表页面

2、点击修改,进入商品修改页面,页面中显示了要修改的商品(从数据库查询)

         要修改的商品从数据库查询,根据商品id(主键)查询商品信息

3、在商品修改页面,修改商品信息,修改后,点击提交

2.2、持久层开发(开发mapper.java和mapper.xml)

我们可以利用逆向工程所生成的单表的mapper.java和mapper.xml中的方法:(关于逆向工程的知识,详见MyBatis详解:逆向工程自动生成代码

1、根据id查询商品信息:Items.java中的Items selectByPrimaryKey(Integer id)方法

2、根据id更新Items表的数据:Items.java中的int updateByPrimaryKeyWithBLOBs(Items record)方法

2.3、业务层开发(开发service接口和对应的实现类)

2.3.1、service接口

package cn.itcast.ssm.service;

import java.util.List;

import cn.itcast.ssm.po.ItemsCustom;
import cn.itcast.ssm.po.ItemsQueryVo;

public interface ItemsService {
	//商品查询列表
	public List<ItemsCustom> findItemsList(ItemsQueryVo itemsQueryVo) throws Exception;
	
	
	//根据id查询商品信息(使用扩展类)
	public ItemsCustom findItemsById(Integer id) throws Exception;
	//修改商品信息
	public void updateItems(Integer id,ItemsCustom itemsCustom) throws Exception;
}

2.3.2、service接口的实现类

package cn.itcast.ssm.service.impl;

import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.itcast.ssm.mapper.ItemsMapper;
import cn.itcast.ssm.mapper.ItemsMapperCustom;
import cn.itcast.ssm.po.Items;
import cn.itcast.ssm.po.ItemsCustom;
import cn.itcast.ssm.po.ItemsQueryVo;
import cn.itcast.ssm.service.ItemsService;

@Service("itemsService")
public class ItemsServiceImpl implements ItemsService{
	@Autowired
	private ItemsMapperCustom itemsMapperCustom;
	@Autowired
	private ItemsMapper itemsMapper;

	//商品查询列表
	@Override
	public List<ItemsCustom> findItemsList(ItemsQueryVo itemsQueryVo) throws Exception {
		
		return itemsMapperCustom.findItemsList(itemsQueryVo);
	}

	//根据id查询商品信息(使用扩展类)
	@Override
	public ItemsCustom findItemsById(Integer id) throws Exception {
		Items items = itemsMapper.selectByPrimaryKey(id);
		//中间对商品信息进行业务处理
		//....
		//返回ItemsCustom
		ItemsCustom itemsCustom = new ItemsCustom();
		//将items的属性值拷贝到itemsCustom
		BeanUtils.copyProperties(items, itemsCustom);
		
		return itemsCustom;
	}

	//修改商品信息
	@Override
	public void updateItems(Integer id, ItemsCustom itemsCustom) throws Exception {
		//添加业务校验,通常在service接口对关键参数进行校验
		//校验 id是否为空,如果为空抛出异常
		
		//更新商品信息使用updateByPrimaryKeyWithBLOBs根据id更新items表中所有字段,包括 大文本类型字段
		//updateByPrimaryKeyWithBLOBs要求必须转入id
		itemsCustom.setId(id);
		itemsMapper.updateByPrimaryKeyWithBLOBs(itemsCustom);
	}
	
}

2.4、表现层(开发controller和jsp)

2.4.1、开发controller

package cn.itcast.ssm.controller;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import cn.itcast.ssm.po.Items;
import cn.itcast.ssm.po.ItemsCustom;
import cn.itcast.ssm.po.ItemsQueryVo;
import cn.itcast.ssm.service.ItemsService;

//商品的controller
@Controller
//为了对url进行分类管理 ,可以在这里定义根路径,最终访问url是根路径+子路径
//比如:商品列表:/items/queryItems.action
@RequestMapping("/items")
public class ItemsController {
	@Autowired
	private ItemsService itemsService;

        @RequestMapping(value="/editItems",method={RequestMethod.POST,RequestMethod.GET})
	//@RequestParam里边指定request传入参数名称和形参进行绑定。
	//通过required属性指定参数是否必须要传入
	//通过defaultValue可以设置默认值,如果id参数没有传入,将默认值和形参绑定。
	//1、默认支持的参数类型绑定2、简单类型的参数绑定
	public String editItems(Model model,@RequestParam(value="id",required=true) Integer items_id)throws Exception {
		
		//调用service根据商品id查询商品信息
		ItemsCustom itemsCustom = itemsService.findItemsById(items_id);
		
		//通过形参中的model将model数据传到页面
		//相当于modelAndView.addObject方法
		model.addAttribute("itemsCustom", itemsCustom);
		
		return "items/editItems";
	}
	
	//商品信息修改提交
	@RequestMapping("/editItemsSubmit")
	//3、pojo绑定
	public String editItemsSubmit(Model model,Integer id,
			ItemsCustom itemsCustom)throws Exception {
	//方法形参传入的是ItemsCustom,如果再传入一个User,他们有相同的属性name,此时页面传过来的input里面的name该和谁的水性绑定。
		//所以用包装类型作为形参更好

				
		//调用service更新商品信息,页面需要将商品信息传到此方法
		itemsService.updateItems(id, itemsCustom);
		return "success";
	}
}

在controller的商品信息修改页面显示和商品信息修改提交两个方法如下:

 

这两个方法的形参其实就是通过参数绑定所实现的,修改某个商品的参数需要先跳到修改页面显示出该商品的当前参数,其中调用的就是业务层的根据id查询商品信息方法;修改完商品参数以后需要将新的商品信息提交到数据库进行更新,商品信息修改提交方法调用的就是业务层的根据id更新Items表的数据。

我们需要讲解得就是如何实现参数绑定,editItems方法中涉及到默认支持的参数绑定类型(Model model)和简单类型的参数绑定(@RequestParam(value="id",required=true) Integer items_id),editItemsSubmit方法涉及到默认支持的参数绑定类型(Model model)和简单类型(Integer id)和pojo类型(ItemsCustom itemsCustom)的参数绑定。详见下面三、参数绑定的类型。

2.4.2、开发jsp

跳转到单个商品信息修改页面的jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix="fmt"%>
<!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>修改商品信息</title>

</head>
<body> 
<!-- 显示错误信息 -->
<c:if test="${allErrors!=null }">
	<c:forEach items="${allErrors }" var="error">
	${ error.defaultMessage}<br/>
</c:forEach>
</c:if>
<form id="itemForm" action="${pageContext.request.contextPath }/items/editItemsSubmit.action" method="post" >
<input type="hidden" name="id" value="${itemsCustom.id }"/>
修改商品信息:
<table width="100%" border=1>
<tr>
	<td>商品名称</td>
	<td><input type="text" name="name" value="${itemsCustom.name }"/></td>
</tr>
<tr>
	<td>商品价格</td>
	<td><input type="text" name="price" value="${itemsCustom.price }"/></td>
</tr>
<tr>
	<td>商品生产日期</td>
	<td><input type="text" name="createtime" value="<fmt:formatDate value="${itemsCustom.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>"/></td>
</tr>
<%-- <tr>
	<td>商品图片</td>
	<td>
		<c:if test="${item.pic !=null}">
			<img src="/pic/${item.pic}" width=100 height=100/>
			<br/>
		</c:if>
		<input type="file"  name="pictureFile"/> 
	</td>
</tr> --%>
<tr>
	<td>商品简介</td>
	<td>
	<textarea rows="3" cols="30" name="detail">${itemsCustom.detail }</textarea>
	</td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="提交"/>
</td>
</tr>
</table>

</form>
</body>

</html>

修改商品信息成功提交后的页面jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>成功提示</title>
</head>
<body>
操作成功!
</body>
</html>

 

三、参数绑定的类型

3.1、spring参数绑定过程

从客户端请求key/value数据,经过参数绑定,将key/value数据绑定到controller方法的形参上。springmvc中,接收页面提交的数据是通过方法形参来接收。而不是在controller类定义成员变量接收!!!!(servlet是这种方式)

其原理如下:

需要重点说明的是:spring参数绑定过程是处理器适配器调用springmvc提供参数绑定组件将key/value数据转成controller方法的形参(先转成形参,再赋给形参),这一过程都是spring帮我们自动完成的,我们只需要遵守规则(即下面讲解的不同类型的参数在controller方法的形参处该如何绑定)

3.2、默认支持的参数绑定类型

直接在controller方法形参上定义下边类型的对象,就可以使用这些对象,适配器调用参数绑定组件直接进行绑定。在参数绑定过程中,如果遇到下边类型直接进行绑定。可以看到2.4.1中都用到了默认支持的Model。

1、HttpServletRequest

通过request对象获取请求信息

2、HttpServletResponse

通过response处理响应信息

3、HttpSession

通过session对象得到session中存放的对象

4、Model/ModelMap

model是一个接口,modelMap是一个接口实现 。

作用:将model数据填充到request域。

 

2.4.1中的editItems方法和editItemsSubmit方法都用到了Model。

3.3、简单类型

简单类型包括:Integer、String、Float、Long、Double等类型,但不包括日期类型(日期类型会单独讲解)

绑定规则:

通过@RequestParam对简单类型的参数进行绑定。

如果不使用@RequestParam,要求request传入参数名称和controller方法的形参名称一致,方可绑定成功。

如果使用@RequestParam,不用限制request传入参数名称和controller方法的形参名称一致。

通过required属性指定参数是否必须要传入,如果设置为true,没有传入参数,报下边错误:

2.4.1中的editItems方法的形参:

对应于itemsList.jsp中的提交按钮:

若不使用@RequestParam,则editItems方法的形参需要和request传入参数名称为id保持一致;而使用了@RequestParam就可以将request传入参数名称为id与editItems方法的形参Integer items_id进行对应,达到修改参数名称的效果。

3.4、pojo类型

3.4.1、绑定规则:

pojo作为controller的形参时,jsp页面中inputnamecontrollerpojo形参中的属性名称一致,即可将页面中数据绑定到pojo

2.4.1中editItemsSubmit方法的形参ItemsCustom itemsCustom即为pojo类型(继承自逆向工程生成的items),对应关系如下

jsp页面定义:商品信息修改页面editItems.jsp

controller的pojo形参ItemsCustom的定义:(由于ItemsCustom继承自逆向工程生成的Items,故ItemsCustom的属性和Items中的属性相同)

3.4.2、自定义参数绑定实现日期类型绑定

对于controller形参中pojo对象,如果属性中有日期类型,需要自定义参数绑定。

将请求日期数据串传成日期类型,要转换的日期类型和pojo中日期属性的类型保持一致。

所以自定义参数绑定将日期串转成java.util.Date类型。需要向处理器适配器中注入自定义的参数绑定组件。

自定义的日期类型的转换器:

package cn.itcast.ssm.controller.converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.core.convert.converter.Converter;

public class CustomDateConverter implements Converter<String,Date>{

	@Override
	public Date convert(String source) {
		
		//实现 将日期串转成日期类型(格式是yyyy-MM-dd HH:mm:ss)
		
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		
		try {
			//转成直接返回
			return simpleDateFormat.parse(source);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//如果参数绑定失败返回null
		return null;
	}

}

在springmvc的配置文件spring.xml中配置自定义的日期类型的转换器:

3.5、包装pojo

这里我们对2.4.1中的查询商品列表方法进行讲解。

quertItems方法的形参ItemsQueryVo即为包装pojo类型(其属性为pojo)

绑定规则:

包装pojo作为controller的形参时,jsp页面中inputname包装pojo中的pojo.属性名称一致,即可将页面中数据绑定到pojo

jsp页面定义:下旬商品信息页面itemsList.jsp

controller的包装pojo形参ItemsQueryVo的定义:

包装pojo形参ItemsQueryVo的pojo属性ItemsCustom的定义:

 

3.6、集合类型

关于集合类型的参数绑定,为了简单起见,我们主要讲解表现层的controller和jsp是如何实现参数绑定的。而业务层和持久层的具体方法就不做赘述了。

3.6.1、数组绑定

针对数组绑定我们实现商品批量删除功能,用户在页面选择多个商品,批量删除。

controller方法定义:

// 批量删除 商品信息(数组绑定)
	@RequestMapping("/deleteItems")
	public String deleteItems(Integer[] items_id) throws Exception {//简单类型参数绑定(数组)

		// 调用service批量删除商品
		// ...

		return "success";

	}

jsp页面定义:

3.6.2、list绑定

针对list绑定实现批量商品修改功能,在页面输入多个商品信息,将多个商品信息提交到controller方法中。

功能实现分析:

1、进入批量商品修改页面(editItemsQuery.jsp),在次页面通过查询商品列表功能,将所有商品信息显示出来

 2、通过批量修改商品提交功能将修改后的商品数据提交到数据库。

通常在需要批量提交数据时,将提交的数据绑定到list<pojo>中,比如:成绩录入(录入多门课成绩,批量提交)。

故使用List接收页面提交的批量数据,通过包装pojo接收,在包装pojo中定义list<pojo>属性

controller方法定义:

List接收页面提交的批量数据,定义在在包装pojo中中的list<pojo>属性,故editItemsAllSubmit方法传入的形参为包装pojo

// 批量修改商品页面,将商品信息查询出来,在页面中可以编辑商品信息
	@RequestMapping("/editItemsQuery")
	public ModelAndView editItemsQuery(HttpServletRequest request,
			ItemsQueryVo itemsQueryVo) throws Exception {

		// 调用service查找 数据库,查询商品列表
		List<ItemsCustom> itemsList = itemsService.findItemsList(itemsQueryVo);

		// 返回ModelAndView
		ModelAndView modelAndView = new ModelAndView();
		// 相当 于request的setAttribut,在jsp页面中通过itemsList取数据
		modelAndView.addObject("itemsList", itemsList);

		modelAndView.setViewName("items/editItemsQuery");

		return modelAndView;

	}

	// 批量修改商品提交(List绑定,将list封装在包装类型的属性中)
	// 通过ItemsQueryVo接收批量提交的商品信息,将商品信息存储到itemsQueryVo中itemsList属性中。
	@RequestMapping("/editItemsAllSubmit")
	public String editItemsAllSubmit(ItemsQueryVo itemsQueryVo)
			throws Exception {

		return "success";
	}

jsp页面定义:

3.6.3、map绑定

在包装类中定义Map对象,并添加get/set方法,action使用包装对象接收。

包装类中定义Map对象如下:

Public class QueryVo {
private Map<String, Object> itemInfo = new HashMap<String, Object>();
  //get/set方法..
}

controller方法定义:

public String useraddsubmit(Model model,QueryVo queryVo)throws Exception{
System.out.println(queryVo.getStudentinfo());
}

页面定义如下:

<tr>
<td>学生信息:</td>
<td>
姓名:<inputtype="text"name="itemInfo['name']"/>
年龄:<inputtype="text"name="itemInfo['price']"/>
.. .. ..
</td>
</tr>

 

四、参数绑定总结

既然springmvc帮我们自动将jsp页面提交的数据绑定到controller方法的形参中,免去了Servlet那样在方法内部通过局部变量从request处获取,我们就要遵循一定的映射规则,这样springmvc才能帮助我们自动绑定。从简单类型到pojo再到包装pojo再到集合,是主键复杂的过程,要遵循一层一层的嵌套,且在嵌套过程中要满足jsp页面中的input标签内的name和controller方法的形参的属性名称保持一致。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值