http://blog.csdn.net/yerenyuan_pku/article/details/72511611

SpringMVC中的参数绑定还是蛮重要的,所以单独开一篇文章来讲解。本文所有案例代码的编写均建立在前文SpringMVC学习(四)——Spring、MyBatis和SpringMVC的整合的案例基础之上,因此希望读者能仔细阅读这篇文章。

默认支持的数据类型

现在有这样一个需求:打开商品编辑页面,展示商品信息。这是我对这个需求的分析:编辑商品信息,需要根据商品id查询商品信息,然后展示到页面。我这里假设请求的url为/itemEdit.action,由于我想要根据商品id查询商品信息,所以需要传递商品id这样一个参数。最终的一个响应结果就是在商品编辑页面中展示商品详细信息,如下: 

为了解决这个需求,必然要有一个商品编辑页面,这里将如下editItem.jsp复制到工程的/WEB-INF/jsp目录下。

  • 商品编辑页面——editItem.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>
    <!-- 上传图片是需要指定属性 enctype="multipart/form-data" -->
    <!-- <form id="itemForm" action="" method="post" enctype="multipart/form-data"> -->
    <form id="itemForm" action="${pageContext.request.contextPath }/updateitem.action" method="post">
    <input type="hidden" name="id" value="${item.id }" /> 修改商品信息:
    <table width="100%" border=1>
    <tr>
    <td>商品名称</td>
    <td><input type="text" name="name" value="${item.name }" /></td>
    </tr>
    <tr>
    <td>商品价格</td>
    <td><input type="text" name="price" value="${item.price }" /></td>
    </tr>
    <tr>
    <td>商品简介</td>
    <td><textarea rows="3" cols="30" name="detail">${item.detail }</textarea>
    </td>
    </tr>
    <tr>
    <td colspan="2" align="center"><input type="submit" value="提交" />
    </td>
    </tr>
    </table> </form>
    </body> </html>

当然了,在商品列表展示页面——itemList.jsp中,我们还须注意编辑修改这个超链接,如下图所示: 

所有前端页面准备好之后,接下来就要编写后台业务代码了。

编写Service层代码

首先在ItemService接口中添加如下一个方法:

Items getItemById(int id);
  • 1
  • 1

如此一来,ItemService接口的代码就变为:

public interface ItemService {
List<Items> getItemList();
Items getItemById(int id);
}

紧接着在ItemService接口的实现类——ItemServiceImpl.java中实现以上方法,即在ItemServiceImpl实现类中添加如下方法:

@Override
public Items getItemById(int id) {
// 根据商品id查询商品信息
Items items = itemsMapper.selectByPrimaryKey(id);
return items;
}

Controller类的参数绑定

要根据商品id查询商品数据,需要从请求的参数中把请求的id取出来。id应该包含在Request对象中。可以从Request对象中取id。因此我们应在ItemController类中添加如下方法:

public ModelAndView editItem(HttpServletRequest request) {
// 从request中取出参数
String strId = request.getParameter("id");
int id = new Integer(strId);
// 调用服务
Items items = itemService.getItemById(id);
// 把结果传递给页面
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("item", items);
// 设置逻辑视图
modelAndView.setViewName("editItem");
return modelAndView;
}

如果想获得Request对象只需要在Controller类方法的形参中添加一个参数即可。SpringMVC框架会自动把Request对象传递给方法。这就是SpringMVC框架默认支持的参数类型。

SpringMVC框架默认支持的参数类型

处理器形参中添加如下类型的参数,处理适配器会默认识别并进行赋值。

  • HttpServletRequest:通过request对象获取请求信息。
  • HttpServletResponse:通过response处理响应信息。
  • HttpSession:通过session对象得到session中存放的对象。
  • Model/ModelMap:ModelMap是Model接口的实现类,我们可通过Model或ModelMap向页面传递数据,如下:

    Items items = itemService.getItemById(id);
    model.addAttribute("item", items);

    页面中通过${item.XXXX}获取item对象的属性值。 
    使用Model和ModelMap的效果是一样的,如果直接使用Model接口,SpringMVC会实例化ModelMap。如果使用Model接口,那么editItem方法可以改造成:

    @RequestMapping("/itemEdit")
    public String editItem(HttpServletRequest request,
    HttpServletResponse response, HttpSession session, Model model) {
    // 从request中取出参数
    String strId = request.getParameter("id");
    int id = new Integer(strId);
    // 调用服务
    Items items = itemService.getItemById(id); // 使用模型设置返回结果,model是框架给我们传递过来的对象,所以这个对象也不需要我们返回
    model.addAttribute("item", items); // 类似于:modelAndView.addObject("item", items);
    // 返回逻辑视图
    return "editItem";
    }

    如果使用Model接口则可以不使用ModelAndView对象,Model对象可以向页面传递数据(model是框架给我们传递过来的对象,所以这个对象不需要我们返回),View对象则可以使用String返回值替代。不管是Model还是ModelAndView,其本质都是使用Request对象向jsp传递数据。

