SpringMVC学习系列(7) 之 格式化显示

在系列(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视图,内容如下:


<%@ 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>

    money:<br/>${contentModel.money}<br/>
date:<br/>${contentModel.date}<br/>

</body>
</html>

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


package com.demo.web.models;

public class FormatModel{

private String money;
private String date;

public String getMoney(){
return money;
}
public String getDate(){
return date;
}

public void setMoney(String money){
this.money=money;
}
public void setDate(String date){
this.date=date;
}

}

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


package com.demo.web.controllers;

import java.math.RoundingMode;
import java.util.Date;
import java.util.Locale;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.format.datetime.DateFormatter;
import org.springframework.format.number.CurrencyFormatter;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.demo.web.models.FormatModel;

@Controller
@RequestMapping(value = "/format")
public class FormatController {

@RequestMapping(value="/test", method = {RequestMethod.GET})
public String test(Model model) throws NoSuchFieldException, SecurityException{

if(!model.containsAttribute("contentModel")){

FormatModel formatModel=new FormatModel();

CurrencyFormatter currencyFormatter = new CurrencyFormatter();
currencyFormatter.setFractionDigits(2);//保留2位小数
currencyFormatter.setRoundingMode(RoundingMode.HALF_UP);//向(距离)最近的一边舍入,如果两边(的距离)是相等的则向上舍入(四舍五入)

DateFormatter dateFormatter=new DateFormatter();
dateFormatter.setPattern("yyyy-MM-dd HH:mm:ss");

Locale locale=LocaleContextHolder.getLocale();

formatModel.setMoney(currencyFormatter.print(12345.678, locale));
formatModel.setDate(dateFormatter.print(new Date(), locale));

model.addAttribute("contentModel", formatModel);
}
return "formattest";
}

}

运行测试:

更改浏览器首选语言:

刷新页面:

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


package com.demo.web.controllers;

import java.math.RoundingMode;
import java.util.Date;
import org.springframework.format.datetime.DateFormatter;
import org.springframework.format.number.CurrencyFormatter;
import org.springframework.format.support.DefaultFormattingConversionService;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.demo.web.models.FormatModel;

@Controller
@RequestMapping(value = "/format")
public class FormatController {

@RequestMapping(value="/test", method = {RequestMethod.GET})
public String test(Model model) throws NoSuchFieldException, SecurityException{

if(!model.containsAttribute("contentModel")){

FormatModel formatModel=new FormatModel();

CurrencyFormatter currencyFormatter = new CurrencyFormatter();
currencyFormatter.setFractionDigits(2);//保留2位小数
currencyFormatter.setRoundingMode(RoundingMode.HALF_UP);//向(距离)最近的一边舍入,如果两边(的距离)是相等的则向上舍入(四舍五入)

DateFormatter dateFormatter=new DateFormatter();
dateFormatter.setPattern("yyyy-MM-dd HH:mm:ss");

DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
conversionService.addFormatter(currencyFormatter);
conversionService.addFormatter(dateFormatter);

formatModel.setMoney(conversionService.convert(12345.678, String.class));
formatModel.setDate(conversionService.convert(new Date(), String.class));

model.addAttribute("contentModel", formatModel);
}
return "formattest";
}

}

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

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


package com.demo.web.models;

import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.NumberFormat;
import org.springframework.format.annotation.NumberFormat.Style;

public class FormatModel{

@NumberFormat(style=Style.CURRENCY)
   private double money;
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date date;

public double getMoney(){
return money;
}
public Date getDate(){
return date;
}

public void setMoney(double money){
this.money=money;
}
public void setDate(Date date){
this.date=date;
}

}

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

把FormatController.java改为如下内容:


package com.demo.web.controllers;

import java.util.Date;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.demo.web.models.FormatModel;

@Controller
@RequestMapping(value = "/format")
public class FormatController {

@RequestMapping(value="/test", method = {RequestMethod.GET})
public String test(Model model) throws NoSuchFieldException, SecurityException{
if(!model.containsAttribute("contentModel")){

FormatModel formatModel=new FormatModel();

formatModel.setMoney(12345.678);
formatModel.setDate(new Date());

model.addAttribute("contentModel", formatModel);
}
return "formattest";
}

}

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

更改视图formattest.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">

<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %>

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

money:<br/>
<spring:eval expression="contentModel.money"></spring:eval><br/>
date:<br/>
<spring:eval expression="contentModel.date"></spring:eval><br/>

</body>
</html>

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

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

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

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

SpringMVC学习系列(7) 之 格式化显示,布布扣,bubuko.com

时间: 2024-12-30 01:01:36

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

SpringMVC学习系列

SpringMVC学习系列(1) 之 初识SpringMVC SpringMVC学习系列(2) 之 经典的HelloWorld实现 SpringMVC学习系列(3) 之 URL请求到Action的映射规则SpringMVC学习系列(4) 之 数据绑定-1 SpringMVC学习系列(5) 之 数据绑定-2 SpringMVC学习系列(6) 之 数据验证 SpringMVC学习系列(7) 之 格式化显示 SpringMVC学习系列(8) 之 国际化 SpringMVC学习系列(9) 之 实现注解式

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

到这里已经写到第12篇了,前11篇基本上把Spring MVC主要的内容都讲了,现在就直接上一个项目吧,希望能对有需要的朋友有一些帮助. 一.首先看一下项目结构: InfrastructureProjects:是抽取出的基础项目,主要封装了一些通用的操作. SpringMVC3Demo:就是管理系统所在的项目. WeiXinAPI:是之前做微信管理平台测试时封装一些操作,如果不需要把该项目移除即可. 注:项目的前端UI框架用的是国外的一个基于Bootstrap框架的开发的Demo,如不需要替换为

SpringMVC学习系列(10) 之 异常处理

在项目中如何处理出现的异常,在每个可能出现异常的地方都写代码捕捉异常?这显然是不合理的,当项目越来越大是也是不可维护的.那么如何保证我们处理异常的代码精简且便于维护呢?这就是本篇要讲的内容->异常处理. 在Spring MVC中我们可以通过以下2中途径来对异常进行集中处理: 一.继承HandlerExceptionResolver接口实现自己的处理方法,如: public class MyHandlerExceptionResolver implements HandlerExceptionRe

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

本篇我们来学习Spring MVC表单标签的使用,借助于Spring MVC提供的表单标签可以让我们在视图上展示WebModel中的数据更加轻松. 一.首先我们先做一个简单了例子来对Spring MVC表单表单标签的使用有一个大致的印象,然后再结合例子对各个标签介绍一下如何使用. 1.首先,在com.demo.web.models包中添加一个模型TagsModel内容如下: package com.demo.web.models; import java.util.List; import ja

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

在系列的 SpringMVC学习系列(12) 完结篇 的示例项目中,由于当时考虑到OpenSessionInView会对性能有一定的影响,所以就没有配置项目的OpenSessionInView.在mapping文件的配置中比如:Account.hbm.xml为了账户登录系统时查询方便,所以在映射Role时直接采用了lazy="false",而且在Role映射权限Authority时也直接采用了lazy="false",这样登录是方便了,但是在做了账户列表时才意识到即

SpringMVC学习系列(9) 之 实现注解式权限验证

对大部分系统来说都需要权限管理来决定不同用户可以看到哪些内容,那么如何在Spring MVC中实现权限验证呢?当然我们可以继续使用servlet中的过滤器Filter来实现.但借助于Spring MVC中的action拦截器我们可以实现注解式的权限验证. 一.首先介绍一下action拦截器: HandlerInterceptor是Spring MVC为我们提供的拦截器接口,来让我们实现自己的处理逻辑,HandlerInterceptor 的内容如下: public interface Handl

SpringMVC学习系列(1) 之 初识SpringMVC

1.前言: 与SpringMVC的结识源于个人之前想做一个微信公众账号的管理平台玩玩,既然要做就需要考虑平台的选择问题.由于我的朋友只有一台运行了Linux系统的虚拟主机,且上面还运行有他自己的一些论坛.找不到windows虚拟主机,且肯定不能换朋友主机的系统.刚开始时打算用mono把之前做的.Net MVC项目搭的框架运行一下看看能不能用,发现根本跑不起来(项目用了Spring.NET当时mono和Spring.NET还不兼容,Sping.NET论坛说是由于mono的反射实现机制的问题.好消息

SpringMVC学习系列(8) 之 国际化

在系列(7)中我们讲了数据的格式化显示,Spring在做格式化展示的时候已经做了国际化处理,那么如何将我们网站的其它内容(如菜单.标题等)做国际化处理呢?这就是本篇要将的内容->国际化. 一.基于浏览器请求的国际化实现: 首先配置我们项目的springservlet-config.xml文件添加的内容如下: <bean id="messageSource" class="org.springframework.context.support.ResourceBun

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

前一篇简单介绍了Spring MVC的一些知识,下面就要开始学习如何把Spring MVC运用到具体的项目中去. 首先还是从一个简单的Hello World项目说起: 我机器的开发环境为: Ubuntu12.04(不同操作系统对本系列项目没有什么影响): 开发工具:Eclipse: 数据库:MySql5.5.35; 运行环境:TomCat V7.0: JDK:JDK 1.7.0_45: 项目工程为:Dynamic Web Project: 一.项目依赖的jar包: 1.Spring框架依赖的ja