SpringMVC Tutorial - Controller

Original address: https://www.codemore.top/cates/Backend/post/2018-04-10/spring-mvc-controller
declare Controller

Controller is also a standard Spring bean that can be WebApplicationContextdefined in Servlet. You can also use @Controllerannotations, and Spring will scan the annotations and automatically register them as Spring beans. Beans with automatic registration @Controllerannotations enabled can use the following Java Config configuration:

@Configuration
@ComponentScan("org.example.web")
public class WebConfig { // ... }

If you use xml configuration, as follows:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="org.example.web"/> <!-- ... --> </beans>
request mapping

@RequestMappingRequests can be mapped to specific Controller methods. Map requests by finding matching urls, http methods, request parameters, headers, media types. This annotation can be used both at the class level and at the method level. For convenience @RequestMapping, the following shortcut annotations are provided according to different HTTP methods:

  • @GetMapping
  • @PostMapping
  • @DeleteMapping
  • @PutMapping
  • @PatchMapping

An example is shown below:

@RestController
@RequestMapping("/persons")
class PersonController { @GetMapping("/{id}") public Person getPerson(@PathVariable Long id) { // ... } @PostMapping @ResponseStatus(HttpStatus.CREATED) public void add(@RequestBody Person person) { // ... } }
URI schematic

Request mapping supports glob patterns and wildcards

  • ? matches a character
  • * matches 0 or more characters
  • ** Matching zero or more paths can be done by @PathVariable accessing variables defined in the URI:
@GetMapping("/owners/{ownerId}/pets/{petId}")
public Pet findPet(@PathVariable Long ownerId, @PathVariable Long petId) { // ... }

URI variables can be defined in classes and methods:

@Controller
@RequestMapping("/owners/{ownerId}")
public class OwnerController { @GetMapping("/pets/{petId}") public Pet findPet(@PathVariable Long ownerId, @PathVariable Long petId) { // ... } }

URI variables are automatically type-converted, and TypeMismatchExceptionan exception is thrown if it fails. Types such as , , , etc. are supported by default int, longand Dateother types that need to be supported can also be registered through DataBinder and Type Conversion. URI variable names can also be explicitly supported, for example @PathVariable("customId"), but if compiled with debug information, or for Java 8 use -parameters compilation, explicit names may not be required. The syntax {varName:regex}indicates that the variable is matched according to the regular expression, for example "/spring-web-3.0.5.jar" can be matched using the following expression

@GetMapping("/{name:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{ext:\\.[a-z]+}")
public void handle(@PathVariable String version, @PathVariable String ext) { // ... }

URIs can also have embedded ${}placeholders that PropertyPlaceHolderConfigurerare parsed from local, system, environment variables or other configuration when the application starts. Spring MVC uses Spring core AntPathMatcherto match paths.

Mode comparison

When there are many pattern matching URIs, comparisons must be made to find the most suitable match. This is achieved through AntPathMatcher.getPatternComparator(String path). URLs can be scored according to the number of variables and wildcards in the URI. If a URI has fewer variables and more wildcards, the score will be lower. When the scores of the matched patterns are the same, the one with the longer matching pattern is selected. If the scores and lengths are the same, the one with fewer variables than the wildcard is selected. /**is not involved in grading and is always the last option. It is /plublic/**also selected when no other pattern without two wildcards is matched. For more detailed information, you can check AntPathMatcherin AntPatternComparator. It can also be inherited PathMatcherto customize URI matching.

suffix match

Spring MVC starts the .*suffix matching mode by default, so that /personthe mapped controller can also be mapped to /person.*. Extensions can be used in place of headers to Acceptindicate the type returned by the request. For example person.pdf, person.xmletc. This was intentional because browser Acceptheaders were hard to parse in the past, but now browsers are Acceptmore explicit, so the better option is to use Accept. And in the past, there have been various problems when using suffix name matching. When using URI variables, path parameters, and URI encoding, the suffix pattern will lead to ambiguity. Postfix mode can be turned off using:

  • PathMatchConfigurerofuseSuffixPatternMatching(false)
  • ContentNeogiationConfigurer offavorPathExtension(false)
Suffix matching and RFD

Reflected File Download (RFD) attacks are very similar to XSS attacks. XSS relies on the input of the request, such as query parameters, URI variables, etc., while RFD is that when the user clicks on the URL, the browser will download a malicious file, and after the user clicks, the host will be attacked. Since Spring MVC's  @ResponseBodysum ResponseEntityrenders different types of response content based on the URI suffix, it may be vulnerable to RFD attacks. Turning off suffix matching can reduce the risk of attacks, but cannot completely prevent RFD attacks. Content-Disposition:inline;filename=f.txtTo prevent RFD attacks, it is possible to add a secure download file when rendering the response content . Most extensions have a whitelist by default, and can HttpMessageConverterregister extensions for content negotiation via inheritance, which can avoid adding them in the response Content-Disposition.

Consumable Media Type

Content-TypeThe matching scope of the request can be narrowed by request, for example:

@PostMapping(path = "/pets", consumes = "application/json")
public void addPet(@RequestBody Pet pet) { // ... }

consumes also supports the negation of expressions, for example , it can !text/plainrefer to anything except text/plain. You can define a class-level consumes, and its methods share the consumes. Unlike other @ReqeustMappingattributes, the method's consumes will override the class definition.

Generated media types

AcceptThe matching scope of the request can be narrowed by the header, for example:

@GetMapping(path = "/pets/{petId}", produces = "application/json;charset=UTF-8")
@ResponseBody
public Pet getPet(@PathVariable String petId) { // ... }

A media type can specify a character set. Negation of expressions is also supported, for example: !text/plainrefers to all except text/plain. Like consumers, it is also possible to specify a class-level produces whose method properties also override class properties.

Parameters and HTTP headers

The range of matching requests can be narrowed by parameters. You can set whether there is a parameter ("myParam"), and vice versa ("!myParam") or specify a value ("myParam=myValue").

@GetMapping(path = "/pets/{petId}", params = "myParam=myValue")
public void findPet(@PathVariable String petId) { // ... }

The same is true for HTTP headers

@GetMapping(path = "/pets", headers = "myHeader=myValue")
public void findPet(@PathVariable String petId) { // ... }

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324615509&siteId=291194637