SpringMVC学习笔记(三) --- 参数绑定

1、参数绑定

需求:打开商品编辑页面,展示商品信息。

需求分析:

        编辑商品信息,需要根据商品id查询商品信息,然后展示到页面。
        请求的url:/itemEdit.action
        参数:id(商品id)
        响应结果:商品编辑页面,展示商品详细信息。

Service:

@Override
public Items getItemById(intid) {
		Items items = itemMapper.getItemById(id);
		return items;
}

Controller参数绑定:

要根据id查询商品数据,需要从请求的参数中把请求的id取出来。Id应该包含在Request对象中。可以从Request对象中取id。

@RequestMapping("/itemEdit")
	public ModelAndView itemEdit(HttpServletRequest request) {
		//从Request中取id
		String strId = request.getParameter("id");
		Integer id = null;
		//如果id有值则转换成int类型
		if (strId != null&& !"".equals(strId)) {
			id = newInteger(strId);
		} else {
			//出错
			return null;
		}
		Items items = itemService.getItemById(id);
		//创建ModelAndView
		ModelAndView modelAndView = new ModelAndView();
		//向jsp传递数据
		modelAndView.addObject("item", items);
		//设置跳转的jsp页面
		modelAndView.setViewName("editItem");
		return modelAndView;
	}

如果想获得Request对象只需要在Controller方法的形参中添加一个参数即可。Springmvc框架会自动把Request对象传递给方法。

2、默认支持的参数类型(处理器形参中添加如下类型的参数处理适配器会默认识别并进行赋值)

Ⅰ、HttpServletRequest

通过request对象获取请求信息

Ⅱ、HttpServletResponse

通过response处理响应信息

Ⅲ、HttpSession

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

Ⅳ、Model/ModelMap

ModelMap是Model接口的实现类,通过Model或ModelMap向页面传递数据,如下:

//调用service查询商品信息
Items item = itemService.findItemById(id);
model.addAttribute("item", item);

页面通过${item.XXXX}获取item对象的属性值。

使用Model和ModelMap的效果一样,如果直接使用Model,springmvc会实例化ModelMap,如果使用Model则可以不使用ModelAndView对象,Model对象可以向页面传递数据,View对象则可以使用String返回值替代。不管是Model还是ModelAndView,其本质都是使用Request对象向jsp传递数据。

如果使用Model则方法可以改造成:

@RequestMapping("/itemEdit")
	public String itemEdit(HttpServletRequest request, Model model) {
		//从Request中取id
		String strId = request.getParameter("id");
		Integer id = null;
		//如果id有值则转换成int类型
		if (strId != null&& !"".equals(strId)) {
			id = newInteger(strId);
		} else {
			//出错
			returnnull;
		}
		Items items = itemService.getItemById(id);
		//创建ModelAndView
		//ModelAndView modelAndView = new ModelAndView();
		//向jsp传递数据
		//modelAndView.addObject("item", items);
		model.addAttribute("item", items);
		//设置跳转的jsp页面
		//modelAndView.setViewName("editItem");
		//return modelAndView;
		return "editItem";
	}

3、绑定简单类型

当请求的参数名称和处理器形参名称一致时会将请求参数与形参进行绑定。从Request取参数的方法可以进一步简化。

@RequestMapping("/itemEdit")
	public String itemEdit(Integer id, Model model) {
		Items items = itemService.getItemById(id);
		//向jsp传递数据
		model.addAttribute("item", items);
		//设置跳转的jsp页面
		return "editItem";
	}

支持的简单数据类型:

参数类型推荐使用包装数据类型,因为基础数据类型不可以为null
整形:Integer、int
字符串:String
单精度:Float、float
双精度:Double、double
布尔型:Boolean、boolean
说明:对于布尔类型的参数,请求的参数值为true或false。
处理器方法:
public String editItem(Model model,Integer id,Boolean status) throws Exception
请求url:
http://localhost:8080/xxx.action?id=2&status=false

@RequestParam:

使用@RequestParam常用于处理简单类型的绑定。

value参数名字,即入参的请求参数名字,如value=“item_id表示请求的参数区中的名字为item_id的参数的值将传入;

required是否必须,默认是true,表示请求中一定要有相应的参数,否则将报错:

        TTP Status 400 - Required Integer parameter 'XXXX' is not present

defaultValue默认值,表示如果请求中没有同名参数时的默认值

定义如下:

