在本教程中,我们将探索org.springframework.web.bind.annotation包中的Spring Web注解,主要包括如下注解:
@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注解用于将Web请求映射到具有灵活方法签名的请求处理类方法上。
Spring MVC和Spring WebFlux都通过各自模块和包结构中的RequestMappingHandlerMapping
和RequestMappingHandlerAdapter
支持这个注解。
@RequestMapping标记@Controller类中的请求处理方法;可以使用以下方式配置
调用示例如下:
@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注解用于将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 是一个将HTTP POST请求映射到特定的处理方法上的注解。
具体来说, @PostMapping是一个复合注解,作为@RequestMapping(method = RequestMethod.POST)
的快捷方式。
例如。
@PostMapping("/employees")
public Employee createEmployee(@Valid @RequestBody Employee employee) {
return employeeRepository.save(employee);
}
@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注解用于将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注解用于将HTTP PATCH请求映射到特定的处理方法上。
具体来说,@PatchMapping是一个复合注解,作为@RequestMapping(method = RequestMethod.PATCH)
的快捷方式。
例如。
@PatchMapping("/patch")
public @ResponseBody ResponseEntity<String> patch() {
return new ResponseEntity<String>("PATCH Response", HttpStatus.OK);
}
@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注解时,Spring会自动转换返回值并将其写入HTTP响应中。控制器类中的每个方法都必须用@ResponseBody**来注解。
@ResponseBody注解告诉控制器,返回的对象被自动序列化为JSON,并传回HttpResponse
对象中。
比如说
@ResponseBody
@RequestMapping("/hello")
String hello() {
return "Hello World!";
}
Spring 4.0引入了@RestController,这是一个专门的控制器注解,结合了@Controller和@ResponseBody注解。
@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);
}
如果我们用这个注解来注解一个请求处理方法,我们可以指定响应的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);
}
这个注解表示一个方法参数被绑定到一个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**来访问HTTP请求参数。
@RequestMapping
Vehicle getVehicleByParam(@RequestParam("id") long id) {
// ...
}
它的配置选项与**@PathVariable**注解相同。
除了这些设置外,通过**@RequestParam**我们可以在Spring发现请求中没有或空值时指定一个注入的值。为了实现这一点,我们必须设置默认值参数。
提供一个缺省值隐含地将required设置为false。
@RequestMapping("/buy")
Car buyCar(@RequestParam(defaultValue = "5") int seatCount) {
// ...
}
这个注解只是@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();
}
}
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();
}
}
通过这个注解,我们可以访问已经在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
@RequestMapping("/hello")
String hello() {
return "Hello World!";
}
如果我们用它来标记一个类,它就适用于其中的所有请求处理方法。
我们可以通过这个注解的参数来微调CORS行为。
@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);
}
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://www.javaguides.net/2018/11/spring-web-mvc-annotations.html
内容来源于网络,如有侵权,请联系作者删除!