《Spring 5 官方文档》18. Web MVC 框架(四)

简介:

使用@ResponseBody注释映射响应体

@ResponseBody注释是类似@RequestBody。该注释可以放在一个方法上,并指示返回类型应该直接写入HTTP响应体(而不是放在模型中,或者解释为视图名称)。例如:

@GetMapping(“/ something”)
@ResponseBody
 public String helloWorld(){
	 return  “Hello World” ; 
}

上述示例将导致文本Hello World被写入HTTP响应流。

与之一样@RequestBody,Spring通过使用一个转换将返回的对象转换为响应体HttpMessageConverter。有关这些转换器的更多信息,请参阅上一部分和消息转换器

使用@RestController注释创建REST控制器

控制器实现REST API是一个非常常见的用例,因此仅提供JSON,XML或定制的MediaType内容。为方便起见,您可以使用以下@RequestMapping方式@ResponseBody来注释您的控制器类,而不是注释所有 方法@RestController

@RestController is a stereotype annotation that combines @ResponseBody and @Controller. More than that, it gives more meaning to your Controller and also may carry additional semantics in future releases of the framework.

与常规@ControllerS,A @RestController可以通过协助 @ControllerAdvice@RestControllerAdvice豆类。有关 更多详细信息,请参阅“使用@ControllerAdvice和@RestControllerAdvice建议控制器”一节。

使用HttpEntity

HttpEntity是相似的@RequestBody@ResponseBody。除了访问请求和响应主体之外HttpEntity(和响应特定子类ResponseEntity)还允许访问请求和响应头,如下所示:

@RequestMapping(“/ something”)
 public ResponseEntity <String> handle(HttpEntity < byte []> requestEntity) throws UnsupportedEncodingException {
	String requestHeader = requestEntity.getHeaders()。getFirst( “MyRequestHeader”);
	byte [] requestBody = requestEntity.getBody(); //使用请求头和身体 
	做某事HttpHeaders responseHeaders = new HttpHeaders(); 
	responseHeaders.set( “MyResponseHeader” “MyValue”);
	返回新的 ResponseEntity <String>( “Hello World”,responseHeaders,HttpStatus。创建); 
}

	

上述示例获取MyRequestHeader请求标头的值,并将其作为字节数组读取。它将MyResponseHeader响应添加到Hello World响应流中,并将响应状态代码设置为201(已创建)。

至于@RequestBody@ResponseBody,Spring使用HttpMessageConverter从和请求和响应流转换。有关这些转换器的更多信息,请参阅上一部分和消息转换器

在方法上使用@ModelAttribute

@ModelAttribute注释可以对方法或方法的参数来使用。本节将介绍其在方法上的用法,下一节将介绍其在方法参数上的用法。

An @ModelAttribute on a method indicates the purpose of that method is to add one or more model attributes. Such methods support the same argument types as @RequestMapping methods but cannot be mapped directly to requests. Instead @ModelAttribute methods in a controller are invoked before @RequestMappingmethods, within the same controller. A couple of examples:

//添加一个属性
//该方法的返回值被添加到名为“account”的模型中
//您可以通过@ModelAttribute(“myAccount”)

@ModelAttribute
自定义名称@ModelAttribute public Account addAccount(@RequestParam String number) {
	 return accountManager.findAccount(number); 
} //添加多个属性@ModelAttribute public void populateModel(@RequestParam String number,Model model){ 
	model.addAttribute(accountManager.findAccount(number)); //添加更多... 
}




 

@ModelAttribute方法用于填充具有常用属性的模型,例如使用状态或宠物类型填充下拉列表,或者检索诸如Account的命令对象,以便使用它来表示HTML表单上的数据。后一种情况在下一节进一步讨论。

注意两种风格的@ModelAttribute方法。在第一个方法中,该方法通过返回它隐式地添加一个属性。在第二个方法中,该方法接受Model并添加任意数量的模型属性。您可以根据需要选择两种风格。

控制器可以有多种@ModelAttribute方法。所有这些方法都@RequestMapping在相同控制器的方法之前被调用。

@ModelAttribute方法也可以在一个@ControllerAdvice注释类中定义,并且这种方法适用于许多控制器。有关更多详细信息,请参阅“使用@ControllerAdvice和@RestControllerAdvice建议控制器”一节。