public String editItem(@RequestParam(value="item_id",required=true) String id) {
	
}

形参名称为id,但是这里使用value="item_id"限定请求的参数名为item_id,所以页面传递参数的名必须为item_id。

注意:如果请求参数中没有item_id将跑出异常:

        HTTP Status 500 - Required Integer parameter 'item_id' is not present

这里通过required=true限定item_id参数为必需传递,如果不传递则报400错误,可以使用defaultvalue设置默认值,即使required=true也可以不传item_id参数值。

4、绑定Pojo类型

需求:将页面修改后的商品信息保存到数据库中

需求分析:

        请求的url:/updateitem.action
        参数:表单中的数据。
        响应内容:更新成功页面

使用pojo接收表单数据:

如果提交的参数很多,或者提交的表单中的内容很多的时候可以使用pojo接收数据。要求pojo对象中的属性名和表单中input的name属性一致。

页面定义如下:

<input type="text" name="name"/>
<input type="text" name="price"/>

pojo定义:

         

请求的参数名称和pojo的属性名称一致,会自动将请求参数赋值给pojo的属性。

@RequestMapping("/updateitem")
	public String updateItem(Items items) {
		itemService.updateItem(items);
		return "success";
	}

注意:提交的表单中不要有日期类型的数据,否则会报400错误。如果想提交日期类型的数据需要用到后面的自定义参数绑定的内容。

解决post乱码问题:

在web.xml中加入:

<filter>
		<filter-name>CharacterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>utf-8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>CharacterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
</filter>

以上可以解决post请求乱码问题。

对于get请求中文参数出现乱码解决方法有两个

(1)修改tomcat配置文件添加编码与工程编码一致,如下:

<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

(2)另外一种方法对参数进行重新编码:

String userName = new String(request.getParamter("userName").getBytes("ISO8859-1"),"utf-8");

ISO8859-1是tomcat默认编码,需要将tomcat编码后的内容按utf-8编码.

5、绑定包装pojo

需求:使用包装的pojo接收商品信息的查询条件

需求分析:

包装对象定义如下:

public class QueryVo {
private Items items;

}

页面定义:

<input type="text" name="items.name" />
<input type="text" name="items.price" />

Controller方法定义如下:

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

接收查询条件:

@RequestMapping("/queryitem")
	public String queryItem(QueryVo queryVo) {
		System.out.println(queryVo.getItems().getName());
		System.out.println(queryVo.getItems().getPrice());
		return null;
	}

6、绑定自定义参数

需求:在商品修改页面可以修改商品的生产日期,并且根据业务需求自定义日期格式

需求分析:由于日期数据有很多种格式,所以springmvc没办法把字符串转换成日期类型。所以需要自定义参数绑定。前端控制器接收到请求后,找到注解形式的处理器适配器,对RequestMapping标记的方法进行适配,并对方法中的形参进行参数绑定。在springmvc这可以在处理器适配器上自定义Converter进行参数绑定。如果使用<mvc:annotation-driven/>可以在此标签上进行扩展。

自定义Converter:

public class DateConverter implements Converter<String, Date> {

	@Override
	public Date convert(String source) {
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			return simpleDateFormat.parse(source);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}
}

配置Converter:

<!-- 加载注解驱动,一定要将自定义的转换器配置到注解驱动上-->
	<mvc:annotation-driven conversion-service="conversionService"/>
	<!-- 转换器配置 -->
	<bean id="conversionService"
		class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
		<propertyname="converters">
			<set>
                 <!--指定自定义转换器的全路径名称-->
				<beanclass="springmvc.convert.DateConverter"/>
			</set>
		</property>
	</bean>

配置Converter方式二:

<?xml version="1.0"encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

	<!-- 扫描带Controller注解的类 -->
	<context:component-scan base-package="springmvc.controller"/>
	
	<!-- 转换器配置 -->
	<bean id="conversionService"
		class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
		<propertyname="converters">
			<set>
				<bean class="springmvc.convert.DateConverter"/>
			</set>
		</property>
	</bean>
	<!-- 自定义webBinder -->
	<bean id="customBinder"	class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
		<property name="conversionService"ref="conversionService"/>
	</bean>
	<!--注解适配器 -->
	<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
		<property name="webBindingInitializer"ref="customBinder"></property>
	</bean>
	<!-- 注解处理器映射器 -->
	<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
	<!-- 加载注解驱动 -->
	<!-- <mvc:annotation-driven/> -->
	<!-- 视图解析器 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass"
			value="org.springframework.web.servlet.view.JstlView"/>
		<!-- jsp前缀 -->
		<property name="prefix"value="/WEB-INF/jsp/"/>
		<!-- jsp后缀 -->
		<property name="suffix"value=".jsp"/>
	</bean>
