SpringMVC学习笔记(四)—— Spring MVC 参数绑定

版权声明:转载请注明来源 https://blog.csdn.net/qq_24598601/article/details/84997529

一、前言

  在上一篇博客的基础上,学习参数绑定,即,前端传参到后端。SpringMVC学习笔记(三)——整合 Mybatis(详细讲解搭建ssm框架)

二、Controller 方法的返回值类型

1. 返回 ModelAndView

  在 Controller 方法中定义 ModelAndView 对象,对象中可添加 Model 数据和指定 View,最后返回。

2. 返回 Void

2.1 通过使用 request 转向页面,如下:request.getRequestDispatcher("").forward(request, response);

2.2 通过使用 response 页面重定向:response.sendRedirect("url");

2.3 通过使用 response 指定响应结果,例如响应 JSON 数据如下:response.setCharacterEncoding("utf-8"); response.setContentType("application/json;charset=utf-8"); response.getWriter().write("json串");

3. 返回 String

3.1 单纯返回一个字符串,则这个字符串就是逻辑视图名,最后会通过视图解析器解析为物理视图(前缀 + 逻辑视图名 + 后缀)地址。

3.2 字符串前加“redirect:”,例如:return "redirect:queryItem.action";表示重定向,相当于response.sendRedirect()

3.3 字符串前加“forward:”,例如:return "forward:queryItem.action";表示转发,相当于request.getRequestDispatcher("").forward(request,response)

三、参数绑定介绍

  Spring MVC 的参数绑定是将接收到的前端提交的数据(key/value形式)通过方法的形参来接收(struts2 是通过类的成员变量来结构)。参数绑定过程:在处理器适配器调用 Spring MVC 提供参数绑定组件 converter (3.0 版本前是 PropertyEditor )将 key/value 数据转成 Controller 方法的形参。我们可以自定义 converter 。比如日期类型绑定。

1. 默认支持的参数绑定类型

  具体默认支持的参数类型有:HttpServletRequest、HttpServletResponse、HttpSession、Model / ModelMap。前三个是三大对象,后一个的 Model 是接口, ModelMap 是 Model 的实现类,可通过 addAttribute() 方法向页面传值。

  通过在 Controller 中的 queryItems 方法加入形参,代码演示:

//商品查询
@RequestMapping("/queryItems")
public String queryItems(HttpServletRequest request, HttpServletResponse response,HttpSession session, Model model) throws Exception {
	
	System.out.println(request);
	System.out.println(response);
	System.out.println(session);
	//1.调用service 查找数据库的商品查询
	List<ItemsCustom> itemsList = itemService.findItemsList(null);
	model.addAttribute("itemsList", itemsList);
	
	return "itemsList";
}

  控制台输出:

org.apache.catalina.connector.RequestFacade@65144694
org.apache.catalina.connector.ResponseFacade@1625d264
org.apache.catalina.session.StandardSessionFacade@d17ae98

  通过获取这几个默认对象,可以进行各种操作,比如重定向,返回 json 数据等等。

2. 简单类型的参数绑定

  简单类型的数据绑定包括有 Integer、String、Double、Float、Boolean,具体的绑定方法是直接在方法中定义形参即可,形参名和前端传入的变量名一致,如果不一致可以使用注解 @RequestParam 对形参进行注解,其源码是:

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {

	@AliasFor("name")
	String value() default "";

	@AliasFor("value")
	String name() default "";

	boolean required() default true;
	
	String defaultValue() default ValueConstants.DEFAULT_NONE;

}

  当形参名和传入的变量名一致时可以省略注解 @RequestParam,但是如果不一致,就必须标注。
  格式:
    @RequestParam([value=]变量名,[…]) 形参类型 形参名
  参数:
    value :变量名,即入参的请求参数名字,如 value=“item_id”表示请求的参数中的名字为 item_id 的参数的值将传入;
    required :是否必须传入,默认为true;
    defaultValue :默认值,表示如果请求中没有同名参数时的默认值。
  作用:
    1. URL路径映射;
    2. 窄化映射请求,注解在类上设置请求前缀;
    3. 请求方法限定,例如 method=RequestMethod.GET。