[Tip]
当没有明确指定模型属性名称时会发生什么?在这种情况下,根据其类型将默认名称分配给模型属性。例如,如果该方法返回类型的对象Account,则使用的默认名称为“account”。您可以通过@ModelAttribute注释的值更改它。如果直接添加属性Model,请使用适当的重载addAttribute(..)方法 – 即,带有或不带有属性名称。

@ModelAttribute批注可在使用@RequestMapping方法为好。在这种情况下,@RequestMapping方法的返回值将被解释为模型属性而不是视图名称。视图名称是基于视图名称约定导出的,非常类似于返回的方法void - 请参见第18.13.3节“View – RequestToViewNameTranslator”

在方法参数上使用@ModelAttribute

如上一节所述@ModelAttribute,可以在方法或方法参数上使用。本节介绍了其在方法参数中的用法。

一个@ModelAttribute上的方法参数指示参数应该从模型中检索。如果模型中不存在,参数首先被实例化,然后添加到模型中。一旦出现在模型中,参数的字段应该从具有匹配名称的所有请求参数中填充。这被称为Spring MVC中的数据绑定,这是一种非常有用的机制,可以节省您逐个解析每个表单字段。

@PostMapping(“/ owners / {ownerId} / pets / {petId} / edit”)
 public String processSubmit( @ModelAttribute Pet pet){}

鉴于上述例子,宠物实例可以从哪里来?有几个选择:

一种@ModelAttribute方法是从数据库中检索属性的常用方法,可以通过使用可选地在请求之间存储属性 @SessionAttributes。在某些情况下,通过使用URI模板变量和类型转换器来检索属性可能很方便。这是一个例子:

@PutMapping(“/ accounts / {account}”)
 public String save( @ModelAttribute(“account”)帐户帐号){
	 // ... 
}

在此示例中,模型属性(即“account”)的名称与URI模板变量的名称相匹配。如果您注册Converter<String, Account>,可以将 String帐户值转换为一个Account实例,则上述示例将无需使用@ModelAttribute方法。

下一步是数据绑定。该WebDataBinder级比赛要求参数名称-包括查询字符串参数和表单域-以模拟通过名称属性字段。在必要时已经应用了类型转换(从字符串到目标字段类型)之后填充匹配字段。数据绑定和验证在 第5章验证,数据绑定和类型转换中介绍。自定义控制器级别的数据绑定过程将在“自定义WebDataBinder初始化”一节中介绍

由于数据绑定,可能会出现错误,例如缺少必填字段或类型转换错误。要检查这些错误,请在BindingResult参数后立即添加一个@ModelAttribute参数:

@PostMapping(“/ owners / {ownerId} / pets / {petId} / edit”)
 public String processSubmit( @ModelAttribute(“pet”)Pet Pet,BindingResult result){ if(result.hasErrors()){
		 return “petForm “ ; 
	} // ... 
}

	 

	

使用一个BindingResult你可以检查是否发现错误,在这种情况下,渲染相同的形式通常是在Spring的<errors> 表单标签的帮助下显示错误的。

请注意,在某些情况下,在没有数据绑定的情况下获取模型中的属性可能是有用的。对于这种情况,您可以将其注入Model控制器,或者使用注释上的binding标志:

@ModelAttribute
 public AccountForm setUpForm(){
     return  new AccountForm(); 
} @ModelAttribute public Account findAccount( @PathVariable String accountId){
     return accountRepository.findOne(accountId); 
} @PostMapping(“update”) public String update( @Valid AccountUpdateForm form,BindingResult result,
         @ModelAttribute(binding = false) Account account){ // ... 
}







除了数据绑定之外,您还可以使用自己的自定义验证器调用验证,传递与BindingResult用于记录数据绑定错误相同的验证器。这允许在一个地方累积数据绑定和验证错误,并随后向用户报告:

@PostMapping( “/老板/ {} OWNERID /宠物/ {} petId /编辑”)
公共字符串processSubmit( PetValidator()验证(PET,结果);
	如果(result.hasErrors()){
		回报“petForm” ;
	} // ... 
}@ModelAttribute("pet") Pet pet, BindingResult result) {

	 

	

或者您可以通过添加JSR-303 @Valid 注释自动调用验证:

@PostMapping(“/ owners / {ownerId} / pets / {petId} / edit”)
 public String processSubmit( @Valid @ModelAttribute(“pet”)Pet pet,BindingResult result){ if(result.hasErrors()){
		 return “petForm” ; 
	} // ... 
}

	 

	

有关如何配置和使用验证的详细信息,请参见第5.8节“Spring验证”第5章验证,数据绑定和类型转换。

使用@SessionAttributes将模型属性存储在请求之间的HTTP会话中

类型级@SessionAttributes注释声明特定处理程序使用的会话属性。这通常将列出模型属性或模型属性的类型,这些模型属性或类型应该透明地存储在会话或某些会话存储中,作为后续请求之间的格式支持bean。

以下代码片段显示了此注释的用法,指定了模型属性名称:

@Controller 
@RequestMapping(“/ editPet.do”)
@SessionAttributes(“pet”)
 public class EditPetForm {
	// ...
}

使用@SessionAttribute访问预先存在的全局会话属性

如果您需要访问全局管理的预先存在的会话属性,即控制器外部(例如,通过过滤器),并且可能存在或可能不存在,@SessionAttribute则会使用方法参数上的注释:

@RequestMapping(“/”)
 public String handle( @SessionAttribute User user){
	 // ... 
}

对于需要添加或删除会话属性的用例,请考虑注入 org.springframework.web.context.request.WebRequest或 javax.servlet.http.HttpSession控制方法。

为了在会话中临时存储模型属性作为控制器工作流的一部分,请考虑使用“使用@SessionAttributes将模型属性存储在请求之间的HTTP会话中”SessionAttributes中 所述的一节

使用@RequestAttribute来访问请求属性

到类似@SessionAttribute@RequestAttribute注释可以被用于访问由滤波器或拦截器创建的预先存在的请求属性:

@RequestMapping(“/”)
 public String handle( @RequestAttribute Client client){
	 // ... 
}

使用“application / x-www-form-urlencoded”数据

以前的章节介绍了@ModelAttribute如何支持浏览器客户端的表单提交请求。建议与非浏览器客户端的请求一起使用相同的注释。然而,在使用HTTP PUT请求时,有一个显着的区别。浏览器可以通过HTTP GET或HTTP POST提交表单数据。非浏览器客户端也可以通过HTTP PUT提交表单。这提出了一个挑战,因为Servlet规范要求ServletRequest.getParameter*()一系列方法仅支持HTTP POST的表单域访问,而不支持HTTP PUT。

为了支持HTTP PUT和PATCH请求,该spring-web模块提供了HttpPutFormContentFilter可以在以下配置中的过滤器 web.xml

<filter> 
	<filter-name> httpPutFormFilter </ filter-name> 
	<filter-class> org.springframework.web.filter.HttpPutFormContentFilter </ filter-class> 
</ filter> 

<filter-mapping> 
	<filter-name> httpPutFormFilter </ filter-name> 
	<servlet-name> dispatcherServlet </ servlet-name> 
</ filter-mapping> 

<servlet> 
	<servlet-name> dispatcherServlet </ servlet-name> 
	<servlet-class> org.springframework.web。 servlet.DispatcherServlet </ servlet-class> 
</ servlet>

上述过滤器拦截具有内容类型的HTTP PUT和PATCH请求application/x-www-form-urlencoded,从请求的正文 中读取表单数据,并包装ServletRequest以便通过ServletRequest.getParameter*()一系列方法使表单数据可用 。

[Note]
由于HttpPutFormContentFilter消耗了请求的正文,因此不应配置为依赖其他转换器的PUT或PATCH URL application/x-www-form-urlencoded。这包括@RequestBody MultiValueMap<String, String>HttpEntity<MultiValueMap<String, String>>

使用@CookieValue注释映射Cookie值

@CookieValue注释允许将方法参数绑定到HTTP cookie的值。

让我们考虑以下cookie已被接收到http请求:

JSESSIONID = 415A4AC178C59DACE0B2C9CA727CDD84

以下代码示例演示如何获取JSESSIONIDcookie 的值:

@RequestMapping(“/ displayHeaderInfo.do”)
 public  void displayHeaderInfo( @CookieValue(“JSESSIONID”) String cookie){
	 // ... 
}

如果目标方法参数类型不是,则会自动应用类型转换 String。请参阅“方法参数和类型转换”一节

使用@RequestHeader注释映射请求标头属性

@RequestHeader注释允许将一个方法参数绑定到请求头。

以下是一个示例请求标头:

主机本地主机:8080 
接受文本/ html应用程序/ xhtml + xml应用程序/ xml; q = 0.9 
接受语言fr,en-gb; q = 0.7,en; q = 0.3 
接受编码gzip,放大
Accept-Charset ISO -8859-1,utf-8; q = 0.7,*; q = 0.7 
保持活力300

以下代码示例演示了如何获取Accept-Encoding和 Keep-Alive标题的值:

@RequestMapping(“/ displayHeaderInfo.do”)
 public  void displayHeaderInfo( @RequestHeader(“Accept-Encoding”) String encoding,
		 @RequestHeader(“Keep-Alive”)  long keepAlive){
	 // ... 
}

Type conversion is applied automatically if the method parameter is not String. See the section called “Method Parameters And Type Conversion”.

@RequestHeader注解上的使用Map<String, String>, MultiValueMap<String, String>HttpHeaders参数,则地图被填充有所有标头值。

[Tip]
内置支持可用于将逗号分隔的字符串转换为字符串或类型转换系统已知的其他类型的数组/集合。例如,注释的方法参数@RequestHeader("Accept")可以是类型String,也可以是 String[]List<String>

方法参数和类型转换

从请求中提取的基于字符串的值(包括请求参数,路径变量,请求标头和cookie值)可能需要转换为方法参数或字段的目标类型(例如,将请求参数绑定到参数中的字段@ModelAttribute)他们一定会。如果目标类型不是String,Spring将自动转换为相应的类型。支持所有简单的类型,如int,long,Date等。您可以进一步自定义通过转换过程WebDataBinder(见称为“定制WebDataBinder初始化”一节),或者通过注册FormattersFormattingConversionService(参见5.6节,“春字段格式”)。

相关文章
|
1月前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
2月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
48 4
|
2月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
162 1
|
2月前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
38 0
|
2月前
|
前端开发 Java 数据库连接
Spring 框架:Java 开发者的春天
Spring 框架是一个功能强大的开源框架,主要用于简化 Java 企业级应用的开发,由被称为“Spring 之父”的 Rod Johnson 于 2002 年提出并创立,并由Pivotal团队维护。
58 1
Spring 框架:Java 开发者的春天
|
29天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
53 2
|
2月前
|
人工智能 Java API
阿里云开源 AI 应用开发框架:Spring AI Alibaba
近期,阿里云重磅发布了首款面向 Java 开发者的开源 AI 应用开发框架:Spring AI Alibaba(项目 Github 仓库地址:alibaba/spring-ai-alibaba),Spring AI Alibaba 项目基于 Spring AI 构建,是阿里云通义系列模型及服务在 Java AI 应用开发领域的最佳实践,提供高层次的 AI API 抽象与云原生基础设施集成方案,帮助开发者快速构建 AI 应用。本文将详细介绍 Spring AI Alibaba 的核心特性,并通过「智能机票助手」的示例直观的展示 Spring AI Alibaba 开发 AI 应用的便利性。示例源
|
28天前
|
消息中间件 NoSQL Java
springboot整合常用中间件框架案例
该项目是Spring Boot集成整合案例,涵盖多种中间件的使用示例,每个案例项目使用最小依赖,便于直接应用到自己的项目中。包括MyBatis、Redis、MongoDB、MQ、ES等的整合示例。
85 1
|
2月前
|
人工智能 开发框架 Java
总计 30 万奖金,Spring AI Alibaba 应用框架挑战赛开赛
Spring AI Alibaba 应用框架挑战赛邀请广大开发者参与开源项目的共建,助力项目快速发展,掌握 AI 应用开发模式。大赛分为《支持 Spring AI Alibaba 应用可视化调试与追踪本地工具》和《基于 Flow 的 AI 编排机制设计与实现》两个赛道,总计 30 万奖金。
|
2月前
|
Java 数据库连接 开发者
Spring 框架:Java 开发者的春天
【10月更文挑战第27天】Spring 框架由 Rod Johnson 在 2002 年创建,旨在解决 Java 企业级开发中的复杂性问题。它通过控制反转(IOC)和面向切面的编程(AOP)等核心机制,提供了轻量级的容器和丰富的功能,支持 Web 开发、数据访问等领域,显著提高了开发效率和应用的可维护性。Spring 拥有强大的社区支持和丰富的生态系统,是 Java 开发不可或缺的工具。