`
jinnianshilongnian
  • 浏览: 21434145 次
  • 性别: Icon_minigender_1
博客专栏
5c8dac6a-21dc-3466-8abb-057664ab39c7
跟我学spring3
浏览量:2404982
D659df3e-4ad7-3b12-8b9a-1e94abd75ac3
Spring杂谈
浏览量:2997639
43989fe4-8b6b-3109-aaec-379d27dd4090
跟开涛学SpringMVC...
浏览量:5631433
1df97887-a9e1-3328-b6da-091f51f886a1
Servlet3.1规范翻...
浏览量:257561
4f347843-a078-36c1-977f-797c7fc123fc
springmvc杂谈
浏览量:1593147
22722232-95c1-34f2-b8e1-d059493d3d98
hibernate杂谈
浏览量:248965
45b32b6f-7468-3077-be40-00a5853c9a48
跟我学Shiro
浏览量:5847500
Group-logo
跟我学Nginx+Lua开...
浏览量:698136
5041f67a-12b2-30ba-814d-b55f466529d5
亿级流量网站架构核心技术
浏览量:780438
社区版块
存档分类
最新评论

SpringMVC数据类型转换——第七章 注解式控制器的数据验证、类型转换及格式化——跟着开涛学SpringMVC

 
阅读更多

 

7.1、简介

在编写可视化界面项目时,我们通常需要对数据进行类型转换、验证及格式化。

 

一、在Spring3之前,我们使用如下架构进行类型转换、验证及格式化:



 流程:

①:类型转换:首先调用PropertyEditor的setAsText(String),内部根据需要调用setValue(Object)方法进行设置转换后的值;

②:数据验证:需要显示调用Spring的Validator接口实现进行数据验证;

③:格式化显示:需要调用PropertyEditor的getText进行格式化显示。

 

使用如上架构的缺点是:

1、PropertyEditor被设计为只能String<——>Object之间转换,不能任意对象类型<——>任意类型,如我们常见的Long时间戳到Date类型的转换是办不到的;

2、PropertyEditor是线程不安全的,也就是有状态的,因此每次使用时都需要创建一个,不可重用;

3、PropertyEditor不是强类型的,setValue(Object)可以接受任意类型,因此需要我们自己判断类型是否兼容;

4、需要自己编程实现验证,Spring3支持更棒的注解验证支持;

5、在使用SpEL表达式语言或DataBinder时,只能进行String<--->Object之间的类型转换;

6不支持细粒度的类型转换/格式化,如UserModel的registerDate需要转换/格式化类似“2012-05-01”的数据,而OrderModel的orderDate需要转换/格式化类似“2012-05-01 15:11:13”的数据,因为大家都为java.util.Date类型,因此不太容易进行细粒度转换/格式化。

 

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



 流程:

①、类型转换:首先表单数据(全部是字符串)通过WebDataBinder进行绑定到命令对象,内部通过PropertyEditor实现;

②:数据验证:在控制器中的功能处理方法中,需要显示的调用Spring的Validator实现并将错误信息添加到BindingResult对象中;

③:格式化显示:在表单页面可以通过如下方式展示通过PropertyEditor格式化的数据和错误信息:

 

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

 

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

//1、格式化单个命令/表单对象的值(好像比较麻烦,真心没有好办法)
<spring:bind path="dataBinderTest.phoneNumber">${status.value}</spring:bind> 
//2、通过form标签,内部的表单标签会自动调用命令/表单对象属性对应的PropertyEditor进行格式化显示
<form:form commandName="dataBinderTest">
    <form:input path="phoneNumber"/><!-- 如果出错会显示错误之前的数据而不是空 -->
</form:form> 
//3、显示验证失败后的错误信息
<form:errors></form:errors> 

如上PropertyEditor和验证API使用起来比较麻烦,而且有许多缺点,因此Spring3提供了更强大的类型转换(Type Conversion)支持,它可以在任意对象之间进行类型转换,不仅仅是String<——>Object;也提供了强大的数据验证支持;同时提供了强大的数据格式化支持。

 

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


 流程:

①:类型转换:内部的ConversionService会根据S源类型/T目标类型自动选择相应的Converter SPI进行类型转换,而且是强类型的,能在任意类型数据之间进行转换

②:数据验证:支持JSR-303验证框架,如将@Valid放在需要验证的目标类型上即可;

③:格式化显示:其实就是任意目标类型---->String的转换,完全可以使用Converter SPI完成。

 

Spring为了更好的诠释格式化/解析功能提供了Formatter SPI,支持根据Locale信息进行格式化/解析,而且该套SPI可以支持字段/参数级别的细粒度格式化/解析,流程如下:

①:类型解析(转换):String---->T类型目标对象的解析,和PropertyEditor类似;

③:格式化显示:任意目标类型---->String的转换,和PropertyEditor类似。

 

Formatter SPI最大特点是能进行字段/参数级别的细粒度解析/格式化控制,即使是Converter SPI也是粗粒度的(到某个具体类型,而不是其中的某个字段单独控制),目前Formatter SPI还不是很完善,如果您有好的想法可以到Spring官网提建议。

 

Formatter SPI内部实现实际委托给Converter SPI进行转换,即约束为解析/格式化String<---->任意目标类型。

 

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


 

①、类型转换:首先表单数据(全部是字符串)通过WebDataBinder进行绑定到命令对象,内部通过Converter SPI实现;

②:数据验证:使用JSR-303验证框架进行验证;

③:格式化显示:在表单页面可以通过如下方式展示通过内部通过Converter SPI格式化的数据和错误信息:

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

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

//1、格式化单个命令/表单对象的值(好像比较麻烦,真心没有好办法)
<spring:bind path="dataBinderTest.phoneNumber">${status.value}</spring:bind> 
//2、<spring:eval>标签,自动调用ConversionService并选择相应的Converter SPI进行格式化展示
<spring:eval expression="dataBinderTest.phoneNumber"></spring:eval> 

如上代码能工作的前提是在RequestMappingHandlerMapping配置了ConversionServiceExposingInterceptor,它的作用是暴露conversionService到请求中以便如<spring:eval>标签使用。

//3、通过form标签,内部的表单标签会自动调用命令/表单对象属性对应的PropertyEditor进行格式化显示
<form:form commandName="dataBinderTest">
    <form:input path="phoneNumber"/><!-- 如果出错会显示错误之前的数据而不是空 -->
</form:form> 
//4、显示验证失败后的错误信息
<form:errors></form:errors> 

接下来我们就详细学习一下这些知识吧。

 

 

7.2、数据类型转换

7.2.1、Spring3之前的PropertyEditor

PropertyEditor介绍请参考【4.16.1、数据类型转换】。

 

一、测试之前我们需要准备好测试环境:

1、模型对象,和【4.16.1、数据类型转换】使用的一样,需要将DataBinderTestModel模型类及相关类拷贝过来放入cn.javass.chapter7.model包

2、控制器定义:         

 

package cn.javass.chapter7.web.controller;
//省略import
@Controller
public class DataBinderTestController {
    @RequestMapping(value = "/dataBind")
    public String test(DataBinderTestModel command) {
        	//输出command对象看看是否绑定正确
		System.out.println(command);
		model.addAttribute("dataBinderTest", command);
		return "bind/success";
	}
}

 

 (3、Spring配置文件定义,请参考chapter7-servlet.xml,并注册DataBinderTestController

 

<bean class="cn.javass.chapter7.web.controller.DataBinderTestController"/> 

4、测试的URL:

http://localhost:9080/springmvc-chapter7/dataBind?username=zhang&bool=yes&schooInfo.specialty=computer&hobbyList[0]=program&hobbyList[1]=music&map[key1]=value1&map[key2]=value2&phoneNumber=010-12345678&date=2012-3-18 16:48:48&state=blocked

 

二、注解式控制器注册PropertyEditor:

 

1、使用WebDataBinder进行控制器级别注册PropertyEditor(控制器独享)

@InitBinder
//此处的参数也可以是ServletRequestDataBinder类型
public void initBinder(WebDataBinder binder) throws Exception {
	//注册自定义的属性编辑器
	//1、日期
	DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	CustomDateEditor dateEditor = new CustomDateEditor(df, true);
	//表示如果命令对象有Date类型的属性,将使用该属性编辑器进行类型转换
	binder.registerCustomEditor(Date.class, dateEditor);	
	//自定义的电话号码编辑器(和【4.16.1、数据类型转换】一样)
	binder.registerCustomEditor(PhoneNumberModel.class, new PhoneNumberEditor());
} 

和【4.16.1、数据类型转换】一节类似,只是此处需要通过@InitBinder来注册自定义的PropertyEditor。

 

2、使用WebBindingInitializer批量注册PropertyEditor

4.16.1、数据类型转换】不太一样,因为我们的注解式控制器是POJO,没有实现任何东西,因此无法注入WebBindingInitializer,此时我们需要把WebBindingInitializer注入到我们的RequestMappingHandlerAdapter或AnnotationMethodHandlerAdapter,这样对于所有的注解式控制器都是共享的。

<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
  <property name="webBindingInitializer">
    <bean class="cn.javass.chapter7.web.controller.support.initializer.MyWebBindingInitializer"/>
  </property>
</bean> 

此时我们注释掉控制器级别通过@InitBinder注册PropertyEditor的方法。

3、全局级别注册PropertyEditor(全局共享)

和【4.16.1、数据类型转换】一节一样,此处不再重复。请参考【4.16.1、数据类型转换】的【全局级别注册PropertyEditor(全局共享)】。

 

接下来我们看一下Spring3提供的更强大的类型转换支持

 

7.2.2、Spring3开始的类型转换系统

Spring3引入了更加通用的类型转换系统,其定义了SPI接口(Converter等)和相应的运行时执行类型转换的API(ConversionService等),在Spring中它和PropertyEditor功能类似,可以替代PropertyEditor来转换外部Bean属性的值到Bean属性需要的类型。

 

该类型转换系统是Spring通用的,其定义在org.springframework.core.convert包中,不仅仅在Spring Web MVC场景下。目标是完全替换PropertyEditor,提供无状态、强类型且可以在任意类型之间转换的类型转换系统,可以用于任何需要的地方,如SpEL、数据绑定。

 

Converter SPI完成通用的类型转换逻辑,如java.util.Date<---->java.lang.Long或java.lang.String---->PhoneNumberModel等。

 

7.2.2.1、架构

1、类型转换器:提供类型转换的实现支持。


 

一个有如下三种接口:

1、Converter:类型转换器,用于转换S类型到T类型,此接口的实现必须是线程安全的且可以被共享。

package org.springframework.core.convert.converter;
public interface Converter<S, T> { //① S是源类型 T是目标类型
	T convert(S source); //② 转换S类型的source到T目标类型的转换方法
} 

示例:请参考cn.javass.chapter7.converter.support.StringToPhoneNumberConverter转换器,用于将String--->PhoneNumberModel。

 

此处我们可以看到Converter接口实现只能转换一种类型到另一种类型,不能进行多类型转换,如将一个数组转换成集合,如(String[] ----> List<String>String[]----->List<PhoneNumberModel>等)。

 

2、GenericConverter和ConditionalGenericConverter:GenericConverter接口实现能在多种类型之间进行转换,ConditionalGenericConverter是有条件的在多种类型之间进行转换。

package org.springframework.core.convert.converter;
public interface GenericConverter {
    Set<ConvertiblePair> getConvertibleTypes();
    Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
}

getConvertibleTypes:指定了可以转换的目标类型对;

convert:在sourceType和targetType类型之间进行转换。

package org.springframework.core.convert.converter;
public interface ConditionalGenericConverter extends GenericConverter {
	boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType);
} 

matches:用于判断sourceType和targetType类型之间能否进行类型转换。

 

示例:如org.springframework.core.convert.support.ArrayToCollectionConverter和CollectionToArrayConverter用于在数组和集合间进行转换的ConditionalGenericConverter实现,如在String[]<---->List<String>、String[]<---->List<PhoneNumberModel>等之间进行类型转换。

 

对于我们大部分用户来说一般不需要自定义GenericConverter, 如果需要可以参考内置的GenericConverter来实现自己的。

 

3、ConverterFactory:工厂模式的实现,用于选择将一种S源类型转换为R类型的子类型T的转换器的工厂接口。

package org.springframework.core.convert.converter;
public interface ConverterFactory<S, R> {
	<T extends R> Converter<S, T> getConverter(Class<T> targetType);
} 

S:源类型;R目标类型的父类型;T:目标类型,且是R类型的子类型;

getConverter:得到目标类型的对应的转换器。

 

示例:如org.springframework.core.convert.support.NumberToNumberConverterFactory用于在Number类型子类型之间进行转换,如Integer--->Double, Byte---->Integer, Float--->Double等。

 

对于我们大部分用户来说一般不需要自定义ConverterFactory,如果需要可以参考内置的ConverterFactory来实现自己的。

 

2、类型转换器注册器、类型转换服务:提供类型转换器注册支持,运行时类型转换API支持。


一共有如下两种接口:

1、ConverterRegistry:类型转换器注册支持,可以注册/删除相应的类型转换器。

package org.springframework.core.convert.converter;
public interface ConverterRegistry {
	void addConverter(Converter<?, ?> converter);
	void addConverter(Class<?> sourceType, Class<?> targetType, Converter<?, ?> converter);
	void addConverter(GenericConverter converter);
	void addConverterFactory(ConverterFactory<?, ?> converterFactory);
	void removeConvertible(Class<?> sourceType, Class<?> targetType);
} 

可以注册:Converter实现,GenericConverter实现,ConverterFactory实现。

 

2、ConversionService:运行时类型转换服务接口,提供运行期类型转换的支持。

package org.springframework.core.convert;
public interface ConversionService {
	boolean canConvert(Class<?> sourceType, Class<?> targetType);
	boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType);
	<T> T convert(Object source, Class<T> targetType);
	Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);
} 

convert:将源对象转换为目标类型的目标对象。

 

Spring提供了两个默认实现(其都实现了ConverterRegistryConversionService接口):

DefaultConversionService:默认的类型转换服务实现;

DefaultFormattingConversionService:带数据格式化支持的类型转换服务实现,一般使用该服务实现即可。

 

7.2.2.2、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子类型(Integer、Long、Double等)<——> 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 find[EntityName](S)获取目标对象,EntityName是T类型的简单类型

FallbackObjectToStringConverter

Object----->String

ConversionService作为恢复使用,即其他转换器不能转换时调用(执行对象的toString()方法)

S:代表源类型,T:代表目标类型

如上的转换器在使用转换服务实现DefaultConversionService和DefaultFormattingConversionService时会自动注册。

 

7.2.2.3、示例

1、自定义String----->PhoneNumberModel的转换器

 

package cn.javass.chapter7.web.controller.support.converter;
//省略import
public class StringToPhoneNumberConverter implements Converter<String, PhoneNumberModel> {
	Pattern pattern = Pattern.compile("^(\\d{3,4})-(\\d{7,8})$");
	@Override
	public PhoneNumberModel convert(String source) {		
		if(!StringUtils.hasLength(source)) {
			//①如果source为空 返回null
			return null;
		}
		Matcher matcher = pattern.matcher(source);
		if(matcher.matches()) {
			//②如果匹配 进行转换
			PhoneNumberModel phoneNumber = new PhoneNumberModel();
			phoneNumber.setAreaCode(matcher.group(1));
			phoneNumber.setPhoneNumber(matcher.group(2));
			return phoneNumber;
		} else {
			//③如果不匹配 转换失败
			throw new IllegalArgumentException(String.format("类型转换失败,需要格式[010-12345678],但格式是[%s]", source));
		}
	}
}

String转换为Date的类型转换器,请参考cn.javass.chapter7.web.controller.support.converter.StringToDateConverter。

 

(2、测试用例(cn.javass.chapter7.web.controller.support.converter.ConverterTest)

@Test
public void testStringToPhoneNumberConvert() {
	DefaultConversionService conversionService = new DefaultConversionService();
	conversionService.addConverter(new StringToPhoneNumberConverter());
	
	String phoneNumberStr = "010-12345678";
	PhoneNumberModel phoneNumber = conversionService.convert(phoneNumberStr, PhoneNumberModel.class);
		
	Assert.assertEquals("010", phoneNumber.getAreaCode());
} 

类似于PhoneNumberEditor将字符串“010-12345678”转换为PhoneNumberModel。  

 

 

@Test
public void testOtherConvert() {
	DefaultConversionService conversionService = new DefaultConversionService();
	
	//"1"--->true(字符串“1”可以转换为布尔值true)
	Assert.assertEquals(Boolean.valueOf(true), conversionService.convert("1", Boolean.class));
	
	//"1,2,3,4"--->List(转换完毕的集合大小为4)
	Assert.assertEquals(4, conversionService.convert("1,2,3,4", List.class).size());
} 

其他类型转换器使用也是类似的,此处不再重复。

 

7.2.2.4、集成到Spring Web MVC环境

1、注册ConversionService实现和自定义的类型转换器

<!-- ①注册ConversionService -->
<bean id="conversionService" class="org.springframework.format.support.
	 	 	 	 	 	 	 	 	 	 	 FormattingConversionServiceFactoryBean">
    <property name="converters">
       <list>
	        <bean class="cn.javass.chapter7.web.controller.support.
	 	 	 	 	 	 	 converter.StringToPhoneNumberConverter"/>
	        <bean class="cn.javass.chapter7.web.controller.support.
	 	 	 	 	 	 	 converter.StringToDateConverter">
	            <constructor-arg value="yyyy-MM-dd"/>
	        </bean>
        </list>
    </property>
</bean> 

FormattingConversionServiceFactoryBean:是FactoryBean实现,默认使用DefaultFormattingConversionService转换器服务实现;

converters:注册我们自定义的类型转换器,此处注册了String--->PhoneNumberModelString--->Date的类型转换器。

 

2、通过ConfigurableWebBindingInitializer注册ConversionService

<!-- ②使用ConfigurableWebBindingInitializer注册conversionService -->
<bean id="webBindingInitializer" class="org.springframework.web.bind.support.
	        	        	        	        	        	        ConfigurableWebBindingInitializer">
	<property name="conversionService" ref="conversionService"/>
</bean> 

此处我们通过ConfigurableWebBindingInitializer绑定初始化器进行ConversionService的注册;

 

3、注册ConfigurableWebBindingInitializer到RequestMappingHandlerAdapter

<bean class="org.springframework.web.servlet.mvc.method.annotation.
                                                            RequestMappingHandlerAdapter">
<property name="webBindingInitializer" ref="webBindingInitializer"/>
</bean> 

通过如上配置,我们就完成了Spring3.0的类型转换系统与Spring Web MVC的集成。此时可以启动服务器输入之前的URL测试了。

 

此时可能有人会问,如果我同时使用PropertyEditor和ConversionService,执行顺序是什么呢?内部首先查找PropertyEditor进行类型转换,如果没有找到相应的PropertyEditor再通过ConversionService进行转换。

 

如上集成过程看起来比较麻烦,后边我们会介绍<mvc:annotation-driven>和@EnableWebMvc,ConversionService会自动注册,后续章节再详细介绍。

 

     

  • 大小: 11.5 KB
  • 大小: 20.6 KB
  • 大小: 17.2 KB
  • 大小: 23.7 KB
  • 大小: 19.7 KB
  • 大小: 36.1 KB
48
2
分享到:
评论
32 楼 Chen_Zhengguang 2016-12-15  
Chen_Zhengguang 写道
   0..0

呵呵
31 楼 Chen_Zhengguang 2016-12-15  
   0..0
30 楼 sp42 2016-05-02  
anky_end 写道
下士闻道 写道
Spring MVC选择开涛做入门真实极大地错误,开始感觉还可以,越到后来越发现:过时的技术笔墨太多,浪费很多时间;二,整理的思路有些混乱,尤其是到了第七章.........
确实是早期的作品,其实不是不好,而是作为入门来说,还是略微费劲些

====================================================================
第七章的确有点费劲,有些应该讲到的地方没讲到。不过,我还是整体下来,我觉得tao哥讲的springmvc讲的很棒了,比我看的两部书上讲的更深入,整体勾勒了springmvc运行流程是怎样的和一些重点知识的原理是怎样的。表示很接受,第七章部分没讲清楚的,自己查看源码也理解差不多啦,收获很大。在此谢谢开头啦

好像以前写日记,流水账
29 楼 mapc我 2016-04-08  
下士闻道 写道
Spring MVC选择开涛做入门真实极大地错误,开始感觉还可以,越到后来越发现:过时的技术笔墨太多,浪费很多时间;二,整理的思路有些混乱,尤其是到了第七章.........
确实是早期的作品,其实不是不好,而是作为入门来说,还是略微费劲些

====================================================================
第七章的确有点费劲,有些应该讲到的地方没讲到。不过,我还是整体下来,我觉得tao哥讲的springmvc讲的很棒了,比我看的两部书上讲的更深入,整体勾勒了springmvc运行流程是怎样的和一些重点知识的原理是怎样的。表示很接受,第七章部分没讲清楚的,自己查看源码也理解差不多啦,收获很大。在此谢谢开头啦
28 楼 anky_end 2016-04-07  
下士闻道 写道
Spring MVC选择开涛做入门真实极大地错误,开始感觉还可以,越到后来越发现:过时的技术笔墨太多,浪费很多时间;二,整理的思路有些混乱,尤其是到了第七章,很多例子直接使用JUnit,而不是一个完整SpringMVC的实例,学习教程就是让人知道怎么在真实场景下使用,交代不清楚;其实开涛本人技术不错,这点毫无疑问,现在也在京东混得不错;我觉得,一方面,开涛不太知道作为教程的方式,另外,这个系列是开涛早期作品,还真是有点不忍直视。

确实是早期的作品,其实不是不好,而是作为入门来说,还是略微费劲些
27 楼 xchz 2016-04-07  
下士闻道 写道
Spring MVC选择开涛做入门真实极大地错误,开始感觉还可以,越到后来越发现:过时的技术笔墨太多,浪费很多时间;二,整理的思路有些混乱,尤其是到了第七章,很多例子直接使用JUnit,而不是一个完整SpringMVC的实例,学习教程就是让人知道怎么在真实场景下使用,交代不清楚;其实开涛本人技术不错,这点毫无疑问,现在也在京东混得不错;我觉得,一方面,开涛不太知道作为教程的方式,另外,这个系列是开涛早期作品,还真是有点不忍直视。

瞎比比,这是博客,如果你觉得不好,不要来看啊,就算你说的是事实又怎样,这些博客确实帮助了很多人,这就够了
26 楼 下士闻道 2016-03-08  
Spring MVC选择开涛做入门真实极大地错误,开始感觉还可以,越到后来越发现:过时的技术笔墨太多,浪费很多时间;二,整理的思路有些混乱,尤其是到了第七章,很多例子直接使用JUnit,而不是一个完整SpringMVC的实例,学习教程就是让人知道怎么在真实场景下使用,交代不清楚;其实开涛本人技术不错,这点毫无疑问,现在也在京东混得不错;我觉得,一方面,开涛不太知道作为教程的方式,另外,这个系列是开涛早期作品,还真是有点不忍直视。
25 楼 xgc3098 2015-04-24  
xgc3098 写道
请教,我按博主说的配置了自定义类型转换器的注册.但是不成功.
org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type 'bean.PhoneNumberModel'


1300534022@qq.com
24 楼 xgc3098 2015-04-24  
请教,我按博主说的配置了自定义类型转换器的注册.但是不成功.
org.springframework.beans.ConversionNotSupportedException: Failed to convert value of type 'java.lang.String' to required type 'bean.PhoneNumberModel'
23 楼 卡卡goto 2014-06-04  
[color=green][/color]好  我喜欢 跟这感(涛)觉(哥)走
22 楼 jinnianshilongnian 2013-06-17  
Motte2010 写道
jinnianshilongnian 写道
Motte2010 写道
你好
   通过 实现Converter 接口的验证方式,抛出异常后,页面上应该怎么样获取错误结果呢,我使用之前用的<form:error path="*" /> 获取不到任何错误信息(异常确认已抛出)
   另外,
  <spring:bind path="dataBinderTest.phoneNumber">${status.value}</spring:bind>
<spring:eval expression="dataBinderTest.phoneNumber"></spring:eval>
这两个标签具体是做什么用的,能解释一下吗,我尝试用了一下,使用和<form:input 效果一样,只是少了和文本框?

有些常见可能不需要文本框,但需要格式化时就可以使用eval转,否则直接使用el是转不了的

那错误信息应该怎么显示呢? <form:error path="*" /> 不管用 显示为空,异常断点确实已经抛出


异常断点确实已经抛出  加到Errors里了吗

1、
<form:errors></form:errors>   显示所有
<form:errors path="*"/> 显示所有
<form:errors path="id" /> 显示某个路径的
21 楼 Motte2010 2013-06-17  
jinnianshilongnian 写道
Motte2010 写道
你好
   通过 实现Converter 接口的验证方式,抛出异常后,页面上应该怎么样获取错误结果呢,我使用之前用的<form:error path="*" /> 获取不到任何错误信息(异常确认已抛出)
   另外,
  <spring:bind path="dataBinderTest.phoneNumber">${status.value}</spring:bind>
<spring:eval expression="dataBinderTest.phoneNumber"></spring:eval>
这两个标签具体是做什么用的,能解释一下吗,我尝试用了一下,使用和<form:input 效果一样,只是少了和文本框?

有些常见可能不需要文本框,但需要格式化时就可以使用eval转,否则直接使用el是转不了的

那错误信息应该怎么显示呢? <form:error path="*" /> 不管用 显示为空,异常断点确实已经抛出
20 楼 jinnianshilongnian 2013-06-16  
Motte2010 写道
你好
   通过 实现Converter 接口的验证方式,抛出异常后,页面上应该怎么样获取错误结果呢,我使用之前用的<form:error path="*" /> 获取不到任何错误信息(异常确认已抛出)
   另外,
  <spring:bind path="dataBinderTest.phoneNumber">${status.value}</spring:bind>
<spring:eval expression="dataBinderTest.phoneNumber"></spring:eval>
这两个标签具体是做什么用的,能解释一下吗,我尝试用了一下,使用和<form:input 效果一样,只是少了和文本框?

有些常见可能不需要文本框,但需要格式化时就可以使用eval转,否则直接使用el是转不了的
19 楼 Motte2010 2013-06-16  
你好
   通过 实现Converter 接口的验证方式,抛出异常后,页面上应该怎么样获取错误结果呢,我使用之前用的<form:error path="*" /> 获取不到任何错误信息(异常确认已抛出)
   另外,
  <spring:bind path="dataBinderTest.phoneNumber">${status.value}</spring:bind>
<spring:eval expression="dataBinderTest.phoneNumber"></spring:eval>
这两个标签具体是做什么用的,能解释一下吗,我尝试用了一下,使用和<form:input 效果一样,只是少了和文本框?
18 楼 jinnianshilongnian 2013-03-30  
carrotzizi 写道
请问在B/S项目里面用得多不?

看你熟悉程度了 我现在用的挺多的
17 楼 carrotzizi 2013-03-30  
请问在B/S项目里面用得多不?
16 楼 zoezhang 2013-01-24  
jinnianshilongnian 写道
zoezhang 写道
jinnianshilongnian 写道
zoezhang 写道
你好,请问这个到底怎么用?我还是不懂。比如用ArrayToCollectionConverter这个类进行数据类型转换,该怎么做?

建议你下载代码看看

什么代码?spring源代码吗?

http://jinnianshilongnian.iteye.com/blog/1752171

谢谢
15 楼 jinnianshilongnian 2013-01-21  
zoezhang 写道
jinnianshilongnian 写道
zoezhang 写道
你好,请问这个到底怎么用?我还是不懂。比如用ArrayToCollectionConverter这个类进行数据类型转换,该怎么做?

建议你下载代码看看

什么代码?spring源代码吗?

http://jinnianshilongnian.iteye.com/blog/1752171
14 楼 zoezhang 2013-01-21  
jinnianshilongnian 写道
zoezhang 写道
你好,请问这个到底怎么用?我还是不懂。比如用ArrayToCollectionConverter这个类进行数据类型转换,该怎么做?

建议你下载代码看看

什么代码?spring源代码吗?
13 楼 jinnianshilongnian 2013-01-12  
zoezhang 写道
你好,请问这个到底怎么用?我还是不懂。比如用ArrayToCollectionConverter这个类进行数据类型转换,该怎么做?

建议你下载代码看看

相关推荐

    springmvc注解式控制器的数据验证、类型转换及格式化 SpringMVC数据验证

    springmvc注解式控制器的数据验证、类型转换及格式化 SpringMVC数据验证 参数传递

    跟我学SpringMVC 教程

    第七章 注解式控制器的数据验证、类型转换及格式化 SpringMVC数据类型转换 第七章 注解式控制器的数据验证、类型转换及格式化 SpringMVC数据格式化 第七章 注解式控制器的数据验证、类型转换及格式化 SpringMVC...

    跟我学SpringMVC

    第七章 注解式控制器的数据验证、类型转换及格式化 SpringMVC数据类型转换 第七章 注解式控制器的数据验证、类型转换及格式化 SpringMVC数据格式化 第七章 注解式控制器的数据验证、类型转换及格式化 SpringMVC数据...

    SpringMVC数据类型转换超详细介绍

    SpringMVC数据类型转换超详细介绍,注解式控制器的数据验证、类型转换及格式化

    SpringMvc开涛.rar

    PDF,源代码 开涛学SpringMVC 第一章源代码下载 第二章 Spring MVC入门 源代码下载 第四章 Controller接口控制器详解 源代码下载 第五章 处理器拦截器详解——跟着...第七章 注解式控制器的数据验证、类型转换及格式化

    SpringMVC学习文档

    SpringMVC入门、Controller接口详解、注解详解、数据验证、类型转换及格式化等等

    SpringMVC示例

    员工信息、RESTRUL_CRUD_添加操作&表单标签、RESTRUL_CRUD_删除操作&处理静态资源、RESTRUL_CRUD_修改操作、自定义类型转换器、annotation-driven配置、InitBinder注解、数据的格式化、JSR 303数据校验、错误消息的...

    Spring MVC通过添加自定义注解格式化数据的方法

    主要给大家介绍了关于Spring MVC通过添加自定义注解格式化数据的方法,文中先对springmvc 自定义注解 以及自定义注解的解析进行了详细的介绍,相信会对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面...

    SpringMVC Employee Demo

    driven配置、InitBinder注解、数据的格式化、JSR303数据校验、错误消息的显示及国际化、Ajax返回JSON、使用HttpMessageConverter、国际化_通过超链接切换中英文、文件上传、自定义的拦截器、拦截器的零Xml配置、异常...

    SpringMVC大威天龙.docx

    SpringMVC是Spring提供的一个强大而灵活的Web框架 借助于注解 SpringMVC提供了几乎是POJO的开发模式 使得控制器的开发和测试更加简单 二 SpringMVC优点 1. 角色划分清晰 2. 分工明确 而且扩展相当灵活 3. 和Spring...

    spring杂谈 作者zhang KaiTao

    1. spring杂谈[原创] 1.1 Spring事务处理时自我调用的解决方案及一些实现方式的风险 ...1.32 Spring3 Web MVC下的数据类型转换(第一篇)——《跟我学Spring3 Web MVC》抢先看 1.33 Spring 注入集合类型

    Spring、SpringMVC和Mybatis框架整合包

    手把手教你整合最优雅SSM框架:SpringMVC + Spring + MyBatis 博客地址:http://blog.csdn.net/qq598535550/article/details/51703190 我们看招聘信息的时候,经常会看到这一点,需要具备SSH框架的技能;而且在大...

    Spring3_MVC注解教程.ppt

    支持REST风格的URL 添加更多注解,可完全注解驱动 引入HTTP输入输出转换器...和数据转换、格式化、验证框架无缝集成 对静态资源处理提供特殊支持 更加灵活的控制器方法签名,可完全独立于Servlet API

    Spring MVC 3.0实战指南.ppt

    4、数据转换、格式化、校验 5、数据模型控制 6、视图及解析器 7、其它 目录: Spring MVC 3.0新特性 Spring MVC框架结构 Spring MVC框架结构 框架的实现者 目录 HTTP请求映射原理 Spring MVC进行映射的依据 通过URL...

    spring-mvc-learn:spring-mvc学习代码源码-mvc source code

    转换器(转换器)和格式化(Formatter) 转炉 实现转换器接口 在spring-mvc的配置文件中添加bean:org.springframework.context.support.ConversionServiceFactoryBean,注册转换器,添加注释驱动的转换服务属性 ...

    spring mvc 3.2 参考文档

    Spring的视图解析也非常灵活,控制器通常负责准备含有数据的model Map并选择一种视图名称,当然,它也可以直接直接写响应流,并完成该请求。视图名称解析可以根据文件扩展名或者Accept头内容类型协商,通过bean的...

    server-api:SERVER-API 是一个gui的web接口管理工具,基于 swagger-ui 的后台API开源项目,采用SpringMvc+Maven3+Jdk1.7+Tomcat7

    api 是一个GUI的WEB接口管理工具,基于 的后台API开源项目,采用SpringMvc+Maven3+Jdk1.7+Tomcat7,该项目的初衷是为了更好的去发展Swagger-ui与SpringMvc的结合,希望能够更加灵活,轻量化的根据后台不同的数据源...

    report 开源的访问层中间件,基于java平台

    可用于接口的调试及性能的展示,以及访问控制层的使用,简化控制层的繁琐代码,简化spring mvc的配置,剥离的请求前的一系列操作,耦合性低,report是请求通道采用责任链模式设计,轻便可控、扩展性强。report的测试...

    SSM入门到精通项目实战(附源码)

    掌握SpringMVC的项目整合配置,@Controller,@RequestMapping,@Resource,@PathVariable,@ResponseBody,@ModelAttribute,@CookieValue,@Transactional等注解的使用,json数据传值,国际化,拦截器,权限控制,...

    java猜数字源码-eweb4j-framework:简单的Java网络框架

    声明式事务、事务模板、事务嵌套 丰富的DAO封装类 多数据源、表关联 简单的 IOC 容器 MVC、ORM、IOC 可控开关 键值对配置文件支持 国际化支持 让我们看看它是如何做到的。 == 1. 独具特色的 RESTful 路由 == 讨厌 _...

Global site tag (gtag.js) - Google Analytics