参数绑定演示:
1.访问传参:http://localhost:8080/ssm/items/queryItems.action?items_id=1
2.代码演示:

//商品查询
@RequestMapping("/queryItems")
public String queryItems(@RequestParam("items_id") Integer items_id, Model model) throws Exception {
	System.out.println("items_id = " + items_id);
	//1.调用service 查找数据库的商品查询
	List<ItemsCustom> itemsList = itemService.findItemsList(null);
	model.addAttribute("itemsList", itemsList);
	
	return "itemsList";
}

  因为我传入的参数是 items_id ,而接收的形参也是 items_id,所以可以省略代码 @RequestParam("items_id")
3. 控制台打印:

items_id = 1

其他类型的同理。

3. POJO 类型的参数绑定

  POJO 的类型绑定包括有简单 POJO 类型和复杂(POJO中有POJO)的 POJO 类型。两者都一样,在简单的 POJO类型进行参数绑定时,需要前台传入的参数名和 POJO 的成员变量名一致才能绑定上,复杂的 POJO 参数绑定对于内部的 POJO 类型通过 POJO成员变量名.另一个POJO的成员变量名 的方式进行绑定。

3.1 简单 POJO 参数绑定
  JSP 代码:

<form name="itemsForm"
	action="${pageContext.request.contextPath }/items/queryItems.action"
	method="post">
	查询条件:
	<table width="100%" border=1>
		<tr>
			<td>
			商品名称:<input name="name" type="text" /><br> 
			商品描述:<input name="detail" type="text" />
			</td>
			<td><input type="submit" value="查询" /> </td>
		</tr>
	</table>
</form>

  后端代码:

@RequestMapping("/queryItems")
public String queryItems(Items items, Model model) throws Exception {
	System.out.println("items = " + items);
	//1.调用service 查找数据库的商品查询
	List<ItemsCustom> itemsList = itemService.findItemsList(null);
	model.addAttribute("itemsList", itemsList);
	
	return "itemsList";
}

3.2 复杂 POJO 参数绑定
  POJO ItemsQueryVo 类代码:

package com.ssm.po;

public class ItemsQueryVo {
	
	private Items items;				//商品类
	
	//自定义用户扩展类,提高系统的可扩展性
	private ItemsCustom itemsCustom;	//自定义用户扩展类
	
	public Items getItems() {
		return items;
	}

	public void setItems(Items items) {
		this.items = items;
	}

	public ItemsCustom getItemsCustom() {
		return itemsCustom;
	}

	public void setItemsCustom(ItemsCustom itemsCustom) {
		this.itemsCustom = itemsCustom;
	}

	@Override
	public String toString() {
		return "ItemsQueryVo [items=" + items + ", itemsCustom=" + itemsCustom + "]";
	}
	
}

  JSP 代码:

<form name="itemsForm"
	action="${pageContext.request.contextPath }/items/queryItems.action"
	method="post">
	查询条件:
	<table width="100%" border=1>
		<tr>
			<td>
			商品名称:<input name="itemsCustom.name" type="text" /><br> 
			商品描述:<input name="itemsCustom.detail" type="text" />
			</td>
			<td><input type="submit" value="查询" /> </td>
		</tr>
	</table>
</form>

  后端代码:

@RequestMapping("/queryItems")
	public String queryItems(ItemsQueryVo itemsQueryVo, Model model) throws Exception {
		System.out.println("itemsQueryVo = " + itemsQueryVo);
		//1.调用service 查找数据库的商品查询
		List<ItemsCustom> itemsList = itemService.findItemsList(null);
		model.addAttribute("itemsList", itemsList);
		
		return "itemsList";
	}
4. 集合类型的参数绑定

  常用的集合有数组类型,List 类型、Map 类型。

4.1 数组类型参数绑定
  页面定义多个 checkbox 选中后向 Controller 提交。