简单数据类型绑定

当请求的参数名称和处理器形参名称一致时会将请求参数与形参进行绑定。从Request取参数的方法可以进一步简化。这样一来,editItem方法可以改造成:

@RequestMapping("/itemEdit")
public String editItem(Integer id, Model model) {
// 调用服务
Items items = itemService.getItemById(id);
// 把数据传递给页面,需要用到Model接口
model.addAttribute("item", items);
// 返回逻辑视图
return "editItem";
}

支持的数据类型

SpringMVC框架支持的数据类型有:

  • 整形: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

注意:参数类型推荐使用包装数据类型,因为基础数据类型不可以为null

@RequestParam

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

  • value:参数名字,即入参的请求参数名字,如value=“item_id”表示请求的参数区中的名字为item_id的参数的值将传入。
  • required:是否必须,默认是true,表示请求中一定要有相应的参数,否则将报如下错误: 
  • defaultValue:默认值,表示如果请求中没有同名参数时的默认值。

使用@RequestParam注解,editItem方法可以改造成:

@RequestMapping("/itemEdit")
public String editItem(@RequestParam(value="id",defaultValue="1",required=true) Integer ids, Model model) {
// 调用服务
Items items = itemService.getItemById(ids);
// 把数据传递给页面,需要用到Model接口
model.addAttribute("item", items);
// 返回逻辑视图
return "editItem";
}


形参名称为ids,但是这里使用value=”id”限定请求的参数名为id,所以页面传递参数的名称必须为id。注意:如果请求参数中没有id将抛出异常: 

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

绑定pojo类型

现有这样一个需求:将页面修改后的商品信息保存到数据库表中。这是我对这个需求的分析:我这里假设请求的url为/updateitem.action,由于我想要将页面修改后的商品信息保存到数据库表中,所以需要传递的参数是表单中的数据。最终的一个响应结果就是跳转到更新成功页面。

使用pojo接收表单数据

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

编写Service层代码

首先在ItemService接口中添加如下一个方法:

void updateItem(Items items);

如此一来,ItemService接口的代码就变为:

public interface ItemService {
List<Items> getItemList();
Items getItemById(int id);
void updateItem(Items items);
}

紧接着在ItemService接口的实现类——ItemServiceImpl.java中实现以上方法,即在ItemServiceImpl实现类中添加如下方法:

@Override
public void updateItem(Items items) {
itemsMapper.updateByPrimaryKeySelective(items);
}

Controller类的参数绑定

在Controller类中使用pojo数据类型进行参数绑定,即应在ItemController类中添加如下方法:

@RequestMapping("/updateitem")
public String updateItems(Items items) {
itemService.updateItem(items);
// 返回成功页面
return "success";
}

请求的参数名称和pojo的属性名称一致,会自动将请求参数赋值给pojo的属性。注意:提交的表单中不要有日期类型的数据,否则会报400错误。如果想提交日期类型的数据需要用到后面的自定义参数绑定的内容。 
最后的响应结果就是跳转到更新成功页面。所以还须在/WEB-INF/jsp目录下编写一个jsp页面——success.jsp,如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!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>Insert title here</title>
</head>
<body>
<h1>商品更新成功!!!</h1>
</body>
</html>

这样,当我们修改完商品信息之后,去数据库表中瞧一瞧,就会看到中文乱码情况了,如下: 

我们知道表单提交的方式是post,那么如何来解决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>

注意:以上只可以解决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编码。

解决完post提交的中文乱码问题之后,再次修改商品信息,去数据库表中瞧一瞧,将发现一切正常。

绑定包装pojo

现有这样一个需求:使用包装的pojo接收商品信息的查询条件。下面是我的需求分析: 
首先,在com.itheima.springmvc.pojo包下编写一个包装类,定义如下:

public class QueryVo {
private Items items; public Items getItems() {
return items;
} public void setItems(Items items) {
this.items = items;
}
}

然后在itemList.jsp页面中添加如下input输入项:

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

添加的位置我已在下图框出: 

接着在ItemController类中添加如下方法:

@RequestMapping("/queryitem")
public String queryItem(QueryVo queryVo) {
// 打印绑定结果
System.out.println(queryVo.getItems().getId());
System.out.println(queryVo.getItems().getName());
return "success";
}