</beans>

7、绑定数组

需求:在商品列表页面选中多个商品,然后删除

需求分析:此功能要求商品列表页面中的每个商品前有一个checkbook,选中多个商品后点击删除按钮把商品id传递给Controller,根据商品id删除商品信息。

jsp中实现:

<c:forEach items="${itemList }" var="item">
<tr>
	<td><input name="ids" value="${item.id}" type="checkbox"></td>
	<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>

生成html代码如下:页面选中多个checkbox向controller方法传递

<table width="100%" border=1>
<tr>
	<td>商品名称</td>
	<td>商品价格</td>
	<td>生产日期</td>
	<td>商品描述</td>
	<td>操作</td>
</tr>
<tr>
	<td><input name="ids" value="1" type="checkbox"></td>
	<td>台式机</td>
	<td>3000.0</td>
	<td>2020-02-03 13:22:53</td>
	<td></td>
	<td><a href="/springmvc-web/itemEdit.action?id=1">修改</a></td>
</tr>
<tr>
	<td><input name="ids" value="2" type="checkbox"></td>
	<td>笔记本</td>
	<td>6000.0</td>
	<td>2020-02-09 13:22:57</td>
	<td></td>
	<td><a href="/springmvc-web/itemEdit.action?id=2">修改</a></td>
</tr>
<tr>
	<td><input name="ids" value="3" type="checkbox"></td>
	<td>背包</td>
	<td>200.0</td>
	<td>2020-01-06 13:23:02</td>
	<td></td>
	<td><a href="/springmvc-web/itemEdit.action?id=3">修改</a></td>
</tr>
</table>

Controller:Controller方法中可以用String[]接收,或者pojo的String[]属性接收。两种方式任选其一即可。定义如下:

@RequestMapping("/queryitem")
	public String queryItem(String[] ids) {
		System.out.println(ids.toString());
		return null;
	}

或者

                

@RequestMapping("/queryitem")
	public String queryItem(QueryVo queryVo) {
		System.out.println(queryVo.getItems().getName());
		System.out.println(queryVo.getItems().getPrice());
		System.out.println(queryVo.getIds());
		return null;
	}

查看结果:

               

8、将表单的数据绑定到List

需求:实现商品数据的批量修改

需求分析:要想实现商品数据的批量修改,需要在商品列表中可以对商品信息进行修改,并且可以批量提交修改后的商品数据。

接收商品列表的pojo:

                          

Jsp实现页面如下:

<c:forEach items="${itemList }" var="item">
<tr>
	<td><input name="ids" value="${item.id}" type="checkbox"></td>
	<td>
		<input name="id" value="${item.id}" type="hidden">
		<input name="name" value="${item.name }" type="text">
	</td>
	<td><input name="name" value="${item.price }" type="text"></td>
	<td><input name="name" value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>" type="text"></td>
	<td><input name="name" value="${item.detail }" type="text"></td>
	<td><a href="${pageContext.request.contextPath }/itemEdit.action?id=${item.id}">修改</a></td>
</tr>
</c:forEach>
varStatus属性常用参数总结下:
${status.index}      输出行号,从0开始。
${status.count}      输出行号,从1开始。
${status.current}   当前这次迭代的(集合中的)项
${status.first}  判断当前项是否为集合中的第一项,返回值为true或false
${status.last}   判断当前项是否为集合中的最后一项,返回值为true或false
begin、end、step分别表示:起始序号,结束序号,跳跃步伐。

Controller:

@RequestMapping("/queryitem")
	public String queryItem(QueryVo queryVo, String[] ids) {
		System.out.println(queryVo.getItems().getName());
		System.out.println(queryVo.getItems().getPrice());
		System.out.println(ids.toString());
		return null;
	}

注意:接收List类型的数据必须是pojo的属性,方法的形参为List类型无法正确接收到数据。

9、SpringMVC与Struts2的不同

  1. springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。

  2. springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。

  3. Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。

发布了57 篇原创文章 · 获赞 6 · 访问量 2581

猜你喜欢

转载自blog.csdn.net/qq_40640228/article/details/103847410
今日推荐