SpringMVC的类型转换和格式化

Posted nuist__NJUPT

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringMVC的类型转换和格式化相关的知识,希望对你有一定的参考价值。

SpringMVC的类型转换和格式化

在SpringMVC中需要收集用户请求参数,并将请求参数传递给应用控制器组件,因为所有的请求参数只能是字符串类型数据,
但是Java是强类型语言,所有SpringMVC必须将这些字符串请求参数转换成相应的数据类型。
SpringMVC提供了强大的类型转换和格式化机制,开发者可以使用SpringMVC内置的类型转换和格式化机制,也可以开发出自己的类型转换器和格式化转换器,完成字符串和各种数据类型之间的转换。

SpringMVC框架的Converter<S,T>是将源类型S转换成目标类型T的一种类型转换接口,开发者在实际应用中使用框架内置的类型转换器就足够了,但是有时候也需要编写具有特定功能的类型转换器。

对于Converter接口,下面我们使用内置转换器和自定义类型转换器分别完成数据类型的转换。
1-在IDEA中创建名为ch13的web应用,并在WEB-INF目录下创建目录lib,在该目录中导入相关jar包,并将lib添加为库项目。

2-web目录下的index.jsp中采集数据信息


<%--
  Created by IntelliJ IDEA.
  User: nuist__NJUPT
  Date: 2021/8/7
  Time: 22:09
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action = "${pageContext.request.contextPath}/add/addGoods" method = "post">
    商品名称:<input type = "text" name = "goodsname"/><br>
    商品价格:<input type = "text" name = "goodsprice"/><br>
    商品数量:<input type = "text" name = "goodsnumber"/><br>
    <input type = "submit" value = "提交"/>
</form>
</body>
</html>

3-在WEB-INF目录的web.xml中配置dispatcherServlet

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         id = "WebApp_ID" version="4.0">
    <!--部署DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF/springmvc-servlet.xml</param-value>
        </init-param>
        <!--表示容器启动时加载的servlet-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--任意的请求都通过DispatcherServlet-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

4-在SpringMVC配置文件springmvc-servlet.xml中扫描controller包,使得注解生效,同时配置视图解析器,解析视图路径。

<?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: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.xsd
       http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--使用扫描机制,扫描控制器类-->
    <context:component-scan base-package="controller"/>

    <!--配置视图解析器-->
    <bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver" id = "internalResourceViewResolver">
        <!--前缀-->
        <property name = "prefix" value = "/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name = "suffix" value = ".jsp"/>
    </bean>
</beans>

5-在src目录下创建controller包,在该包中创建控制器类GoodsController,index.jsp提交的请求,可以有以下方法接收请求参数并处理。


import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/add")
public class GoodsController {
    @RequestMapping("/addGoods")
    public String add(String goodsname, double goodsprice, int goodsnumber, Model model){
        double total = goodsnumber * goodsprice ; //计算总价格
        System.out.println(total) ;
        model.addAttribute("sum", total); //暴露模型数据
        return "success" ; //跳转到success.jsp页面
    }
}


6-在WEB-INF目录下创建jsp目录,在该目录上创建success.jsp视图,如下所示,在视图中使用EL表达式取出model中sum的值

<%--
  Created by IntelliJ IDEA.
  User: nuist__NJUPT
  Date: 2021/8/7
  Time: 21:40
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
商品总价为:${sum}
</body>
</html>

7-发布SpringMVC应用,运行tomcat服务器,如下所示。

输入数据,点击提交后,将在新的页面看到商品总价格:5500

当SpringMVC内置类型转换器不能满足需求时候,开发者可以定义自己的类型转换器,例如用户希望在表单中输入信息来创建商品信息。当输入apple,10.58,200时候,表示程序自动创建一个new Goods,将apple赋值给goodsname属性,将10.58赋值给goodsprice属性,将200自动赋值给goodsnumber属性,接下来演示自定义Converter类型转换器。

1-创建web应用,与上述的第1步相同,不再赘述。
2-在WEB-INF目录的web.xml中配置dispatcherServlet,与上述的第3步相同,不再赘述。
3-在web目录下的index.jsp中写入信息采集代码

<%--
  Created by IntelliJ IDEA.
  User: nuist__NJUPT
  Date: 2021/8/7
  Time: 19:56
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>$Title$</title>
</head>
<body>
<form action = "${pageContext.request.contextPath}/my/converter" method="post">
    请输入商品信息,格式为apple,10.58,200
    <input type = "text" name = "goods"/>
    <input type = "submit" value = "提交"/>
</form>
</body>
</html>

4-在src目录下创建pojo包,在该包中创建名为GoodsModel的实体类,将商品信息封装在该实体类中。

public class GoodsModel {
    //商品信息封装到实体类中
    private String goodsname ;
    private double goodsprice ;
    private int goodsnumber ;

    public String getGoodsname() {
        return goodsname;
    }

    public void setGoodsname(String goodsname) {
        this.goodsname = goodsname;
    }

    public double getGoodsprice() {
        return goodsprice;
    }

    public void setGoodsprice(double goodsprice) {
        this.goodsprice = goodsprice;
    }

    public int getGoodsnumber() {
        return goodsnumber;
    }

    public void setGoodsnumber(int goodsnumber) {
        this.goodsnumber = goodsnumber;
    }
}