最后的一个访问流程大致就是这样: 

自定义参数绑定

有这样一个需求:在商品修改页面可以修改商品的生产日期,并且根据业务需求自定义日期格式。 
要解决这个需求,首先要在editItem.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>
<!-- 上传图片是需要指定属性 enctype="multipart/form-data" -->
<!-- <form id="itemForm" action="" method="post" enctype="multipart/form-data"> -->
<form id="itemForm" action="${pageContext.request.contextPath }/updateitem.action" method="post">
<input type="hidden" name="id" value="${item.id }" /> 修改商品信息:
<table width="100%" border=1>
<tr>
<td>商品名称</td>
<td><input type="text" name="name" value="${item.name }" /></td>
</tr>
<tr>
<td>商品价格</td>
<td><input type="text" name="price" value="${item.price }" /></td>
</tr>
<tr>
<td>商品生产日期</td>
<td><input type="text" name="createtime"
value="<fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd HH:mm:ss"/>" /></td>
</tr>
<tr>
<td>商品简介</td>
<td><textarea rows="3" cols="30" name="detail">${item.detail }</textarea>
</td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="提交" />
</td>
</tr>
</table> </form>
</body> </html>

我们还是一如往前地修改商品的信息(当然包含修改商品的生产日期),当我们点击提交按钮时,发现报400错误,如下: 

我之前就已讲过:提交的表单中不要有日期类型的数据,否则会报400错误。如果想提交日期类型的数据需要用到后面的自定义参数绑定的内容。所以要真正解决这个需求,就必然要用到自定义参数绑定的内容。下面是我对这个需求的分析:由于日期数据有很多种格式,所以SpringMVC没办法把字符串转换成日期类型。所以需要自定义参数绑定。前端控制器接收到请求后,找到注解形式的处理器适配器,对RequestMapping标记的方法进行适配,并对方法中的形参进行参数绑定。在SpringMVC中可以在处理器适配器上自定义Converter进行参数绑定。如果使用<mvc:annotation-driven/>,可以在此标签上进行扩展。

自定义Converter

在com.itheima.springmvc.converter下编写一个自定义Converter——DateConverter.java,如下:

/**
* SpringMVC转换器
* Converter<S, T> S:source源数据类型,T:target目标数据类型
* @author 李阿昀
*
*/
public class DateConverter implements Converter<String, Date> { @Override
public Date convert(String source) {
try {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = simpleDateFormat.parse(source);
return date;
} catch (ParseException e) {
e.printStackTrace();
}
return null;
} }

配置Converter

如果使用<mvc:annotation-driven/>,可以在此标签上进行扩展。在springmvc.xml配置文件中添加如下配置:

<!-- 配置一个注解驱动,如果配置此标签,那么就可以不用配置处理器映射器和处理器适配器 -->
<mvc:annotation-driven conversion-service="conversionService" />
<!-- 转换器的配置 -->
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.itheima.springmvc.converter.DateConverter"/>
</set>
</property>
</bean>

其实配置Converter还有另一种方式,不过实际开发中用到的很少,这里还是讲一下,按照这种方式配置完Converter之后,springmvc.xml配置文件就为:

<?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: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://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!-- 配置一个扫描包,指定Controller的包,它会扫描这个包下所有带@Controller注解的类,并创建对象放到springmvc容器中 -->
<context:component-scan base-package="com.itheima.springmvc.controller"/> <!-- 转换器配置 -->
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.itheima.springmvc.converter.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"/> <!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>

注意:此方法需要独立配置处理器映射器、适配器,不再使用<mvc:annotation-driven/>。 
这样当我们修改商品的信息(当然包含修改商品的生产日期)时,就能修改成功了,并不会报400的错误。

SpringMVC与Struts2的不同

    1. SpringMVC的入口是一个servlet即前端控制器,而Struts2入口是一个filter过虑器。
    2. SpringMVC是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),Struts2是基于类开发,传递参数是通过类的属性,只能设计为多例
    3. Struts2采用值栈存储请求和响应的数据,通过OGNL存取数据,SpringMVC通过参数解析器将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过request域传输到页面。jsp视图解析器默认使用jstl。

