Spring MVC 框架的 Converter 是一个可以将一种数据类型转换成另一种数据类型的接口,这里 S 表示源类型,T 表示目标类型。开发者在实际应用中使用框架内置的类型转换器基本上就够了,但有时需要编写具有特定功能的类型转换器。

内置的类型转换器

Spring MVC 框架中,对于常用的数据类型,开发者无须创建自己的类型转换器,因为 Spring MVC 框架有许多内置的类型转换器用于完成常用的类型转换。Spring MVC 框架提供的内置类型转换包括以下几种类型。

1)标量转换器

image.png

2)集合、数组相关转换器

image.png
类型转换是在视图与控制器相互传递数据时发生的。Spring MVC 框架对于基本类型(例如 int、long、float、double、boolean 以及 char 等)已经做好了基本类型转换。例如,对于 addGoods.jsp 的提交请求,可以由以下处理方法来接收请求参数并处理:

  1. package controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.web.bind.annotation.RequestMapping;
  4. @Controller
  5. public class Goodsontroller {
  6. @RequestMapping("/addGoods")
  7. public String add(String goodsname, double goodsprice, int goodsnumber) {
  8. double total = goodsprice * goodsnumber;
  9. System.out.println(total);
  10. return "success";
  11. }
  12. }

注意:在使用内置类型转换器时,请求参数输入值与接收参数类型要兼容,否则会报 400 错误。请求参数类型与接收参数类型不兼容问题需要学习输入校验后才可解决。

自定义类型转换器

当 Spring MVC 框架内置的类型转换器不能满足需求时,开发者可以开发自己的类型转换器。

例如有一个应用 springMVCDemo03 希望用户在页面表单中输入信息来创建商品信息。当输入“apple,10.58,200”时表示在程序中自动创建一个 new Goods,并将“apple”值自动赋给 goodsname 属性,将“10.58”值自动赋给 goodsprice 属性,将“200”值自动赋给 goodsnumber 属性。

springMVCDemo03 应用与 springMVCDemo02 具有相同的 JAR 包、web.xml。

如果想实现上述应用,需要做以下 5 件事:

  • 创建实体类。
  • 创建控制器类。
  • 创建自定义类型转换器类。
  • 注册类型转换器。
  • 创建相关视图。

按照上述步骤采用自定义类型转换器完成需求。

1)创建实体类

在 springMVCDemo03 的 src 目录下创建 pojo 包,并在该包中创建名为 GoodsModel 的实体类,代码如下:

  1. package pojo;
  2. public class GoodsModel {
  3. private String goodsname;
  4. private double goodsprice;
  5. private int goodsnumber;
  6. // 省略setter和getter方法
  7. }

2)创建控制器类

在 springMVCDemo03 的 src 目录下创建 controller 包,并在该包中创建名为 ConverterController 的控制器类,代码如下:

  1. package controller;
  2. import org.springframework.stereotype.Controller;
  3. import org.springframework.ui.Model;
  4. import org.springframework.web.bind.annotation.RequestMapping;
  5. import org.springframework.web.bind.annotation.RequestParam;
  6. import pojo.GoodsModel;
  7. @Controller
  8. @RequestMapping("/my")
  9. public class ConverterController {
  10. @RequestMapping("/converter")
  11. /*
  12. * 使用@RequestParam
  13. * ("goods")接收请求参数,然后调用自定义类型转换器GoodsConverter将字符串值转换为GoodsModel的对象gm
  14. */
  15. public String myConverter(@RequestParam("goods") GoodsModel gm, Model model) {
  16. model.addAttribute("goods", gm);
  17. return "showGoods";
  18. }
  19. }

3)创建自定义类型转换器类

自定义类型转换器类需要实现 Converter 接口,重写 convert(S) 接口方法。

convert(S) 方法的功能是将源数据类型 S 转换成目标数据类型 T。在 springMVCDemo03 的 src 目录下创建 converter 包,并在该包中创建名为 GoodsConverter 的自定义类型转换器类,代码如下:

  1. package converter;
  2. import org.springframework.core.convert.converter.Converter;
  3. import pojo.GoodsModel;
  4. public class GoodsConverter implements Converter<String, GoodsModel> {
  5. public GoodsModel convert(String source) {
  6. // 创建一个Goods实例
  7. GoodsModel goods = new GoodsModel();
  8. // 以“,”分隔
  9. String stringvalues[] = source.split(",");
  10. if (stringvalues != null && stringvalues.length == 3) {
  11. // 为Goods实例赋值
  12. goods.setGoodsname(stringvalues[0]);
  13. goods.setGoodsprice(Double.parseDouble(stringvalues[1]));
  14. goods.setGoodsnumber(Integer.parseInt(stringvalues[2]));
  15. return goods;
  16. } else {
  17. throw new IllegalArgumentException(String.format(
  18. "类型转换失败, 需要格式'apple, 10.58,200 ',但格式是[% s ] ", source));
  19. }
  20. }
  21. }

4)注册类型转换器

在 springMVCDemo03 的 WEB-INF 目录下创建配置文件 springmvc-servlet.xml,并在配置文件中注册自定义类型转换器,配置文件代码如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
  4. xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
  5. xsi:schemaLocation="
  6. http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd
  8. http://www.springframework.org/schema/context
  9. http://www.springframework.org/schema/context/spring-context.xsd
  10. http://www.springframework.org/schema/mvc
  11. http://www.springframework.org/schema/mvc/spring-mvc.xsd">
  12. <!-- 使用扫描机制扫描控制器类,控制器类都在controller包及其子包下 -->
  13. <context:component-scan base-package="controller" />
  14. <!--注册类型转换器GoodsConverter-->
  15. <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
  16. <property name="converters">
  17. <list>
  18. <bean class="converter.GoodsConverter"/>
  19. </list>
  20. </property>
  21. </bean>
  22. <bean
  23. class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  24. <property name="prefix" value="/WEB-INF/jsp/" />
  25. <property name="suffix" value=".jsp" />
  26. </bean>
  27. </beans>

5)创建相关视图

在 springMVCDemo03 应用的 WebContent 目录下创建信息采集页面 input.jsp,核心代码如下:

  1. <form action="${pageContext.request.contextPath}/my/converter" method= "post">
  2. 请输入商品信息(格式为apple, 10.58,200):
  3. <input type="text" name="goods" /><br>
  4. <input type="submit" value="提交" />
  5. </form>

在 springMVCDemo03 应用的 /WEB-INF/jsp 目录下创建信息显示页面 showGoods.jsp,核心代码如下:

  1. <body>
  2. 您创建的商品信息如下:
  3. <!-- 使用EL表达式取出model中的goods信息 -->
  4. 商品名称为:${goods.goodsname }
  5. 商品价格为:${goods.goodsprice }
  6. 商品名称为:${goods.goodsnumber }
  7. </body>