Spring MVC注解@RequestBody @RequestMapping @GetMapping @PostMapping @PutMapping @DeleteMapping @PatchMapping @ControllerAdvice等

x33g5p2x  于2021-08-23 转载在 Spring  
字(9.4k)|赞(0)|评价(0)|浏览(199)

在本教程中,我们将探索org.springframework.web.bind.annotation包中的Spring Web注解,主要包括如下注解:

@RequestBody

@RequestBody注解表示方法参数需要被绑定到Web请求实体上。请求实体通过一个HttpMessageConverter来解决方法参数。可以通过@Valid注解对参数进行数据验证。

例如,使用**@RequestBody**注解将雇员JSON对象转换为Java对象。

@RestController
@RequestMapping("/api/v1")
public class EmployeeController {
    @Autowired
    private EmployeeRepository employeeRepository;
    
    @PostMapping("/employees")
    public Employee createEmployee(@Valid @RequestBody Employee employee) {
        return employeeRepository.save(employee);
    }

@RequestMapping

@RequestMapping注解用于将Web请求映射到具有灵活方法签名的请求处理类方法上。

Spring MVC和Spring WebFlux都通过各自模块和包结构中的RequestMappingHandlerMappingRequestMappingHandlerAdapter支持这个注解。
@RequestMapping标记@Controller类中的请求处理方法;可以使用以下方式配置

  • path,或其别名,名称和值:方法被映射到哪个URL上
  • method:HTTP方法
  • params:根据HTTP参数的存在、不存在或其值来过滤请求。
  • headers:根据HTTP头信息的存在、不存在或其值来过滤请求。
  • consumes:该方法在HTTP请求体中可以支持哪些请求类型
  • produces:该方法可以在HTTP响应体中产生哪些请求类型

调用示例如下:

@Controller
class EmployeeController {
 
    @RequestMapping(value = "/employees/home", method = RequestMethod.GET)
    String home() {
        return "home";
    }
}

如果我们在类的层面上应用这个注解,我们可以为@Controller类中的所有处理方法提供默认设置。唯一的例外是URL,Spring不会用方法级别的设置来覆盖它,而是附加两个路径部分。
例如,下面的配置与上面的配置有相同的效果。

@Controller
@RequestMapping(value = "/employees", method = RequestMethod.GET)
class EmployeeController {
 
    @RequestMapping("/home")
    String home() {
        return "home";
    }
}

@GetMapping

@GetMapping注解用于将HTTP GET请求映射到特定的处理方法上。

具体来说, @GetMapping是一个复合注解, 作为@RequestMapping(method = RequestMethod.GET)的快捷方式。
例子:

@GetMapping("/employees")
public List<Employee> getAllEmployees() {
 return employeeRepository.findAll();
}

@GetMapping("/employees/{id}")
public ResponseEntity<Employee> getEmployeeById(@PathVariable(value = "id") Long employeeId)
 throws ResourceNotFoundException {
 Employee employee = employeeRepository.findById(employeeId)
   .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));
 return ResponseEntity.ok().body(employee);
}

@PostMapping

**@PostMapping 是一个将HTTP POST请求映射到特定的处理方法上的注解。

具体来说, @PostMapping是一个复合注解,作为@RequestMapping(method = RequestMethod.POST)的快捷方式。
例如。

@PostMapping("/employees")
public Employee createEmployee(@Valid @RequestBody Employee employee) {
 return employeeRepository.save(employee);
}

@PutMapping

@PutMapping注解用于将HTTP PUT请求映射到特定的处理方法上。

具体来说,@PutMapping是一个复合注解,作为@RequestMapping(method = RequestMethod.PUT)的快捷方式。
例子。

@PutMapping("/employees/{id}")
public ResponseEntity<Employee> updateEmployee(@PathVariable(value = "id") Long employeeId,
  @Valid @RequestBody Employee employeeDetails) throws ResourceNotFoundException {
 Employee employee = employeeRepository.findById(employeeId)
 .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));

 employee.setEmailId(employeeDetails.getEmailId());
 employee.setLastName(employeeDetails.getLastName());
 employee.setFirstName(employeeDetails.getFirstName());
 final Employee updatedEmployee = employeeRepository.save(employee);
 return ResponseEntity.ok(updatedEmployee);
}

@DeleteMapping

@DeleteMapping注解用于将HTTP DELETE请求映射到特定的处理方法上。