(转)SpringMVC学习(五)——SpringMVC的参数绑定的更多相关文章

  1. SpringMVC学习(二)———— 参数绑定

    一.参数绑定 1.1.什么是参数绑定? 客户在浏览器端会提交一些参数到服务器端,比如用户的登录等,就会传username 和 password过来,springmvc则通过参数绑定组件将请求参数的内容 ...

  2. (转)SpringMVC学习(六)——SpringMVC高级参数绑定与@RequestMapping注解

    http://blog.csdn.net/yerenyuan_pku/article/details/72511749 高级参数绑定 现在进入SpringMVC高级参数绑定的学习,本文所有案例代码的编 ...

  3. (转)SpringMVC学习(一)——SpringMVC介绍与入门

    http://blog.csdn.net/yerenyuan_pku/article/details/72231272 SpringMVC介绍 SpringMVC是什么? SpringMVC和Stru ...

  4. (转)SpringMVC学习(三)——SpringMVC的配置文件

    http://blog.csdn.net/yerenyuan_pku/article/details/72231527 读者阅读过SpringMVC学习(一)——SpringMVC介绍与入门这篇文章后 ...

  5. JAVAEE——SpringMVC第二天:高级参数绑定、@RequestMapping、方法返回值、异常处理、图片上传、Json交互、实现RESTful、拦截器

    1. 课前回顾 https://www.cnblogs.com/xieyupeng/p/9093661.html 2. 课程计划 1.高级参数绑定 a) 数组类型的参数绑定 b) List类型的绑定 ...

  6. SpringMVC第四篇【参数绑定详讲、默认支持参数类型、自定义参数绑定、RequestParam注解】

    参数绑定 我们在Controller使用方法参数接收值,就是把web端的值给接收到Controller中处理,这个过程就叫做参数绑定- 默认支持的参数类型 从上面的用法我们可以发现,我们可以使用req ...

  7. SpringMVC 完美解决PUT请求参数绑定问题(普通表单和文件表单)

    一 解决方案 修改web.xml配置文件 将下面配置拷贝进去(在原有的web-app节点里面配置 其它配置不变) <!-- 处理PUT提交参数(只对基础表单生效) --> <filt ...

  8. springMVC入门(四)------参数绑定与返回值类型

    简介 从之前的介绍,已经可以使用springMVC完成完整的请求.返回数据的功能. 待解决的问题:如何将数据传入springMVC的控制器进行后续的处理,完成在原生servlet/jsp开发中Http ...

  9. SpringMVC @RequestBody @RequestParam @PathVariable 等参数绑定注解详解

    request 数据到handler method 参数数据的绑定所用到的注解和什么情形下使用: http://blog.csdn.net/walkerjong/article/details/794 ...

随机推荐

  1. 一、使用 BeautifulSoup抓取网页信息信息

    一.解析网页信息 from bs4 import BeautifulSoup with open('C:/Users/michael/Desktop/Plan-for-combating-master ...

  2. Git(二)--常用命令

    $ git init  从当前目录初始化 $ git clone git://xxxx  从远程仓库克隆 $ git status 确定哪些文件当前处于什么状态 $ git add 开始跟踪一个新文件 ...

  3. myeclipse 2014 没有Install New Software的解决办法

    要安装离线zip包,但在myeclipse2014的help菜单中找不到 Install New Software 解决如下: help--install from site--add--archiv ...

  4. Python3.6 的字符串内建函数

    1.capitalize(self) 将字符串的第一个字符转换为大写 2.casefold(self) 返回将字符串中所有大写字符转换为小写后生成的字符串 3.center(self, width, ...

  5. AWS AutoScaling的一个ScaleDown策略问题以及解决方法

    此文已由作者袁欢授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 1. AWS AutoScaling简介 AutoScaling是AWS的一个重要服务,用来弹性的自动创建(S ...

  6. SpringCloud之旅第一篇-微服务概念

    一.单体架构的问题 微服务为什么会出现?在学习Springboot的时候知道Springboot极大的简化了我们的开发,我们可以快速的进行业务开发,Springboot单体应用在项目的开发初期能够满足 ...

  7. vue中引入公共方法并使用

    test.js文件(公共js文件) function myFun() { console.log('this is my function') } export { myfun } // 2 expo ...

  8. thinkphp5.0 cache数据缓存机制

    use think\cache; public function index(){ //Cache::get('name')获取缓存,如果name值不存在则返回false: if (Cache::ge ...

  9. web前端篇:JavaScript基础篇(易懂小白上手快)-2

    目录 一.内容回顾: ECMAScript基础语法 1.基本数据类型和引用数据类型 2.条件判断和循环 3.赋值运算符,逻辑运算符 4.字符串的常用方法 5.数组的常用方法 6.对象 7.函数 8.日 ...

  10. Markdown - 如何给文本加下划线

    解决方法 Markdown可以和HTML的语法兼容,可以通过HTML的标签来实现效果: 写法 效果 <u>下划线</u> 下划线 这里解释下,u指的是underline下划线. ...