<input type="checkbox" name="item_id" value="1"/>
<input type="checkbox" name="item_id" value="2"/>
<input type="checkbox" name="item_id" value="3"/>

  Controller代码

@RequestMapping("/queryItems")
public String queryItems(String[] items_id, Model model) throws Exception {
	System.out.println("items_id = " + items_id);
	//1.调用service 查找数据库的商品查询
	List<ItemsCustom> itemsList = itemService.findItemsList(null);
	model.addAttribute("itemsList", itemsList);
	
	return "itemsList";
}

4.2 List 类型参数绑定
  在 POJO 中定义一个 List 类型的成员变量,生成 get/set 方法。

public class ItemsCustom extends Items{

	//这里添加扩展字段
	private List<Items> itemss;
	
	//get/set方法
}

  在 Jsp 页面定义两个 input,注意 name 的命名,itemss为 POJO 的成员变两名,name为 Items 变量名。

商品List0:<input name="itemss[0].name" type="text" />
商品List1:<input name="itemss[1].name" type="text" />

  在 Controller 中方法定义如下:

@RequestMapping("/queryItems")
public String queryItems(ItemsCustom itemsCustom, Model model) throws Exception {
	System.out.println("itemsCustom = " + itemsCustom);
	//1.调用service 查找数据库的商品查询
	List<ItemsCustom> itemsList = itemService.findItemsList(null);
	model.addAttribute("itemsList", itemsList);
	
	return "itemsList";
}

4.3 Map 类型参数绑定
  在 POJO 中定义一个 Map 类型的成员变量,生成 get/set 方法。

public class ItemsCustom extends Items{

	//这里添加扩展字段
	private Map<String, Object> map;
	
	//get/set方法
}

  在 Jsp 页面定义两个 input,注意 name 的命名,map 为成员变量名,name 和 price 对应 key ,其传入的值对应 value。

商品Map0:<input name="map['name']" type="text" />
商品Map1:<input name="map['price']" type="text" />

  在 Controller 中方法定义如下:

@RequestMapping("/queryItems")
public String queryItems(ItemsCustom itemsCustom, Model model) throws Exception {
	System.out.println("itemsCustom = " + itemsCustom);
	//1.调用service 查找数据库的商品查询
	List<ItemsCustom> itemsList = itemService.findItemsList(null);
	model.addAttribute("itemsList", itemsList);
	
	return "itemsList";
}
5. 自定义参数绑定实现日期(Date)类型的参数绑定

  第一步是编写一个自定义的 Converter ,功能是将 String 类型转换为 Date 类型。

package com.ssm.controller.converter;

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) {
		try {
			SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			//转换成功,返回
			return simpleDateFormat.parse(source);
		} catch (Exception e) {
			e.printStackTrace();
		}
		//不成功,返回null
		return null;
	}

}

  第二步是在springmvc.xml 中进行配置:

<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
<!-- 自定义转换器 -->
<bean id="conversionService"
	class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
	<!-- 转换器 -->
	<property name="converters">
		<list>
			<bean class="com.ssm.controller.converter.CustomDateConverter"/>
		</list>
	</property>
</bean>

  JSP代码

创建时间:<input name="createtime" type="text" />

  Controller代码

@RequestMapping("/queryItems")
public String queryItems(ItemsCustom itemsCustom, Model model) throws Exception {
	System.out.println("itemsCustom = " + itemsCustom);
	//1.调用service 查找数据库的商品查询
	List<ItemsCustom> itemsList = itemService.findItemsList(null);
	model.addAttribute("itemsList", itemsList);
	
	return "itemsList";
}

四、Spring MVC 传参乱码解决

  1. Spring MVC 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>

  1. Spring MVC get 请求乱码解决
      对于 GET 请求参数乱码可以是在 Tomcat 的配置文件 server.xml 中修改代码<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>,增加属性URIEncoding="utf-8",即:<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

  还可以对参数进行重新编码String params new String(request.getParamter("params").getBytes("ISO8859-1"),"UTF-8");等重新编码的方法。

猜你喜欢

转载自blog.csdn.net/qq_24598601/article/details/84997529