SpringMVC框架笔记整理(三): 注解式控制器-数据处理

请求参数数据映射限定

@RequestMapping(params="create", method=RequestMethod.GET)
public String showForm() {
    System.out.println("===============showForm");
    return "parameter/create";
}

@RequestMapping(params=”create”, method=RequestMethod.GET) :表示请求中有“create”的参数名且请求方法为“GET”即可匹配,如可匹配的请求URL“http://×××/parameter1?create”;

//请求参数不包含 create参数名,进行类级别的@RequestMapping窄
@RequestMapping(params="!create", method=RequestMethod.GET)

/**
表示请求中的有“test1”参数名 且 有“test2=create”参数即可匹配,
如可匹配的请求URL“http://×××/parameter3?test1&test2=create。
*/
@RequestMapping(params={"test1", "test2=create"})

数据绑定

1、@RequestParam绑定单个请求参数值;
2、@PathVariable绑定URI模板变量值;
3、@CookieValue绑定Cookie数据值
4、@RequestHeader绑定请求头数据;
5、@ModelValue绑定参数到命令对象;
6、@SessionAttributes绑定命令对象到session;
7、@RequestBody绑定请求的内容区数据并能进行自动类型转换等。
8、@RequestPart绑定“multipart/data”数据,除了能绑定@RequestParam能做到的请求参数外,还能绑定上传的文件等

除了上边提到的注解,可以通过如HttpServletRequest等API得到请求数据,但推荐使用注解方式,因为使用起来更简单

Spring Web MVC 提供Model、Map或ModelMap让我们能去暴露渲染视图需要的模型数据

@RequestMapping(value = "/model") 
public String createUser(Model model, Map model2, ModelMap model3) { 
    model.addAttribute("a", "a");
    model3.put("c", "c"); 
    System.out.println(model2 == model3);
    return "success";
}

这里写图片描述

AnnotationMethodHandlerAdapter和RequestMappingHandlerAdapter 使用BindingAwareModelMap作为模型对象的实现,即此处我们的形参 (Model model, Map model2, ModelMap model3)都是同一个BindingAwareModelMap实例。

//添加模型数据
model.addAttribute("a", "a"); 

ModelAndView mv = new ModelAndView("success"); 
//在视图渲染之前更新同名"a"的模型数据
mv.addObject("a", "update"); 

//修改同名模型数据
model.addAttribute("a", "new"); 

// 视图页面的a将显示为"update" 而不是"new"

处理方法的返回值中的模型数据(如ModelAndView)会 合并 功能处理方法形式参数中的模型数据(如Model),但如果两者之间有同名的,返回值中的模型数据会覆盖形式参数中的模型数据

1、请求参数绑定 @RequestParam

这里写图片描述

这里写图片描述

如/hello3/?username=zhang

2、绑定URI模版变量值@PathVariable
用于将请求URL中的模板变量映射到功能处理方法的参数上

这里写图片描述

这里写图片描述

数据类型转换

Spring3开始,我们可以使用如下架构进行类型转换、验证及格式化

这里写图片描述

流程:
①:类型转换:内部的ConversionService会根据S源类型/T目标类型自动选择相应的Converter SPI进行类型转换,而且是强类型的,能在任意类型数据之间进行转换;
②:数据验证:支持JSR-303验证框架,如将@Valid放在需要验证的目标类型上即可;
③:格式化显示:其实就是任意目标类型—->String的转换,完全可以使用Converter SPI完成。

在Spring Web MVC环境中,数据类型转换、验证及格式化通常是这样使用的

这里写图片描述

①、类型转换:首先表单数据(全部是字符串)通过WebDataBinder进行绑定到命令对象,内部通过Converter SPI实现;
②:数据验证:使用JSR-303验证框架进行验证;
③:格式化显示:在表单页面可以通过如下方式展示通过内部通过Converter SPI格式化的数据和错误信息:

Converter SPI (类型转换器):用于数据类型转换
Formatter SPI (格式化转换器):通常需要将数据转换为具有某种格式的字符串进行展示,进行数据格式化服务、

首先需要通过如上taglib指令引入spring的两个标签库。

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

Spring内建的类型转换器

第一组:标量转换器

类名说明
StringToBooleanConverterString—–>Boolean true:true/on/yes/1;
false:false/off/no/0
ObjectToStringConverterObject—–>String
调用toString方法转换
StringToNumberConverterFactoryString—–>Number(如Integer、Long等)
NumberToNumberConverterFactoryNumber子类型<——>Number子类型(Integer、Long、Double等)
StringToCharacterConverterString —–>java.lang.Character 取字符串第一个字符
NumberToCharacterConverterNumber子类型(Integer、Long、Double等)——> java.lang.Character
CharacterToNumberFactoryjava.lang.Character ——>Number子类型(Integer、Long、Double等)
StringToEnumConverterFactoryString—–>enum类型
通过Enum.valueOf将字符串转换为需要的enum类型
EnumToStringConverterenum类型—–>String
返回enum对象的name()值
StringToLocaleConverterString—–>java.util.Local
PropertiesToStringConverterjava.util.Properties—–>String
默认通过ISO-8859-1解码
StringToPropertiesConverterString—–>java.util.Properties
默认使用ISO-8859-1编码


第二组:集合、数组相关转换器

