SpringBoot 2 构建 REST 服务 - HTTP 平台

要用 Web 层包装存储库,必须使用 Spring MVC。多亏了 Spring Boot,几乎没有基础代码可以编写。相反,我们可以专注于操作:

nonrest/src/main/java/payroll/EmployeeController.java

package payroll;

import java.util.List;

import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
class EmployeeController {

  private final EmployeeRepository repository;

  EmployeeController(EmployeeRepository repository) {
    this.repository = repository;
  }

  // Aggregate root

  @GetMapping("/employees")
  List<Employee> all() {
    return repository.findAll();
  }

  @PostMapping("/employees")
  Employee newEmployee(@RequestBody Employee newEmployee) {
    return repository.save(newEmployee);
  }

  // Single item

  @GetMapping("/employees/{id}")
  Employee one(@PathVariable Long id) {

    return repository.findById(id)
      .orElseThrow(() -> new EmployeeNotFoundException(id));
  }

  @PutMapping("/employees/{id}")
  Employee replaceEmployee(@RequestBody Employee newEmployee, @PathVariable Long id) {

    return repository.findById(id)
      .map(employee -> {
        employee.setName(newEmployee.getName());
        employee.setRole(newEmployee.getRole());
        return repository.save(employee);
      })
      .orElseGet(() -> {
        newEmployee.setId(id);
        return repository.save(newEmployee);
      });
  }

  @DeleteMapping("/employees/{id}")
  void deleteEmployee(@PathVariable Long id) {
    repository.deleteById(id);
  }
}
  • @RestController 表示每个方法返回的数据将直接写入响应主体,而不是呈现模版;
  • EmployeeRepository 由构造函数注入到控制器中;
  • 我们为每个操作提供路由(@GetMapping@PostMapping@PutMapping@DeleteMapping,对应于 HTTP 的 GETPOSTPUTDELETE 调用)。(注意:阅读每种方法并了解他它们的作用非常有用。);
  • EmployeeNotFoundException 是一个异常,用于指示何时查找员工但找不到员工。

nonrest/src/main/java/payroll/EmployeeNotFoundException.java

package payroll;

class EmployeeNotFoundException extends RuntimeException {

  EmployeeNotFoundException(Long id) {
    super("Could not find employee " + id);
  }
}

当抛出 EmployeeNotFoundException 时,Spring MVC 配置的这个额外花絮用于呈现 HTTP 404

nonrest/src/main/java/payroll/EmployeeNotFoundAdvice.java

package payroll;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

@ControllerAdvice
class EmployeeNotFoundAdvice {

  @ResponseBody
  @ExceptionHandler(EmployeeNotFoundException.class)
  @ResponseStatus(HttpStatus.NOT_FOUND)
  String employeeNotFoundHandler(EmployeeNotFoundException ex) {
    return ex.getMessage();
  }
}
  • @ResponseBody 表示该建议直接呈现到响应主体中;
  • @ExceptionHandler 将建议配置为仅在抛出 EmployeeNotFoundException 时才响应;
  • @ResponseStatus 说要发出 HttpStatus.NOT_FOUND,即 HTTP 404
  • 建议的主题生成内容。在这种情况下,它会给出异常消息。

要启动要用,请右键单机 PayRollApplication 中的 public static void main,然后从 IDE 中选择 Run,或者:

Spring Initializr 使用 Maven 包装器,因此键入:

$ ./mvnw clean spring-boot:run

或者使用我们安装的 Maven 版本键入以下命令:

$ mvn clean spring-boot:run

应用启动后,我们可以立即对其进行查询。

$ curl -v localhost:8080/employees

这将产生:

*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /employees HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 200
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Thu, 09 Aug 2018 17:58:00 GMT
<
* Connection #0 to host localhost left intact
[{"id":1,"name":"Bilbo Baggins","role":"burglar"},{"id":2,"name":"Frodo Baggins","role":"thief"}]

在这里,我们可以查看压缩格式的预加载数据。

如果我们尝试查询一个不存在的用户…

$ curl -v localhost:8080/employees/99

我们将得到:

*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 8080 (#0)
> GET /employees/99 HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.54.0
> Accept: */*
>
< HTTP/1.1 404
< Content-Type: text/plain;charset=UTF-8
< Content-Length: 26
< Date: Thu, 09 Aug 2018 18:00:56 GMT
<
* Connection #0 to host localhost left intact
Could not find employee 99

该消息很好地显示了 HTTP 404 错误和自定义消息找不到雇员 99

显示当前编码的交互并不困难…

$ curl -X POST localhost:8080/employees -H 'Content-type:application/json' -d '{"name": "Samwise Gamgee", "role": "gardener"}'

创建一个新的 Employee 记录,然后将内容发送回给我们:

{"id":3,"name":"Samwise Gamgee","role":"gardener"}

我们可以更改用户:

$ curl -X PUT localhost:8080/employees/3 -H 'Content-type:application/json' -d '{"name": "Samwise Gamgee", "role": "ring bearer"}'

更新用户:

{"id":3,"name":"Samwise Gamgee","role":"ring bearer"}

根据我们构建服务的方式,可能会产生重大影响。在这种情况下,替换更新更好。例如,如果未提供名称,则将其晴空。

我们可以删除…

$ curl -X DELETE localhost:8080/employees/3
$ curl localhost:8080/employees/3
Could not find employee 3

这一切都很好,但是我们由 RESTful 服务吗?(如果我们没有受到提示,则答案为否。)

缺少了什么?

发布了232 篇原创文章 · 获赞 14 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/stevenchen1989/article/details/105531134