Consumable Media 类型
您可以通过指定consumable media类型的列表来缩小主要映射。 只有当Content-Type请求头与指定的媒体类型匹配时,才会匹配该请求。 例如:
@PostMapping(path = "/pets", consumes = "application/json") public void addPet(@RequestBody Pet pet, Model model) { // implementation omitted } consumable media类型表达式也可以在!text / plain中否定,以匹配除Content-Type of text / plain之外的所有请求。 还要考虑使用MediaType中提供的常量,例如APPLICATION_JSON_VALUE和APPLICATION_JSON_UTF8_VALUE。
Producible Media 类型
您可以通过指定producible media类型列表来缩小主要映射。 只有当Accept请求头匹配这些值之一时,才会匹配该请求。 此外,使用产生条件确保用于产生响应的实际内容类型与产生条件中指定的媒体类型相关。 例如:
@GetMapping(path = "/pets/{petId}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) @ResponseBody public Pet getPet(@PathVariable String petId, Model model) { // implementation omitted } 就像消费一样,可生产的媒体类型表达式可以被否定为!text / plain,以匹配除了接受头文件值为text / plain的所有请求。 还要考虑使用MediaType中提供的常量,例如APPLICATION_JSON_VALUE和APPLICATION_JSON_UTF8_VALUE。
请求参数和头部值
您可以通过请求参数条件(如“myParam”,“!myParam”或“myParam = myValue”)缩小请求匹配。 前两个测试请求参数存在/不存在,第三个为特定参数值。 下面是一个请求参数值条件的例子:
@Controller @RequestMapping("/owners/{ownerId}") public class RelativePathUriTemplateController { @GetMapping(path = "/pets/{petId}", params = "myParam=myValue") public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) { // implementation omitted } }
也可以根据特定的请求头值来测试请求头存在/不存在或匹配:
@Controller @RequestMapping("/owners/{ownerId}") public class RelativePathUriTemplateController { @GetMapping(path = "/pets", headers = "myHeader=myValue") public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) { // implementation omitted } }
HTTP 头部和 HTTP 可选项
映射到“GET”的@RequestMapping方法也隐式映射到“HEAD”,即不需要明确声明“HEAD”。处理HTTP HEAD请求就像是HTTP GET一样,而不是仅写入正文,仅计数字节数,并设置“Content-Length”头。
@RequestMapping方法内置支持HTTP选项。默认情况下,通过将所有@RequestMapping方法上显式声明的具有匹配URL模式的HTTP方法设置为“允许”响应头来处理HTTP OPTIONS请求。当没有明确声明HTTP方法时,“允许”标题设置为“GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS”。理想地总是声明@RequestMapping方法要处理的HTTP方法,或者使用专用的组合@RequestMapping变体之一(参见“Composed @RequestMapping Variants”一节)。
虽然不需要@RequestMapping方法可以映射到HTTP HEAD或HTTP选项,也可以两者兼容。
18.3.3 定义@RequestMapping 处理方法
@RequestMapping处理方法可以有非常灵活的签名。 支持的方法参数和返回值将在以下部分中介绍。 大多数参数可以按任意顺序使用,唯一的例外是BindingResult参数。 这将在下一节中介绍。
支持的方法参数类型
下面是支持的方法参数类型:
-
org.springframework.web.context.request.WebRequest
ororg.springframework.web.context.request.NativeWebRequest
. 允许通用请求参数访问以及请求/会话属性访问,而不涉及本机Servlet API。 - Request or response objects (Servlet API). 选择任意特定的请求或响应类型, for example
ServletRequest
orHttpServletRequest
or Spring’sMultipartRequest
/MultipartHttpServletRequest
. - Session对象(Servlet API)类型为HttpSession。 此类型的参数强制存在相应的会话。 因此,这样的论证从不为空。
会话访问可能不是线程安全的,特别是在Servlet环境中。 如果允许多个请求同时访问会话,请考虑将RequestMappingHandlerAdapter的“synchronizeOnSession”标志设置为“true”。
- java.servlet.http.PushBuilder用于关联的Servlet 4.0推送构建器API,允许编程的HTTP / 2资源推送。
- java.security.Principal(或一个特定的Principal实现类(如果已知)),包含当前验证的用户。
- org.springframework.http.HttpMethod为HTTP请求方法,表示为Spring的HttpMethod枚举。
- 由当前请求区域设置的java.util.Locale,由最具体的语言环境解析器确定,实际上是在MVC环境中配置的LocaleResolver / LocaleContextResolver。
- 与当前请求相关联的时区的java.util.TimeZone(Java 6+)/ java.time.ZoneId(Java 8+),由LocaleContextResolver确定。
- java.io.InputStream / java.io.Reader,用于访问请求的内容。该值是由Servlet API公开的原始InputStream / Reader。
- java.io.OutputStream / java.io.Writer用于生成响应的内容。该值是由Servlet API公开的原始OutputStream / Writer。
- @PathVariable注释参数,用于访问URI模板变量。请参阅the section called “URI Template Patterns”.
- @MatrixVariable注释参数,用于访问位于URI路径段中的名称/值对。请参阅 the section called “Matrix Variables”.
- @RequestParam用于访问特定Servlet请求参数的注释参数。参数值将转换为声明的方法参数类型。请参阅 the section called “Binding request parameters to method parameters with @RequestParam”.
- @RequestHeader用于访问特定Servlet请求HTTP标头的注释参数。参数值将转换为声明的方法参数类型。请参阅 the section called “Mapping request header attributes with the @RequestHeader annotation”.
- @RequestBody用于访问HTTP请求体的注释参数。使用HttpMessageConverters将参数值转换为声明的方法参数类型。请参阅the section called “Mapping the request body with the @RequestBody annotation”.
- @RequestPart注释参数,用于访问“multipart / form-data”请求部分的内容。请参见Section 18.10.5, “Handling a file upload request from programmatic clients” 和Section 18.10, “Spring’s multipart (file upload) support”.
- @SessionAttribute用于访问现有的永久会话属性(例如,用户认证对象)的注释参数,而不是通过@SessionAttributes作为控制器工作流的一部分临时存储在会话中的模型属性。
- @RequestAttribute用于访问请求属性的注释参数。
- HttpEntity <?>参数访问Servlet请求HTTP头和内容。请求流将使用HttpMessageConverters转换为实体。请参阅 the section called “Using HttpEntity”.
- java.util.Map / org.springframework.ui.Model / org.springframework.ui.ModelMap用于丰富暴露于Web视图的隐式模型。
- org.springframework.web.servlet.mvc.support.RedirectAttributes来指定在重定向情况下使用的精确的属性集,并且还添加Flash属性(临时存储在服务器端的属性,使其可以在请求之后使用重定向)。请参见 the section called “Passing Data To the Redirect Target” 和Section 18.6, “Using flash attributes”.
- 根据@InitBinder方法和/或HandlerAdapter配置,命令或表单对象将请求参数绑定到bean属性(通过setter)或直接转换为字段,并进行可定制的类型转换。请参阅RequestMappingHandlerAdapter上的webBindingInitializer属性。默认情况下,这些命令对象及其验证结果将作为模型属性公开,使用命令类名称 – 例如。对于“some.package.OrderAddress”类型的命令对象的model属性“orderAddress”。 ModelAttribute注释可以用于方法参数来自定义所使用的模型属性名称。
- org.springframework.validation.Errors / org.springframework.validation.BindingResult验证前一个命令或表单对象的结果(即在前面的方法参数)。
- 用于将表单处理标记为完整的org.springframework.web.bind.support.SessionStatus状态句柄,它触发在处理程序类型级别上由@SessionAttributes注释指示的会话属性的清除。
- org.springframework.web.util.UriComponentsBuilder用于准备与当前请求的主机,端口,方案,上下文路径以及servlet映射的文字部分相关的URL的构建器。
错误或BindingResult参数必须遵循正在绑定的模型对象,因为方法签名可能有多个模型对象,Spring将为每个模型对象创建一个单独的BindingResult实例,因此以下示例将不起作用:
BindingResult和@ModelAttribute的排序无效。
@PostMapping public String processSubmit(@ModelAttribute("pet") Pet pet, Model model, BindingResult result) { ... } 注意,Pet和BindingResult之间有一个Model参数。 要使其工作,您必须重新排序参数如下:
@PostMapping public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result, Model model) { ... }
支持的方法返回类型
以下是支持的返回类型:
- 一个ModelAndView对象,其中模型隐含地丰富了命令对象和@ModelAttribute注释引用数据访问器方法的结果。
- 一个Model对象,其视图名称通过RequestToViewNameTranslator隐式确定,隐式丰富了命令对象的模型以及@ModelAttribute注释引用数据访问器方法的结果。
- 用于暴露模型的Map对象,其视图名称通过RequestToViewNameTranslator隐式确定,隐式丰富了命令对象的模型以及@ModelAttribute注释引用数据访问器方法的结果。
- 一个View对象,其模型通过命令对象和@ModelAttribute注释引用数据访问器方法隐式确定。处理程序方法也可以通过声明一个Model参数(见上文)以编程方式丰富模型。
- 解释为逻辑视图名称的字符串值,模型通过命令对象和@ModelAttribute注释引用数据访问器方法隐式确定。处理程序方法也可以通过声明一个Model参数(见上文)以编程方式丰富模型。
- 如果方法处理响应本身(通过直接写入响应内容,为此目的声明一个类型为ServletResponse / HttpServletResponse的参数),或者如果视图名称通过RequestToViewNameTranslator隐式确定(不在处理程序方法签名)。
- 如果该方法用@ResponseBody注释,则返回类型将写入响应HTTP主体。返回值将使用HttpMessageConverters转换为声明的方法参数类型。请参阅 the section called “Mapping the response body with the @ResponseBody annotation”.
- 一个HttpEntity <?>或ResponseEntity <?>对象来提供对Servlet响应HTTP头和内容的访问。实体将使用HttpMessageConverters转换为响应流。请参阅 the section called “Using HttpEntity”.
- 一个HttpHeaders对象返回没有正文的响应。
- 当应用程序想要在由Spring MVC管理的线程中异步生成返回值时,可以返回Callable <?>。
- 当应用程序想从自己选择的线程生成返回值时,可以返回DeferredResult <?>
- 当应用程序想要从线程池提交中产生值时,可以返回ListenableFuture <?>或CompletableFuture <?> / CompletionStage <?>。
- 可以返回ResponseBodyEmitter以异步地将多个对象写入响应;也支持作为ResponseEntity内的主体。
- 可以返回SseEmitter以将异步的Server-Sent事件写入响应;也支持作为ResponseEntity内的主体。
- 可以返回StreamingResponseBody以异步写入响应OutputStream;也支持作为ResponseEntity内的主体
- 任何其他返回类型都被认为是要暴露给视图的单一模型属性,使用在方法级别(或基于返回类型类名称的默认属性名称)中通过@ModelAttribute指定的属性名称。该模型隐含地丰富了命令对象和@ModelAttribute注释引用数据访问器方法的结果。
使用@RequestParam注解将请求参数绑定到控制器中的方法参数。 以下代码片段显示用法:
@Controller @RequestMapping("/pets") @SessionAttributes("pet") public class EditPetForm { // ... @GetMapping public String setupForm(@RequestParam("petId") int petId, ModelMap model) { Pet pet = this.clinic.loadPet(petId); model.addAttribute("pet", pet); return "petForm"; } // ... }
默认情况下,使用此注释的参数是必需的,但您可以通过将@ RequestParam的必需属性设置为false(例如@RequestParam(name =“id”,required = false))来指定参数是可选的。 如果目标方法参数类型不是String,则会自动应用类型转换。 请参阅“方法参数和类型转换”一节。 当在Map <String,String>或MultiValueMap <String,String>参数上使用@RequestParam注释时,映射将填充所有请求参数。
使用@RequestBody注释映射请求体
@RequestBody方法参数注释表示方法参数应绑定到HTTP请求体的值。 例如:
@PutMapping("/something") public void handle(@RequestBody String body, Writer writer) throws IOException { writer.write(body); } 通过使用HttpMessageConverter将请求体转换为method参数。 HttpMessageConverter负责将HTTP请求消息转换为对象,并从对象转换为HTTP响应体。 RequestMappingHandlerAdapter支持带有以下默认HttpMessageConverters的@RequestBody注释:
-
byteArrayHttpMessageConverter
converts byte arrays. -
StringHttpMessageConverter
converts strings. -
FormHttpMessageConverter
converts form data to/from a MultiValueMap<String, String>. -
SourceHttpMessageConverter
converts to/from a javax.xml.transform.Source.
有关这些转换器的更多信息,请参阅消息转换器。 另请注意,如果使用MVC命名空间或MVC Java配置,默认情况下会注册更广泛的消息转换器。 有关详细信息,请参见第18.16.1节“启用MVC Java配置或MVC XML命名空间”。 Section 18.16.1, “Enabling the MVC Java Config or the MVC XML Namespace” 如果您打算读写XML,则需要使用org.springframework.oxm包中的特定Marshaller和Unmarshaller实现配置MarshallingHttpMessageConverter。 下面的示例显示了如何直接在配置中执行此操作,但是如果您的应用程序通过MVC命名空间或MVC Java配置进行配置,请参见第18.16.1节“启用MVC Java配置或MVC XML命名空间”。
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"> <property name="messageConverters"> <util:list id="beanList"> <ref bean="stringHttpMessageConverter"/> <ref bean="marshallingHttpMessageConverter"/> </util:list> </property> </bean> <bean id="stringHttpMessageConverter" class="org.springframework.http.converter.StringHttpMessageConverter"/> <bean id="marshallingHttpMessageConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter"> <property name="marshaller" ref="castorMarshaller"/> <property name="unmarshaller" ref="castorMarshaller"/> </bean> <bean id="castorMarshaller" class="org.springframework.oxm.castor.CastorMarshaller"/> @RequestBody方法参数可以用@Valid注释,在这种情况下,它将使用配置的Validator实例进行验证。 当使用MVC命名空间或MVC Java配置时,会自动配置一个JSR-303验证器,假设在类路径上可用JSR-303实现。 就像@ModelAttribute参数一样,可以使用一个Errors参数来检查错误。 如果未声明此类参数,则将引发MethodArgumentNotValidException异常。 该异常在DefaultHandlerExceptionResolver中处理,它将向客户端发送一个400错误。
使用@ResponseBody注解映射响应体
使用@RequestParam
注释将请求参数绑定到控制器中的方法参数。
以下代码片段显示用法:
@Controller @RequestMapping(“/ pets”) @SessionAttributes(“pet”) public class EditPetForm { // ... @GetMapping public String setupForm( @RequestParam(“petId”)int petId,ModelMap model){ Pet pet = this .clinic.loadPet(petId); model.addAttribute( “pet”,pet); 返回“petForm” ; } // ... }
使用这个注解的参数默认情况下必需的,但你可以指定一个参数是通过设置可选@RequestParam
的required
属性false
(如@RequestParam(name="id", required=false)
)。
如果目标方法参数类型不是,则会自动应用类型转换 String
。请参阅“方法参数和类型转换”一节。
当@RequestParam
在一个Map<String, String>
或者 MultiValueMap<String, String>
参数上使用注释时,地图将填充所有请求参数。
所述@RequestBody
方法参数注释指示方法参数应绑定到HTTP请求正文的值。例如:
@PutMapping(“/ something”) public void handle( @RequestBody String body,Writer writer) throws IOException { writer.write(body); }
您可以使用a将请求体转换为method参数HttpMessageConverter
。 HttpMessageConverter
负责从HTTP请求消息转换为对象,并从对象转换为HTTP响应正文。该RequestMappingHandlerAdapter
支持@RequestBody
使用以下默认注释HttpMessageConverters
:
-
ByteArrayHttpMessageConverter
转换字节数组。 -
StringHttpMessageConverter
转换字符串。 -
FormHttpMessageConverter
将表单数据转换为/从MultiValueMap <String,String>转换。 -
SourceHttpMessageConverter
转换为/从javax.xml.transform.Source转换。
有关这些转换器的更多信息,请参阅消息转换器。另请注意,如果使用MVC命名空间或MVC Java配置,默认情况下会注册更广泛的消息转换器。有关详细信息,请参见第18.16.1节“启用MVC Java配置或MVC XML命名空间”。
如果您打算读写XML,则需要 从包中MarshallingHttpMessageConverter
配置特定的Marshaller
和实现。下面的示例显示了如何直接在配置中执行此操作,但是如果您的应用程序通过MVC命名空间或MVC Java配置进行配置,请参见第18.16.1节“启用MVC Java配置或MVC XML命名空间”。Unmarshaller
org.springframework.oxm
<豆 类 = “org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter” > <属性 名 = “了MessageConverter” > <util的:列表 ID = “beanList” > <REF 豆 = “stringHttpMessageConverter” /> < ref bean = “marshallingHttpMessageConverter” /> </ util:list> </ property> </ bean> <bean id = “stringHttpMessageConverter” class = “org.springframework.http。转换器.StringHttpMessageConverter“ /> <bean id = ”marshallingHttpMessageConverter“ class = ”org.springframework.http.converter.xml.MarshallingHttpMessageConverter“ > <property name = ”marshaller“ ref = ”castorMarshaller“ /> <property name = ”unmarshaller“ ref = “castorMarshaller” /> </ bean> <bean id = “castorMarshaller” class = “org.springframework.oxm.castor.CastorMarshaller”/>
一种@RequestBody
方法参数可以与进行注释@Valid
,在这种情况下,它将使用配置的验证Validator
实例。当使用MVC命名空间或MVC Java配置时,会自动配置一个JSR-303验证器,假设在类路径上可用JSR-303实现。
就像使用@ModelAttribute
参数,一个Errors
参数可以用来检查错误。如果没有宣布这样的论据,MethodArgumentNotValidException
将会提出一个。在异常处理DefaultHandlerExceptionResolver
,它发送400
错误回到客户端。
有关通过MVC命名空间或MVC Java配置配置消息转换器和验证器的信息,请参见第18.16.1节“启用MVC Java配置或MVC XML命名空间”。 |