使用@RestController注解创建REST的控制器
使用一个实现了REST API的Controller(控制器)是很普遍的事,这样,控制器就只为JSON,XML,或者任意MediaType内容服务。你可以使用@RestController注解方便的在一个controller类上面注解,这样,就不用在每一个@RequestMapping方法底下写上@ResponseBody了。
@RestController是结合了@ResponseBody和@Controller的构造型注解,此外,它可能将在Spring框架以后的版本中被赋予更多的含义。
使用HttpEntity
HttpEntity很像@RequestBody和@ResponseBody,除了可以访问请求和响应的主体,HttpEntity(和特定响应的下属类ResponseEntity)也允许访问请求和响应的报头,如下所示:
在上面的例子中,获取了”MyRequestHeader”的请求报头,并读取其主体作为一个字节数组(byte[])。然后在响应中添加了”MyResponseHeader”,在响应数据流中写入了”Hello World”,最后把响应状态代码设置为201(Created)。
在使用@RequestBody和@ResponseBody时,Spring使用HttpMessageConverter来把请求和响应数据流互相转换。详见”消息转换器”这一章节。
在方法上使用@ModelAttribute
@ModelAttribute注解能在方法上,或者方法入参中使用,本章节解释在方法上的使用方法,下一章节会解释在方法入参中的使用方法。
在方法上使用@ModelAttribute代表了这个方法要添加一个或多个model(模型)attribute(属性),这种方法与@RequestMapping注解的方法支持同样的入参类型。但是,它不能直接映射请求,取而代之的是,在同一个controller中的@ModelAttribute方法能在@RequestMapping方法之前进行调用,下面是两个例子:
@ModelAttribute方法是用来把需要普遍使用的attribute添加进model的。举个例子,在一个下拉菜单中填充进宠物类型或者(美国各)州名,或者检索一个指令对象,并在HTML表单中展示(比如检索账号信息并在HTML表单中的展示)。后面这种情况将在下一章节详解。
请注意这两种不同风格的@ModelAttribute方法。在第一个例子中,这个方法在返回值中隐式地添加了attribute。第二个例子中,这个方法接受了一个Model,并添加任意数量的model attribute,这两种使用方式,你可以按需选择。
一个controller可以有任意个@ModelAttribute方法,在同一个controller中,这些方法会在@RequestMapping方法之前被调用。
@ModelAttribute方法同样能在@ControllerAdvice注解的类中使用,也可以在其他controller中使用。详见”使用@ControllerAdvice做advice(通知)”这一章节。
小提示:
当model attribute(模型属性)名没有显式指定时,会发生什么事?在这种情况下,默认会基于它的类型来决定模型属性名。比如:如果有个方法,返回了一个Account类型的对象,默认的model attribute名就是“account”。你可以利用@ModelAttribute注解中的值来改变名字。如果直接在Model对象中添加attribute,可以适当地使用重载的addAttribute(..)方法。
@ModelAttribute注解同样也能在@RequestMapping方法上使用,这种情况下,@RequestMapping方法的返回值会被当作model attribute,而不是视图名。视图名就跟返回void时一样。详见”The View - RequestToViewNameTransLator”。
在方法入参中使用@ModelAttribute
在上一章节中说过@ModelAttribute能在方法上,或者方法入参中使用,本章将阐述在方法入参中的使用方法。
在方法入参中的@ModelAttribute,表示这个参数会从model中被检索,如果在model的检索中没有这个attribute,这个参数将会先实例化,再添加到model中。一旦在model中有了attribute,跟这个attribute名字匹配的所有请求参数中,都会有这个参数的值。这就是Spring MVC中的数据绑定,这个特性很有用,可以避免每次都需要在不同的字段中去添加参数。
上面的例子中,Pet这个实例从何而来?有几个可能:
在上面的例子中,model attribute(模型属性)的名字匹配到了URI模板中的变量名,如果你注册了一个能够把String类型的account值转换成Account实例的Converter<String, Account>,那么,上面的例子中,不使用@ModelAttribute方法也能运行。
下一步是数据绑定,WebDataBinder类会匹配请求的参数名——包括处理字符串参数和表单字段,转换成以名字区分的模型属性。当必要时,会在类型转换后(从String类型转到目标字段类型),把匹配的字段加到模型属性中。数据绑定和验证在第8章”验证,数据绑定,和类型转换”阐述。在controller级别自定义数据绑定处理在”自定义WebDataBinder初始化”这一章节中阐述。
在数据绑定中,有可能会出现各种错误,比如:必要字段缺失,或者转换错误等等。如果要检查这些错误,可以在@ModelAttribute入参后面添加BindingResult入参。
运用BindingResult,你能够在需要经常渲染同一个表单的情况下,检查是否有数据绑定错误,这些错误将被Spring的<errors>表单标签展示出来。
除了数据绑定之外,你也能在BindingResult中,用你自定义的验证器去调用验证操作,这样,在同一个地方就可以完成验证错误和数据绑定,之后把结果返回给用户:
或者,你能添加一个JSR-303的@Valid注解来自动调用验证操作:
可参考8.8,”Spring 验证”和第8章”验证、数据绑定、和类型转换”,来了解怎么样配置和使用验证。
使用一个实现了REST API的Controller(控制器)是很普遍的事,这样,控制器就只为JSON,XML,或者任意MediaType内容服务。你可以使用@RestController注解方便的在一个controller类上面注解,这样,就不用在每一个@RequestMapping方法底下写上@ResponseBody了。
@RestController是结合了@ResponseBody和@Controller的构造型注解,此外,它可能将在Spring框架以后的版本中被赋予更多的含义。
使用HttpEntity
HttpEntity很像@RequestBody和@ResponseBody,除了可以访问请求和响应的主体,HttpEntity(和特定响应的下属类ResponseEntity)也允许访问请求和响应的报头,如下所示:
在上面的例子中,获取了”MyRequestHeader”的请求报头,并读取其主体作为一个字节数组(byte[])。然后在响应中添加了”MyResponseHeader”,在响应数据流中写入了”Hello World”,最后把响应状态代码设置为201(Created)。
在使用@RequestBody和@ResponseBody时,Spring使用HttpMessageConverter来把请求和响应数据流互相转换。详见”消息转换器”这一章节。
在方法上使用@ModelAttribute
@ModelAttribute注解能在方法上,或者方法入参中使用,本章节解释在方法上的使用方法,下一章节会解释在方法入参中的使用方法。
在方法上使用@ModelAttribute代表了这个方法要添加一个或多个model(模型)attribute(属性),这种方法与@RequestMapping注解的方法支持同样的入参类型。但是,它不能直接映射请求,取而代之的是,在同一个controller中的@ModelAttribute方法能在@RequestMapping方法之前进行调用,下面是两个例子:
@ModelAttribute方法是用来把需要普遍使用的attribute添加进model的。举个例子,在一个下拉菜单中填充进宠物类型或者(美国各)州名,或者检索一个指令对象,并在HTML表单中展示(比如检索账号信息并在HTML表单中的展示)。后面这种情况将在下一章节详解。
请注意这两种不同风格的@ModelAttribute方法。在第一个例子中,这个方法在返回值中隐式地添加了attribute。第二个例子中,这个方法接受了一个Model,并添加任意数量的model attribute,这两种使用方式,你可以按需选择。
一个controller可以有任意个@ModelAttribute方法,在同一个controller中,这些方法会在@RequestMapping方法之前被调用。
@ModelAttribute方法同样能在@ControllerAdvice注解的类中使用,也可以在其他controller中使用。详见”使用@ControllerAdvice做advice(通知)”这一章节。
小提示:
当model attribute(模型属性)名没有显式指定时,会发生什么事?在这种情况下,默认会基于它的类型来决定模型属性名。比如:如果有个方法,返回了一个Account类型的对象,默认的model attribute名就是“account”。你可以利用@ModelAttribute注解中的值来改变名字。如果直接在Model对象中添加attribute,可以适当地使用重载的addAttribute(..)方法。
@ModelAttribute注解同样也能在@RequestMapping方法上使用,这种情况下,@RequestMapping方法的返回值会被当作model attribute,而不是视图名。视图名就跟返回void时一样。详见”The View - RequestToViewNameTransLator”。
在方法入参中使用@ModelAttribute
在上一章节中说过@ModelAttribute能在方法上,或者方法入参中使用,本章将阐述在方法入参中的使用方法。
在方法入参中的@ModelAttribute,表示这个参数会从model中被检索,如果在model的检索中没有这个attribute,这个参数将会先实例化,再添加到model中。一旦在model中有了attribute,跟这个attribute名字匹配的所有请求参数中,都会有这个参数的值。这就是Spring MVC中的数据绑定,这个特性很有用,可以避免每次都需要在不同的字段中去添加参数。
上面的例子中,Pet这个实例从何而来?有几个可能:
- 有可能已经使用了@SessionAttributes,所以model里已经有这个实例了——详见”使用@SessionAttributes在request间的HTTP session储存model attribute”章节。
- 有可能已经在同一个controller中使用了@ModelAttribute方法,所以model里已经有这个实例了——就如上一章节阐述的那样。
- 有可能已经通过URI模板变量和类型转换器检索到了。(将在下面的章节详述)
- 有可能通过它的默认的构造器实例化了。
在上面的例子中,model attribute(模型属性)的名字匹配到了URI模板中的变量名,如果你注册了一个能够把String类型的account值转换成Account实例的Converter<String, Account>,那么,上面的例子中,不使用@ModelAttribute方法也能运行。
下一步是数据绑定,WebDataBinder类会匹配请求的参数名——包括处理字符串参数和表单字段,转换成以名字区分的模型属性。当必要时,会在类型转换后(从String类型转到目标字段类型),把匹配的字段加到模型属性中。数据绑定和验证在第8章”验证,数据绑定,和类型转换”阐述。在controller级别自定义数据绑定处理在”自定义WebDataBinder初始化”这一章节中阐述。
在数据绑定中,有可能会出现各种错误,比如:必要字段缺失,或者转换错误等等。如果要检查这些错误,可以在@ModelAttribute入参后面添加BindingResult入参。
运用BindingResult,你能够在需要经常渲染同一个表单的情况下,检查是否有数据绑定错误,这些错误将被Spring的<errors>表单标签展示出来。
除了数据绑定之外,你也能在BindingResult中,用你自定义的验证器去调用验证操作,这样,在同一个地方就可以完成验证错误和数据绑定,之后把结果返回给用户:
或者,你能添加一个JSR-303的@Valid注解来自动调用验证操作:
可参考8.8,”Spring 验证”和第8章”验证、数据绑定、和类型转换”,来了解怎么样配置和使用验证。