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

来源:互联网 发布:安装centos要下载哪些 编辑:程序博客网 时间:2024/06/01 17:38

请求参数数据映射限定

@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内建的类型转换器

第一组:标量转换器

类名 说明 StringToBooleanConverter String—–>Boolean true:true/on/yes/1;
false:false/off/no/0 ObjectToStringConverter Object—–>String
调用toString方法转换 StringToNumberConverterFactory String—–>Number(如Integer、Long等) NumberToNumberConverterFactory Number子类型<——>Number子类型(Integer、Long、Double等) StringToCharacterConverter String —–>java.lang.Character 取字符串第一个字符 NumberToCharacterConverter Number子类型(Integer、Long、Double等)——> java.lang.Character CharacterToNumberFactory java.lang.Character ——>Number子类型(Integer、Long、Double等) StringToEnumConverterFactory String—–>enum类型
通过Enum.valueOf将字符串转换为需要的enum类型 EnumToStringConverter enum类型—–>String
返回enum对象的name()值 StringToLocaleConverter String—–>java.util.Local PropertiesToStringConverter java.util.Properties—–>String
默认通过ISO-8859-1解码 StringToPropertiesConverter String—–>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) 即集合之间的类型转换 MapToMapConverter Map<—->Map之间的转换 ArrayToStringConverter 任意S数组—->String类型 StringToArrayConverter String—–>数组 默认通过“,”分割,且去除字符串的两边空格(trim) ArrayToObjectConverter 任意S数组—->任意Object的转换
(如果目标类型和源类型兼容,直接返回源对象;否则返回S数组的第一个元素并进行类型转换) ObjectToArrayConverter Object—–>单元素数组 CollectionToStringConverter 任意T集合(List、Set)—->String类型 StringToCollectionConverter String—–>集合(List、Set)
默认通过“,”分割,且去除字符串的两边空格(trim) CollectionToObjectConverter 任意T集合—->任意Object的转换
(如果目标类型和源类型兼容,直接返回源对象;否则返回S数组的第一个元素并进行类型转换) ObjectToCollectionConverter Object—–>单元素集合


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

类名 说明 ObjectToObjectConverter Object(S)—–>Object(T)
首先尝试valueOf进行转换、没有则尝试new 构造器(S) IdToEntityConverter Id(S)—–>Entity(T)
查找并调用public static T findEntityName获取目标对象,EntityName是T类型的简单类型 FallbackObjectToStringConverter Object—–>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内建的格式化转换器

类名 说明 DateFormatter java.util.Date<—->String 实现日期的格式化/解析 NumberFormatter java.lang.Number<—->String 实现通用样式的格式化/解析 CurrencyFormatter java.lang.BigDecimal<—->String 实现货币样式的格式化/解析 PercentFormatter java.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