具体来说, @DeleteMapping是一个复合注解,作为@RequestMapping(method = RequestMethod.DELETE)的快捷方式。
例子。

@DeleteMapping("/employees/{id}")
public Map<String, Boolean> deleteEmployee(@PathVariable(value = "id") Long employeeId)
  throws ResourceNotFoundException {
 Employee employee = employeeRepository.findById(employeeId)
   .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId));

 employeeRepository.delete(employee);
 Map<String, Boolean> response = new HashMap<>();
 response.put("deleted", Boolean.TRUE);
 return response;
}

@PatchMapping

@PatchMapping注解用于将HTTP PATCH请求映射到特定的处理方法上。

具体来说,@PatchMapping是一个复合注解,作为@RequestMapping(method = RequestMethod.PATCH)的快捷方式。
例如。

@PatchMapping("/patch")
public @ResponseBody ResponseEntity<String> patch() {
    return new ResponseEntity<String>("PATCH Response", HttpStatus.OK);
}

@ControllerAdvice

@ControllerAdvice注解是@Component的一种特殊化组件。用**@ControllerAdvice**注解的类会被classpath扫描自动检测到。

使用**@ControllerAdvice是为@ExceptionHandler@InitBinder,@ModelAttribute提供所有或选定的控制器。我们要做的是创建一个带有@ControllerAdvice注解的类,并创建一个所需的方法,该方法将带有@ExceptionHandler注解,用于全局异常处理,@InitBinder用于全局初始绑定,@ModelAttribute用于全局模型属性添加。每当一个请求来到一个控制器和它的方法@RequestMapping,如果没有本地定义的@ExceptionHandler**,@InitBinder@ModelAttribute,全局定义的类注解@ControllerAdvice被提供。
调用示例如下:

@ControllerAdvice(basePackages = {"com.javaguides.springmvc.controller"} )
public class GlobalControllerAdvice {
 @InitBinder
 public void dataBinding(WebDataBinder binder) {
  SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
  dateFormat.setLenient(false);
  binder.registerCustomEditor(Date.class, "dob", new CustomDateEditor(dateFormat, true));
 }
 @ModelAttribute
        public void globalAttributes(Model model) {
  model.addAttribute("msg", "Welcome to My World!");
        }
 @ExceptionHandler(FileNotFoundException.class)
        public ModelAndView myError(Exception exception) {
     ModelAndView mav = new ModelAndView();
     mav.addObject("exception", exception);
     mav.setViewName("error");
     return mav;
 }
}

@ResponseBody

当你在一个方法上使用**@ResponseBody注解时,Spring会自动转换返回值并将其写入HTTP响应中。控制器类中的每个方法都必须用@ResponseBody**来注解。

@ResponseBody注解告诉控制器,返回的对象被自动序列化为JSON,并传回HttpResponse对象中。
比如说

@ResponseBody
@RequestMapping("/hello")
String hello() {
    return "Hello World!";
}

Spring 4.0引入了@RestController,这是一个专门的控制器注解,结合了@Controller和@ResponseBody注解。

@ExceptionHandler

@ExceptionHandler注解用于处理特定处理程序类和/或处理程序方法中的异常。

使用该注解的处理程序方法可以有非常灵活的签名。
当一个请求处理方法抛出任何指定的异常时,Spring会调用这个方法。被捕获的异常可以作为一个参数传递给该方法。

@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<?> resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
  ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
  return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
}

@ResponseStatus

如果我们用这个注解来注解一个请求处理方法,我们可以指定响应的HTTP状态。我们可以用code参数或其别名value参数来声明状态代码。

此外,我们还可以使用理由参数提供一个原因。
我们也可以和**@ExceptionHandler**一起使用。

@ResponseStatus(HttpStatus.BAD_REQUEST)
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<?> resourceNotFoundException(ResourceNotFoundException ex, WebRequest request) {
  ErrorDetails errorDetails = new ErrorDetails(new Date(), ex.getMessage(), request.getDescription(false));
  return new ResponseEntity<>(errorDetails, HttpStatus.NOT_FOUND);
}

@PathVariable

这个注解表示一个方法参数被绑定到一个URI模板变量。我们可以用@RequestMapping注解指定URI模板,用@PathVariable将方法参数绑定到模板的某个部分。

@RequestMapping("/{id}")
public User getUser(@PathVariable("id") long id) {
    // ...
}

如果模板中的部分名称与方法参数的名称一致,我们就不必在注解中指定它。

@RequestMapping("/{id}")
public User getUser(@PathVariable long id) {
    // ...
}

此外,我们可以通过将参数required设置为false来标记一个路径变量的可选性。

@RequestMapping("/{id}")
public User getUser(@PathVariable(required = false) long id) {
    // ...
}

@RequestParam

@RequestParam注解,表示一个方法参数应该被绑定到一个网络请求参数。我们使用**@RequestParam**来访问HTTP请求参数。

@RequestMapping
Vehicle getVehicleByParam(@RequestParam("id") long id) {
    // ...
}

它的配置选项与**@PathVariable**注解相同。

除了这些设置外,通过**@RequestParam**我们可以在Spring发现请求中没有或空值时指定一个注入的值。为了实现这一点,我们必须设置默认值参数。
提供一个缺省值隐含地将required设置为false。

@RequestMapping("/buy")
Car buyCar(@RequestParam(defaultValue = "5") int seatCount) {
    // ...
}

阅读更多内容请点击https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestParam.html

@Controller

这个注解只是@Component类的一个特殊化,允许通过classpath扫描自动检测到实现类。

我们可以用@Controller定义一个Spring MVC控制器。阅读更多:Spring @Controller 和 @RestController 注解与实例
例如:

@Controller
@RequestMapping("/api/v1")
public class EmployeeController {
    @Autowired
    private EmployeeRepository employeeRepository;

    @GetMapping("/employees")
    public List<Employee> getAllEmployees() {
        return employeeRepository.findAll();
    }
}

@RestController

Spring 4.0引入了@RestController,这是一个专门的控制器版本,它是一个方便的注解,除了添加@Controller和@ResponseBody注解外,没有其他作用。通过用@RestController注解来注解控制器类,你不再需要在所有的请求映射方法中添加@ResponseBody。默认情况下,@ResponseBody注解是激活的。

要在我们的例子中使用@RestController,我们需要做的就是将@Controller修改为@RestController,并从每个方法中移除@ResponseBody。最终的类应该如下所示

@RestController
@RequestMapping("/api/v1")
public class EmployeeController {
    @Autowired
    private EmployeeRepository employeeRepository;

    @GetMapping("/employees")
    public List<Employee> getAllEmployees() {
        return employeeRepository.findAll();
    }
}

@ModelAttribute

通过这个注解,我们可以访问已经在MVC @Controller模型中的元素,只要提供模型的键值。

@PostMapping("/users")
void saveUser(@ModelAttribute("user") User user) {
    // ...
}

像@PathVariable和@RequestParam一样,如果参数有相同的名字,我们就不必指定模型键。

@PostMapping("/users")
void saveUser(@ModelAttribute User user) {
    // ...
}

此外,@ModelAttribute还有另一个用途:如果我们用它来注解一个方法,Spring会自动将该方法的返回值添加到模型中。

@ModelAttribute("vehicle")
User getUser() {
    // ...
}

像以前一样,我们不需要指定模型键,Spring默认使用方法的名称。

@ModelAttribute
User user() {
    // ...
}

在Spring调用一个请求处理方法之前,它会调用类中所有@ModelAttribute注解的方法。

@CrossOrigin

@CrossOrigin为注解的请求处理方法启用跨域通信。

@CrossOrigin
@RequestMapping("/hello")
String hello() {
    return "Hello World!";
}

如果我们用它来标记一个类,它就适用于其中的所有请求处理方法。

我们可以通过这个注解的参数来微调CORS行为。

@InitBinder

@InitBinder 注解确定了初始化WebDataBinder的方法,这些方法将用于填充被注解的处理方法的命令和表单对象参数。

这种init-binder方法支持RequestMapping所支持的所有参数,除了命令/表单对象和相应的验证结果对象。Init-binder方法不能有返回值;它们通常被声明为void。
例如:

// add an initbinder ... to convert trim input strings
    // remove leading and trailing whitespace
    // resolve issue for our validation

    @InitBinder
    public void initBinder(WebDataBinder dataBinder) {

        StringTrimmerEditor stringTrimmerEditor = new StringTrimmerEditor(true);

        dataBinder.registerCustomEditor(String.class, stringTrimmerEditor);
    }

相关文章