5-在src目录下创建controller包,在该包中创建控制器类,ConverterController,在该控制器类中使用RequestParam接收请求参数,然后调用自定义转换器GoodsConverter将字符串值转换为GoodsModel的对象gm,然后暴露模型数据,返回到相应页面。


import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import pojo.GoodsModel;

@Controller
@RequestMapping("/my") //使得请求与处理方法一一对应
public class ConverterController {
    @RequestMapping("/converter")
    //接收请求参数,调用自定义类型转换器将字符串值转换为GoodsModel的对象那个gm
    public String myConverter(@RequestParam("goods") GoodsModel gm, Model model){
        model.addAttribute("goods", gm) ;
        return "showGoods" ; //返回到showGoods.jsp视图
    }
}

6-在src目录下创建converter包,在该包中创建自定义类型转换器类GoodsConverter,将源类型数据转换为目标类型数据。

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

public class GoodsConverter implements Converter<String, GoodsModel> {
    @Override
    public GoodsModel convert(String source) {
        //创建一个Goods实例
        GoodsModel goods = new GoodsModel() ;
        //将字符串以逗号分隔
        String  [] stringValue = source.split(",") ;
        if(stringValue != null && stringValue.length == 3){
            //相应类型的元素存储到goods中
            goods.setGoodsname(stringValue[0]);
            goods.setGoodsprice(Double.parseDouble(stringValue[1]));
            goods.setGoodsnumber(Integer.parseInt(stringValue[2]));
            return goods ;
        }else{
            throw new IllegalArgumentException(String.format("格式转换失败,目前的格式是【%s】", source)) ;
        }
    }
}

7-自定义的类型转换器需要在SpringMVC的配置文件中注册才能生效,在WEB-INF中创建SpringMVC的配置文件springmvc-servlet.xml,在该配置文件中扫描controller包,配置视图解析图,同时注册类型转换器GoodsConverter

<?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: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.xsd
       http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--使用扫描机制,扫描控制器类-->
    <context:component-scan base-package="controller"/>
    <!--注册类型转换器GoodsConvert-->
    <bean id = "conversionService" class = "org.springframework.context.support.ConversionServiceFactoryBean">
        <property name = "converters">
            <list>
                <bean class = "converter.GoodsConverter"/>
            </list>
        </property>
    </bean>
    <mvc:annotation-driven conversion-service="conversionService" />

    <!--配置视图解析器-->
    <bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver" id = "internalResourceViewResolver">
        <!--前缀-->
        <property name = "prefix" value = "/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name = "suffix" value = ".jsp"/>
    </bean>
</beans>

8-在WEB-INF的jsp目录下创建信息显示页面showGoods.jsp,代码如下:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>$Title$</title>
</head>
<body>
你创建的商品信息如下:<br>
商品的名称为:${goods.goodsname}<br>
商品的价格为:${goods.goodsprice}<br>
商品的数量为:${goods.goodsnumber}<br>
</form>
</body>
</html>

9-发布SpringMVC应用,运行tomcat服务器,如下所示
10-输入数据后提交,如下所示

SpringMVC框架的Formatter与Converter<S,T>都是将一种数据类型转换成另一种数据类型,不同的是Formatter的源数据类型必须是String类型,Converter的源数据类型可以是任意类型。
在Web应用中由Http发送的请求数据在控制器中都是以字符串的类型获取,因此在Web应用中选择Formatter比选择Converter更加合理。
自定义格式转换器编写一个实现Fornatter接口的Java类,该接口有parse和print两个方法,自定义格式转换器必须覆盖它们。parse方法的功能是利用Locale将一个String类型转换为目标类型,print方法是返回目标对象的字符串表示。

下面演示使用Formatter完成格式化器的设计,
应用的具体要求如下:
1-用户在页面表单输入信息来创建商品信息,输入效果如图所示。

2-控制器使用实体Bean类GoodsModelb接收页面请求参数,GoodsModelb的类属性如下:
private String goodsname ;
private double goodsprice ;
private int goodsnumber ;
private Date goodsdate ;
3-GoodsModelb实体类接收请求参数时候,商品名称、价格、数量使用内置的类型转换器完成,商品日期需要用自定义的格式转换器完成。
4-用格式化器转化后的数据显示在showGoods.jsp页面。

第1步:创建web应用,与上述的第1步相同,不再赘述。
第2步:在WEB-INF目录的web.xml中配置dispatcherServlet.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         id = "WebApp_ID" version="4.0">
    <!--部署DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>WEB-INF/springmvc-servlet.xml</param-value>
        </init-param>
        <!--表示容器启动时加载的servlet-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!--任意的请求都通过DispatcherServlet-->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- 配置 CharacterEncodingFilter解决中文乱码问题-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

        <!-- 配置编码格式为UTF-8 -->
        <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>
</web-app>

第3步:在web目录下创建信息采集页面index.jsp

<%--
  Created by IntelliJ IDEA.
  User: nuist__NJUPT
  Date: 2021/8/7
  Time: 19:56
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>$Title$</title>
</head>
springmvc参数类型转换三种方式

SpringMVC——类型转换和格式化数据校验客户端显示错误消息

SpringMVC的格式化转换器Formatter

spring类型转换器(三)

SpringMVC之转换器与格式化

SpringMVC中JSON数据交互