类名说明
ArrayToCollectionConverter任意S数组—->任意T集合(List、Set)
CollectionToArrayConverter任意T集合(List、Set)—->任意S数组
ArrayToArrayConverter任意S数组<—->任意T数组
CollectionToCollectionConverter任意T集合(List、Set)<—->任意T集合(List、Set) 即集合之间的类型转换
MapToMapConverterMap<—->Map之间的转换
ArrayToStringConverter任意S数组—->String类型
StringToArrayConverterString—–>数组 默认通过“,”分割,且去除字符串的两边空格(trim)
ArrayToObjectConverter任意S数组—->任意Object的转换
(如果目标类型和源类型兼容,直接返回源对象;否则返回S数组的第一个元素并进行类型转换)
ObjectToArrayConverterObject—–>单元素数组
CollectionToStringConverter任意T集合(List、Set)—->String类型
StringToCollectionConverterString—–>集合(List、Set)
默认通过“,”分割,且去除字符串的两边空格(trim)
CollectionToObjectConverter任意T集合—->任意Object的转换
(如果目标类型和源类型兼容,直接返回源对象;否则返回S数组的第一个元素并进行类型转换)
ObjectToCollectionConverterObject—–>单元素集合


第三组:默认(fallback)转换器:之前的转换器不能转换时调用

类名说明
ObjectToObjectConverterObject(S)—–>Object(T)
首先尝试valueOf进行转换、没有则尝试new 构造器(S)
IdToEntityConverterId(S)—–>Entity(T)
查找并调用public static T findEntityName获取目标对象,EntityName是T类型的简单类型
FallbackObjectToStringConverterObject—–>String ConversionService
作为恢复使用,即其他转换器不能转换时调用(执行对象的toString()方法)


S:代表源类型,T:代表目标类型
如上的转换器在使用转换服务实现 DefaultConversionService和DefaultFormattingConversionService时会自动注册

数据格式化

格式化转换器:提供格式化转换的实现支持。

这里写图片描述

1、Printer接口:格式化显示接口,将T类型的对象根据Locale信息以某种格式进行打印显示(即返回字符串形式);

package org.springframework.format; 
public interface Printer<T> { 
    String print(T object, Locale locale);  
}

2、Parser接口:解析接口,根据Locale信息解析字符串到T类型的对象;

package org.springframework.format;
public interface Parser<T> { 
    T parse(String text, Locale locale) throws ParseException;
}

解析失败可以抛出java.text.ParseException或IllegalArgumentException异常即可。

3、Formatter接口:格式化SPI接口,继承Printer和Parser接口,完成T类型对象的格式化和解析功能;

package org.springframework.format; 
public interface Formatter<T> extends Printer<T>, Parser<T> {
}

4、AnnotationFormatterFactory接口:注解驱动的字段格式化工厂,用于创建带注解的对象字段的Printer和Parser,即用于格式化和解析带注解的对象字段。

package org.springframework.format; 

public interface AnnotationFormatterFactory<A extends Annotation> {//①可以识别的注解类型 
    //②可以被A注解类型注解的字段类型集合 
    Set<Class<?>> getFieldTypes();  

    //③根据A注解类型和fieldType类型获取Printer 
    Printer<?> getPrinter(A annotation, Class<?> fieldType);    

    //④根据A注解类型和fieldType类型获取Parser 
    Parser<?> getParser(A annotation, Class<?> fieldType);
}

返回用于格式化和解析被A注解类型注解的字段值的Printer和Parser。如JodaDateTimeFormatAnnotationFormatterFactory可以为带有@DateTimeFormat注解的java.util.Date字段类型创建相应的Printer和Parser进行格式化和解析。

Spring内建的格式化转换器

类名说明
DateFormatterjava.util.Date<—->String 实现日期的格式化/解析
NumberFormatterjava.lang.Number<—->String 实现通用样式的格式化/解析
CurrencyFormatterjava.lang.BigDecimal<—->String 实现货币样式的格式化/解析
PercentFormatterjava.lang.Number<—->String 实现百分数样式的格式化/解析
NumberFormatAnnotationFormatterFactory@NumberFormat注解类型的数字字段类型<—->String

①通过@NumberFormat指定格式化/解析格式
②可以格式化/解析的数字类型:Short、Integer、Long、Float、Double、BigDecimal、BigInteger
JodaDateTimeFormatAnnotationFormatterFactory@DateTimeFormat注解类型的日期字段类型<—->String
①通过@DateTimeFormat指定格式化/解析格式
②可以格式化/解析的日期类型: joda中的日期类型(org.joda.time包中的):LocalDate、LocalDateTime、LocalTime、ReadableInstant java内置的日期类型:Date、Calendar、Long

classpath中必须有Joda-Time类库,否则无法格式化日期类型


NumberFormatAnnotationFormatterFactory 和JodaDateTimeFormatAnnotationFormatterFactory(如果classpath提供了Joda-Time类库)在使用格式化服务实现DefaultFormattingConversionService时会自动注册。

@NumberFormater:定义数字相关的解析/格式化元数据(通用样式、货币样式、百分数样式),参数如下:

  • style:用于指定样式类型,包括三种:Style.NUMBER(通用样式) Style.CURRENCY(货币样式) Style.PERCENT(百分数样式),默认Style.NUMBER;
  • pattern:自定义样式,如patter=”#,###”

@DateTimeFormat:定义日期相关的解析/格式化元数据,参数如下:

  • pattern:指定解析/格式化字段数据的模式,如”yyyy-MM-dd HH:mm:ss”
  • iso:指定解析/格式化字段数据的ISO模式,
    包括四种:
    ISO.NONE(不使用)
    ISO.DATE(yyyy-MM-dd)
    ISO.TIME(hh:mm:ss.SSSZ)
    ISO.DATE_TIME(yyyy-MM-dd hh:mm:ss.SSSZ),默认ISO.NONE;
  • style:指定用于格式化的样式模式,默认“SS”,具体使用请参考Joda-Time类库的org.joda.time.format.DateTimeFormat的forStyle的javadoc;
  • 优先级: pattern 大于 iso 大于 style。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值