0061 Spring MVC的數據格式化--Formatter--FormatterRegistrar--@DateTimeFormat--@NumberFormat


Converter只完成了數據類型的轉換,卻不負責輸入輸出數據的格式化工作,日期時間、貨幣等雖都以字符串形式存在,卻有不同的格式。

Spring格式化框架要解決的問題是:從格式化的數據中獲取真正的數據,綁定數據,將處理完成的數據輸出為格式化的數據。Formatter接口就是該框架最重要的接口

Converter主要是做Object與Object之間的類型轉換,Formatter則是要完成任意Object與String之間的類型轉換。前者適合於任何一層,而后者則主要用於web層

下面用Formatter接口完成0060中用converter完成的功能

先寫個類實現Formatter接口

package net.sonng.mvcdemo.converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import org.springframework.format.Formatter;

public class DateFormatter implements Formatter<Date> {
    private String datePattern;
    private SimpleDateFormat dateFormat;
    public DateFormatter(String datePattern){
        this.datePattern=datePattern;
        dateFormat=new SimpleDateFormat(datePattern);
    }
    @Override
    public String print(Date date,Locale locale){
        System.out.println("Date轉String類型執行中。。。。");
        return dateFormat.format(date);
    }
    @Override
    public Date parse(String source,Locale locale) throws ParseException{
        try{
            System.out.println("字符串轉Date類型執行中。。。。");
            return dateFormat.parse(source);
        }catch(Exception ex){
            ex.printStackTrace();
            throw new IllegalArgumentException();
        }
    }
}

配置xml

    <mvc:annotation-driven conversion-service="conversionService" />
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <!-- FormattingConversionServiceFactoryBean實現了ConversionService接口,具有類型轉換和格式化的功能,既可以配置converters又可以配置formatters -->
        <property name="formatters">
            <list>
                <bean class="net.sonng.mvcdemo.converter.DateFormatter" c:_0="dd-MM-yyyy" /> <!-- 注意日期格式日-月-年 -->
            </list>
        </property>
    </bean>

訪問index.html,輸入數據,注意生日處按日月年的格式輸入

使用FormatterRegistrar注冊Formatter

要使用Formatter,除了上面的將其配置在FormattingConversionServiceFactoryBeanformatters屬性中外,還可以像下面這樣注冊

寫個類實現FormatterRegistrar

package net.sonng.mvcdemo.converter;

import org.springframework.format.FormatterRegistrar;
import org.springframework.format.FormatterRegistry;

public class MyFormatterRegistrar implements FormatterRegistrar {  //實現FormatterRegistrar接口
    private DateFormatter dateFormatter;
    
    public void setDateFormatter(DateFormatter dateFormatter) {    //setter
        this.dateFormatter = dateFormatter;
    }

    @Override
    public void registerFormatters(FormatterRegistry registry) {    
        registry.addFormatter(dateFormatter);                      //注冊給定的formatter
    }
}

配置xml

    <mvc:annotation-driven conversion-service="conversionService" />
    <bean id="dateFormatter" class="net.sonng.mvcdemo.converter.DateFormatter" c:_0="dd-MM-yyyy" />   <!-- 聲明formatter的bean,提供給下面的MyFormatterRegistrar -->
    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
        <property name="formatterRegistrars">  <!-- 這里可以配置converters,formatters,還可以配置formatterRegistrars -->
            <set>
                <bean class="net.sonng.mvcdemo.converter.MyFormatterRegistrar" p:dateFormatter-ref="dateFormatter"  />
            </set>
        </property>
    </bean>

Spring提供的一些Formatter實現

實際上,Spring自身已經將DateFormatter寫好了,位於org.springframework.format.datetime包下
另外在org.springframework.format.number包下面還提供了三個用於數字對象格式化的實現類
----NumberFormatter:用於數字類型
----CurrencyFormatter:用戶貨幣類型
----PercentFormatter:用於百分數數字類型

用注解配置Formatter

先寫個index.html,分別測試日期、整數、百分數、貨幣類型

