在系列(6)中我们介绍了如何验证提交的数据的正确性,当数据验证通过后就会被我们保存起来。保存的数据会用于以后的展示,这才是保存的价值。那么在展示的时候如何按照要求显示?(比如:小数保留一定的位数,日期按指定的格式等)。这就是本篇要说的内容—>格式化显示。

从Spring3.X开始,Spring提供了Converter SPI类型转换和Formatter SPI字段解析/格式化服务,其中Converter SPI实现对象与对象之间的相互转换,Formatter SPI实现String与对象之间的转换,Formatter SPI是对Converter SPI的封装并添加了对国际化的支持,其内部转换还是由Converter SPI完成。

下面是一个简单的请求与模型对象的转换流程:

Spring提供了FormattingConversionService和DefaultFormattingConversionService来完成对象的解析和格式化。Spring内置的几种Formatter SPI如下:

名称 功能
NumberFormatter 实现Number与String之间的解析与格式化
CurrencyFormatter 实现Number与String之间的解析与格式化(带货币符号)
PercentFormatter 实现Number与String之间的解析与格式化(带百分数符号)
DateFormatter 实现Date与String之间的解析与格式化
NumberFormatAnnotationFormatterFactory @NumberFormat注解,实现Number与String之间的解析与格式化,可以通过指定style来指示要转换的格式(Style.Number/Style.Currency/Style.Percent),当然也可以指定pattern(如pattern=“#.##”(保留2位小数) ),这样pattern指定的格式会覆盖掉Style指定的格式
JodaDateTimeFormatAnnotationFormatterFactory @DateTimeFormat注解,实现日期类型与String之间的解析与格式化这里的日期类型包括Date、Calendar、Long以及Joda的日期类型。必须在项目中添加Joda-Time包

下面就开始演示:

首先把Joda-Time包添加到之前的项目中,这里用的是joda-time-2.3.jar,在views文件夹下添加一个formattest.jsp视图,内容如下:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4.  
  5. <html>
  6. <head>
  7. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  8. <title>Insert title here</title>
  9. </head>
  10. <body>
  1. money:<br/>${contentModel.money}<br/>
  2. date:<br/>${contentModel.date}<br/>
  1. </body>
  2. </html>

1.首先我们直接用Formatter来做演示,在com.demo.web.models包中添加FormatModel.java内容如下:

  1. package com.demo.web.models;
  2.  
  3. public class FormatModel{
  4.  
  5. private String money;
  6. private String date;
  7.  
  8. public String getMoney(){
  9. return money;
  10. }
  11. public String getDate(){
  12. return date;
  13. }
  14.  
  15. public void setMoney(String money){
  16. this.money=money;
  17. }
  18. public void setDate(String date){
  19. this.date=date;
  20. }
  21.  
  22. }

在com.demo.web.controllers包中添加FormatController.java内容如下:

  1. package com.demo.web.controllers;
  2.  
  3. import java.math.RoundingMode;
  4. import java.util.Date;
  5. import java.util.Locale;
  6. import org.springframework.context.i18n.LocaleContextHolder;
  7. import org.springframework.format.datetime.DateFormatter;
  8. import org.springframework.format.number.CurrencyFormatter;
  9. import org.springframework.stereotype.Controller;
  10. import org.springframework.ui.Model;
  11. import org.springframework.web.bind.annotation.RequestMapping;
  12. import org.springframework.web.bind.annotation.RequestMethod;
  13. import com.demo.web.models.FormatModel;
  14.  
  15. @Controller
  16. @RequestMapping(value = "/format")
  17. public class FormatController {
  18.  
  19. @RequestMapping(value="/test", method = {RequestMethod.GET})
  20. public String test(Model model) throws NoSuchFieldException, SecurityException{
  21.  
  22. if(!model.containsAttribute("contentModel")){
  23.  
  24. FormatModel formatModel=new FormatModel();
  25.  
  26. CurrencyFormatter currencyFormatter = new CurrencyFormatter();
  27. currencyFormatter.setFractionDigits(2);//保留2位小数
  28. currencyFormatter.setRoundingMode(RoundingMode.HALF_UP);//向(距离)最近的一边舍入,如果两边(的距离)是相等的则向上舍入(四舍五入)
  29.  
  30. DateFormatter dateFormatter=new DateFormatter();
  31. dateFormatter.setPattern("yyyy-MM-dd HH:mm:ss");
  32.  
  33. Locale locale=LocaleContextHolder.getLocale();
  34.  
  35. formatModel.setMoney(currencyFormatter.print(12345.678, locale));
  36. formatModel.setDate(dateFormatter.print(new Date(), locale));
  37.  
  38. model.addAttribute("contentModel", formatModel);
  39. }
  40. return "formattest";
  41. }
  42.  
  43. }

运行测试:

更改浏览器首选语言:

刷新页面:

2.这次用DefaultFormattingConversionService来做演示,把FormatController.java改为如下内容:

  1. package com.demo.web.controllers;
  2.  
  3. import java.math.RoundingMode;
  4. import java.util.Date;
  5. import org.springframework.format.datetime.DateFormatter;
  6. import org.springframework.format.number.CurrencyFormatter;
  7. import org.springframework.format.support.DefaultFormattingConversionService;
  8. import org.springframework.stereotype.Controller;
  9. import org.springframework.ui.Model;
  10. import org.springframework.web.bind.annotation.RequestMapping;
  11. import org.springframework.web.bind.annotation.RequestMethod;
  12.  
  13. import com.demo.web.models.FormatModel;
  14.  
  15. @Controller
  16. @RequestMapping(value = "/format")
  17. public class FormatController {
  18.  
  19. @RequestMapping(value="/test", method = {RequestMethod.GET})
  20. public String test(Model model) throws NoSuchFieldException, SecurityException{
  21.  
  22. if(!model.containsAttribute("contentModel")){
  23.  
  24. FormatModel formatModel=new FormatModel();
  25.  
  26. CurrencyFormatter currencyFormatter = new CurrencyFormatter();
  27. currencyFormatter.setFractionDigits(2);//保留2位小数
  28. currencyFormatter.setRoundingMode(RoundingMode.HALF_UP);//向(距离)最近的一边舍入,如果两边(的距离)是相等的则向上舍入(四舍五入)
  29.  
  30. DateFormatter dateFormatter=new DateFormatter();
  31. dateFormatter.setPattern("yyyy-MM-dd HH:mm:ss");
  32.  
  33. DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
  34. conversionService.addFormatter(currencyFormatter);
  35. conversionService.addFormatter(dateFormatter);
  36.  
  37. formatModel.setMoney(conversionService.convert(12345.678, String.class));
  38. formatModel.setDate(conversionService.convert(new Date(), String.class));
  39.  
  40. model.addAttribute("contentModel", formatModel);
  41. }
  42. return "formattest";
  43. }
  44.  
  45. }

这次没有了Locale locale=LocaleContextHolder.getLocale();再次运行测试并更改语言后刷新,可以看到与第一种方法截图同样的效果,说明DefaultFormattingConversionService会自动根据浏览器请求的信息返回相应的格式。

3.估计有人会觉得,啊…我只是想要格式化显示而已,还要这么麻烦,写代码一个字段一个字段的转换???别急,上面只是对内置的格式化转换器做一下演示,实际项目中肯定不会这么用的,下面就介绍一下基于注解的格式化。首先把FormatModel.java改为如下内容:

  1. package com.demo.web.models;
  2.  
  3. import java.util.Date;
  4. import org.springframework.format.annotation.DateTimeFormat;
  5. import org.springframework.format.annotation.NumberFormat;
  6. import org.springframework.format.annotation.NumberFormat.Style;
  7.  
  8. public class FormatModel{
  9.  
  10. @NumberFormat(style=Style.CURRENCY)
       private double money;
  11. @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
  12. private Date date;
  13.  
  14. public double getMoney(){
  15. return money;
  16. }
  17. public Date getDate(){
  18. return date;
  19. }
  20.  
  21. public void setMoney(double money){
  22. this.money=money;
  23. }
  24. public void setDate(Date date){
  25. this.date=date;
  26. }
  27.  
  28. }

注意:这里的money和date不再是String类型,而是它们自己本来的类型。

把FormatController.java改为如下内容:

  1. package com.demo.web.controllers;
  2.  
  3. import java.util.Date;
  4. import org.springframework.stereotype.Controller;
  5. import org.springframework.ui.Model;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RequestMethod;
  8. import com.demo.web.models.FormatModel;
  9.  
  10. @Controller
  11. @RequestMapping(value = "/format")
  12. public class FormatController {
  13.  
  14. @RequestMapping(value="/test", method = {RequestMethod.GET})
  15. public String test(Model model) throws NoSuchFieldException, SecurityException{
  16. if(!model.containsAttribute("contentModel")){
  17.  
  18. FormatModel formatModel=new FormatModel();
  19.  
  20. formatModel.setMoney(12345.678);
  21. formatModel.setDate(new Date());
  22.  
  23. model.addAttribute("contentModel", formatModel);
  24. }
  25. return "formattest";
  26. }
  27.  
  28. }

注意:这里代码里面只有赋值已经没有格式化的内容了。

更改视图formattest.jsp的内容如下:

  1. <%@ page language="java" contentType="text/html; charset=UTF-8"
  2. pageEncoding="UTF-8"%>
  3. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4.  
  5. <%@taglib prefix="spring" uri="http://www.springframework.org/tags" %>
  1. <html>
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  4. <title>Insert title here</title>
  5. </head>
  6. <body>
  7.  
  8. money:<br/>
  9. <spring:eval expression="contentModel.money"></spring:eval><br/>
  10. date:<br/>
  11. <spring:eval expression="contentModel.date"></spring:eval><br/>
  12.  
  13. </body>
  14. </html>

注意:这里需要添加引用<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %>,并用spring:eval来绑定要显示的值。

运行测试更改浏览器语言然后刷新页面依然可以看到以第一种方法截图相同的效果,证明注解有效。

格式化显示的内容到此结束。

代码下载:http://pan.baidu.com/s/1qWM3Zf2

注: 之前没注意前11篇的示例代码,不知道为什么当时打包上传上去的是没有.project项目文件的,导致下载后不能直接导入eclipse运行,虚拟机又 被我删掉了,这些示例代码也没有备份,但是代码文件还在的,所以可以新建一个Dynamic Web Project把对应的配置文件和controller还有view导入就可以了,给大家造成的不便说声抱歉。

SpringMVC学习系列(7) 之 格式化显示的更多相关文章

  1. SpringMVC学习系列-后记 开启项目的OpenSessionInView

    在系列的 SpringMVC学习系列(12) 完结篇 的示例项目中,由于当时考虑到OpenSessionInView会对性能有一定的影响,所以就没有配置项目的OpenSessionInView.在ma ...

  2. SpringMVC学习系列-后记 解决GET请求时中文乱码的问题

    SpringMVC学习系列-后记 解决GET请求时中文乱码的问题 之前项目中的web.xml中的编码设置: <filter> <filter-name>CharacterEnc ...

  3. SpringMVC学习系列-后记 结合SpringMVC和Hibernate-validator,根据后台验证规则自动生成前台的js验证代码

    在SpringMVC学习系列(6) 之 数据验证中我们已经学习了如何结合Hibernate-validator进行后台的数据合法性验证,但是通常来说后台验证只是第二道保险,为了更好的用户体验会现在前端 ...

  4. SpringMVC学习系列(11) 之 表单标签

    本篇我们来学习Spring MVC表单标签的使用,借助于Spring MVC提供的表单标签可以让我们在视图上展示WebModel中的数据更加轻松. 一.首先我们先做一个简单了例子来对Spring MV ...

  5. SpringMVC学习系列(3) 之 URL请求到Action的映射规则

    在系列(2)中我们展示了一个简单的get请求,并返回了一个简单的helloworld页面.本篇我们来学习如何来配置一个action的url映射规则. 在系列(2)中我们在HelloWorldContr ...

  6. SpringMVC学习系列(2) 之 经典的HelloWorld实现

    前一篇简单介绍了Spring MVC的一些知识,下面就要开始学习如何把Spring MVC运用到具体的项目中去. 首先还是从一个简单的Hello World项目说起: 我机器的开发环境为: Ubunt ...

  7. SpringMVC学习系列(12) 完结篇 之 基于Hibernate+Spring+Spring MVC+Bootstrap的管理系统实现

    到这里已经写到第12篇了,前11篇基本上把Spring MVC主要的内容都讲了,现在就直接上一个项目吧,希望能对有需要的朋友有一些帮助. 一.首先看一下项目结构: InfrastructureProj ...

  8. SpringMVC学习系列 之 表单标签

    http://www.cnblogs.com/liukemng/p/3754211.html 本篇我们来学习Spring MVC表单标签的使用,借助于Spring MVC提供的表单标签可以让我们在视图 ...

  9. SpringMVC学习系列- 表单验证

    本篇我们来学习Spring MVC表单标签的使用,借助于Spring MVC提供的表单标签可以让我们在视图上展示WebModel中的数据更加轻松. 一.首先我们先做一个简单了例子来对Spring MV ...

随机推荐

  1. AWS 搭建 VPN 服务(PPTP & L2TP) 整理

    只为记录和整理在AWS上假设VPN服务器帮助过我的资料,环境使用AWS EC2 东京区域, OS为ubuntu, PPTP和L2TP各自建立一个, 从speed test上看, 下载有2mbps左右, ...

  2. SPSS数据分析—分段回归

    在SPSS非线性回归过程中,我们讲到了损失函数按钮可以自定义损失函数,但是还有一个约束按钮没有讲到,该按钮的功能是对自 定义的损失函数的参数设定条件,这些条件通常是由逻辑表达式组成,这就使得损失函数具 ...

  3. 20150207读书笔记<深入理解计算机系统2-1>

    第二章 信息存储 (1)  多数计算机以一个字节作为最小可寻址的存储器单元. 机器级程序将存储器看成一个非常大的字节数组,称为虚拟存储器. 存储器的每个字节都由唯一的数字标识,称为它的地址. 所有可能 ...

  4. 获取数据库里面最新的ID

    你如果新插入的一段资料,你想获取它的ID,就用   “mysql_insert_id()”; 并且要重新定义一个名称

  5. GitHub Pages 搭建流程-基于jekyll-bootstrap

    我写这篇文章的目的是记录本博客的搭建过程,自己从零开始逐步搭建起来了GitHub Pages,其中借鉴了很多的博客和模版,稍后会在后面列出,也为没有用过gihub和jekyll的童鞋提供一点帮助. 学 ...

  6. docker 会这些也够

    $ sudo systemctl start docker $ sudo systemctl stop docker $ sudo systemctl restart docker If you wa ...

  7. 利用MVVM设计快速开发个人中心、设置等模块

    我们在做iOS开发过程中,静态页面的开发比开发动态页面更让我们开发者抓狂.因为动态页面通常是一个页面一种cell样式,作为开发者只需要专注于定制好一种样式之后,就可以使用数据填充出较好的界面.而静态c ...

  8. 二叉搜索树 C++代码实现

    暂未发现什么bug,如果发现请指出. #include<iostream> using namespace std; //定义二叉搜索树的结点 struct Node { int data ...

  9. CSS简单布局总结

    display  block       块级元素,占据一行 none       隐藏 inline      允许同一行显示,但不再有宽和高 inline-block   允许在一行的块级元素,可 ...

  10. React Native的组件ListView

    React Native的组件ListView类似于iOS中的UITableView和UICollectionView,也就是说React Native的组件ListView既可以实现UITableV ...