Spring 5.2.2 MVC (7)—注解控制器

接着Spring 5.2.2 MVC (6)--注释控制器讲基于注解控制内容。
java


3)后缀匹配typescript

     默认状况下,Spring MVC执行.*后缀模式匹配,以便映射到/person的控制器也隐蔽映射到/person.*。而后使用文件扩展名解释请求的内容类型以用于响应(即,代替Accept 头) - ,例如/person.pdf/person.xml和其余。编程

     当浏览器用来发送难以一致的Accept 头时,以这种方式使用文件扩展名是必要的。目前,这已再也不是必需的,使用Accept 头应该是首选。json

     随着时间的推移,文件扩展名的使用已经被证实在许多方面存在问题。当使用URI变量、路径参数和URI编码覆盖时,它可能会致使歧义。关于基于URL的受权和安全性的推理也变得更加困难。浏览器

要彻底禁用文件扩展名的使用,必须同时设置如下两项:安全

  1. useSuffixPatternMatching(false)--参看PathMatchConfigurer微信

  2. favorPathExtension(false)--参看ContentNegotiationConfigureapp


基于URL的内容仍然颇有用(例如,在浏览器中键入URL时)。为了实现这一点,咱们建议使用基于查询参数的策略,以免文件扩展名带来的大多数问题。或者,若是必须使用文件扩展名,请考虑经过ContentNegotiationConfigurermediaTypes 属性将它们限制为显式注册的扩展名列表。ide

@Configuration@EnableWebMvcpublic class WebConfig implements WebMvcConfigurer {
@Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { configurer.mediaType("json", MediaType.APPLICATION_JSON); configurer.mediaType("xml", MediaType.APPLICATION_XML); }}


4)后缀匹配和RFD测试

      反射文件下载(reflected file download,RFD)攻击与XSS相似,它依赖于响应中反射的请求输入(例如,查询参数和URI变量)。然而RFD攻击不是将JavaScript插入HTML,而是依赖于浏览器切换来执行下载,并在之后双击时将响应视为可执行脚本。

     在Spring MVC中,@ResponseBodyResponseEntity 方法面临风险,由于它们能够呈现不一样的内容类型,客户端能够经过URL路径扩展请求这些内容类型。禁用后缀模式匹配和使用路径扩展进行内容能够下降风险,但不足以防止RFD攻击。

    为了防止RFD攻击,在呈现响应体以前,Spring MVC添加了一个:Content-Disposition:inline;filename=f.txt头来建议一个固定且安全的下载文件。只有当URL路径包含既没有白名单也没有为内容显式注册的文件扩展名时,才会执行此操做。然而,当URL直接输入到浏览器中时,它可能会产生反作用。

    默认状况下,许多公共路径扩展都是白名单。具备自定义HttpMessageConverter 实现的应用程序能够注册用于内容的文件扩展名,以免为这些扩展名添加Content-Disposition头。

有关RFD的其余建议,见CVE-2015-5211。

5)Consumable 媒体Types

    能够根据请求的Content-Type缩小请求映射范围,以下例所示:

//使用consumes属性缩小Content-Type映射范围。@PostMapping(path = "/pets", consumes = "application/json") public void addPet(@RequestBody Pet pet) { // ...}

consumes 属性还支持否认表达式 - ,例如!text/plain是指除text/plain之外的任何内容类型。

     能够在类级别声明一个共享consumes 属性。然而,与大多数其余请求映射属性不一样,当在类级别使用时,方法级别使用consumes 属性重写,而不是扩展类级别声明。

   MediaType 为经常使用的媒体类型(如APPLICATION_JSON_VALUE APPLICATION_XML_VALUE)提供常量。


6)Producible 媒体 Types

    能够基于Accept 请求头和控制器方法生成的内容类型列表缩小请求映射,以下例所示:

//使用products属性缩小content type映射范围。@GetMapping(path = "/pets/{petId}", produces = "application/json") @ResponseBodypublic Pet getPet(@PathVariable String petId) { // ...}

媒体类型能够指定字符集。例如,支持否认表达式 -!text/plain是指除“text/plain”以外的任何内容类型。

    能够在类级别声明共享的produces 属性。可是,与大多数其余请求映射属性不一样,当在类级别使用时,方法级别生成produces 属性重写,而不是扩展类级别声明。


7)Parameters, headers

    能够基于请求参数条件缩小请求映射范围。你能够测试是否存在请求参数(myParam),是否缺乏一个(!myPara)或特定值(myParam=myValue)。如下示例演示如何测试特定值:

//测试myParam是否等于myValue@GetMapping(path = "/pets/{petId}", params = "myParam=myValue") public void findPet(@PathVariable String petId) { // ...}

你还能够对请求头条件使用相同的条件,以下例所示:

//测试myHeader是否等于myvalue。@GetMapping(path = "/pets", headers = "myHeader=myValue") public void findPet(@PathVariable String petId) { // ...}

    你能够将Content-TypeAccept 与headers条件匹配,但最好使用consumersproducts


8)HTTP HEAD, OPTIONS

   @GetMapping(和@RequestMapping(method=HttpMethod.GET))为请求映射支持HTTP HEAD 。控制器方法不须要更改。在javax.servlet.http.HttpServlet中应用的response 封装确保将Content-Length头设置为写入的字节数(而不实际写入响应)。

  @GetMapping(和@RequestMapping(method=HttpMethod.GET))隐式映射到并支持HTTP HEAD。一个HTTP HEAD请求被看成HTTP GET来处理,只是不写正文,而是计算字节数并设置Content-Length头。

     默认状况下,经过将Allow response头设置为全部@RequestMapping方法中列出的具备匹配URL模式的HTTP方法列表来处理HTTP选项。

    对于没有HTTP方法声明的@RequestMappingAllow 头被设置为GET、HEAD、POST、PUT、PATCH、DELETE、OPTIONS。控制器方法应始终声明支持的HTTP方法(例如,使用HTTP方法特定的变量:@GetMapping@PostMapping和其余变量)。

     你能够将@RequestMapping方法映射到HTTP HEAD和HTTP  OPTIONS,但在通常状况下这是不必的。


9)自定义注解

    Spring MVC支持使用组合注解进行请求映射。这些注解自己就是用@RequestMapping进行元注解的注解,用于从新声明@RequestMapping属性的一个子集(或所有),具备更窄、更具体的用途。

   @GetMapping@PostMapping@PutMapping@DeleteMapping@PatchMapping是组合注解的示例。之因此提供它们,是由于大多数控制器方法应该映射到特定的HTTP方法,而不是使用@RequestMapping,默认状况下,它与全部HTTP方法匹配。若是须要组合注解的示例,请查看如何声明这些注释。

    Spring MVC还支持具备自定义请求匹配逻辑的自定义请求映射属性。这是一个更高级的选项,须要子类RequestMappingHandlerMapping 并重写getCustomMethodCondition 方法,你能够在该方法中检查自定义属性并返回本身的RequestCondition


10)易于理解的Registrations

    你能够以编程方式注册处理程序方法,这些方法可用于动态注册或高级状况,例如不一样URL下同一处理程序的不一样实例。如下示例注册处理程序方法:

@Configurationpublic class MyConfig { //为控制器注入目标处理程序和处理程序映射。 @Autowired public void setHandlerMapping(RequestMappingHandlerMapping mapping, UserHandler handler)  throws NoSuchMethodException {    //准备请求映射数据。 RequestMappingInfo info = RequestMappingInfo .paths("/user/{id}").methods(RequestMethod.GET).build();  //获取处理程序方法 Method method = UserHandler.class.getMethod("getUser", Long.class);  //添加注册。 mapping.registerMapping(info, handler, method);  }}


明天讲 基于控制器注解的句柄方法(Handler Methods)。


敬请持续关注。


欢迎关注和转发Spring中文社区(加微信群,能够关注后加我微信):


本文分享自微信公众号 - Spring中文社区(gh_81d233bb13a4)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索