<!DOCTYPE html>
<html>
<head>
    <title>Spring MVC的數據類型轉換</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type="text/javascript" src="resources/jquery-3.1.0.js"></script>
    <script type="text/javascript" src="resources/json2.js"></script>
    
</head>
    <body>
        <form action="register" method="post">
            日期類型:<input type="text" name="birthday" /> <br><br>
            整數類型:<input type="text" name="total" /> <br><br>
            百分數類型:<input type="text" name="discount" /><br><br>
            貨幣類型:<input type="text" name="money" /><br><br>
                <input type="submit" value="提交" />
        </form>
    </body>
</html>

實體類User,注解就加在該類的實例變量上

package net.sonng.mvcdemo.entity;

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 User {
    @DateTimeFormat(pattern="dd-MM-yyyy")                           //注解加在實例變量上
    private Date birthday;
    @NumberFormat(style=Style.NUMBER,pattern="#,###")               //說是這兩個屬性互斥,怎么可以同時出現呢?
    private int total;
    @NumberFormat(style=Style.PERCENT)
    private double discount;
    @NumberFormat(style=Style.CURRENCY)
    private double money;
    //。。。。。。。
}

controller

package net.sonng.mvcdemo.controller;

import net.sonng.mvcdemo.entity.User;

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

@Controller
public class UserController {
    
    @RequestMapping("/register")
    public String register(User user,Model model){
        model.addAttribute("user", user);
        return "result";
    }
}

result.jsp

<%@page pageEncoding="utf-8" 
        contentType="text/html;charset=utf-8" %>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>測試AnnotationFormatterFactory</title>
</head>
<body>
<h3>測試表單數據格式化</h3>
<form:form modelAttribute="user" method="post" action="" >
<table>
    <tr>
        <td>日期類型:</td>
        <td><form:input path="birthday"/></td>
    </tr>
    <tr>
        <td>整數類型:</td>
        <td><form:input path="total"/></td>
    </tr>
    <tr>
        <td>百分數類型:</td>
        <td><form:input path="discount"/></td>
    </tr>
    <tr>
        <td>貨幣類型:</td>
        <td><form:input path="money"/></td>
    </tr>
</table>
</form:form>
</body>
</html>

輸入:

輸出:

org.springframework.format.annotation包下有兩個注解:@DateTimeForamt和@NumberFormat

@DateTimeFormat
可以注釋java.util.Date, java.util.Calendar, java.lang.Long等時間類型的變量,擁有以下三個互斥屬性
----iso:類型為DateTimeFormat.ISO,常用值:
--------DateTimeFormat.ISO.DATE: 格式為yyyy-MM-dd
--------DateTimeFormat.ISO.DATE_TIME: 格式為yyyy-MM-dd hh:mm:ss .SSSZ
--------DateTimeFormat.ISO.TIME: 格式為hh:mm:ss .SSSZ
--------DateTimeFormat.ISO.NONE: 不使用ISO格式的時間
----pattern:類型為String,使用自定義的時間格式化字符串,如yyyy-MM-dd hh:mm:ss
----style:類型為String,通過樣式指定日期時間的格式,由兩位字符組成,第一位表示日期,第二為表示時間
--------S:短日期時間樣式
--------M:中日期時間樣式
--------L:長日期時間樣式
--------F:完整日期時間樣式
---------:(短橫線)忽略日期時間樣式

@NumberFormat
可注釋類似數字類型的實例變量,擁有兩個互斥屬性
----pattern:類型String,使用自定義的數字格式化串,如##,###表示50,000
----style:類型NumberFormat.Style,幾個常用值:
--------Style.CURRENCY: 貨幣類型
--------Style.NUMBER: 正常數字類型
--------Style.PERCENT: 百分比類型

總結

數據格式化也包含了部分數據轉換的內容

實現Formatter接口,重寫print()與parse()方法,實現自定義的數據格式化

Spring MVC提供了幾個格式化類:DateFormatter、NumberFormatter、CurrencyFormatter、PercentFormatter

利用注解@NumberFormat和@DateTimeFormat,注釋在實體類的實例變量上,也可以實現日期、時間、數字的格式化


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM