SpringBoot 2 builds REST service-HTTP platform

To wrap the repository with the Web layer, you must use Spring MVC. Thanks to Spring Boot, almost no basic code can be written. Instead, we can focus on the operation:

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 It means that the data returned by each method will be written directly to the response body instead of rendering the template;
  • EmployeeRepository Injected into the controller by the constructor;
  • We provide routing @GetMapping(for each operation @PostMapping, , @PutMappingand @DeleteMapping, corresponding to the HTTP GET, POST, PUTand DELETEcalls). (Note: It is very useful to read each method and understand its role.);
  • EmployeeNotFoundException An exception is used to indicate when to find an employee but cannot find an employee.

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

package payroll;

class EmployeeNotFoundException extends RuntimeException {

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

When thrown EmployeeNotFoundExceptionwhen, Spring MVC configuration of this additional scenes for rendering 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 Indicates that the suggestion is directly presented in the response body;
  • @ExceptionHandlerThe recommended configuration is only thrown EmployeeNotFoundExceptionresponse only;
  • @ResponseStatusSaid to send HttpStatus.NOT_FOUND, that is HTTP 404 ;
  • Suggested topics generate content. In this case, it will give an exception message.

To start to use, stand-alone right PayRollApplicationin public static void main, and select from the IDE in the Run , or:

Spring Initializr uses the Maven wrapper, so type:

$ ./mvnw clean spring-boot:run

Or use the Maven version we installed to type the following command:

$ mvn clean spring-boot:run

After the application starts, we can query it immediately.

$ curl -v localhost:8080/employees

This will produce:

*   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"}]

Here, we can view the preloaded data in compressed format.

If we try to query a non-existent user ...

$ curl -v localhost:8080/employees/99

We will get:

*   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

The message nicely shows the HTTP 404 error and the custom message can't find employee 99 .

Showing the currently coded interaction is not difficult ...

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

Create a new Employeerecord, and then send content back to us:

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

We can change users:

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

Update user:

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

Depending on how we structure the service, it may have a significant impact. In this case, replacement is better than update . For example, if no name is provided, clear it.

We can delete ...

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

All this is fine, but are we served by RESTful? (If we are not prompted, the answer is no.)

What is missing?

Published 232 original articles · Liked 14 · Visits 20,000+

Guess you like

Origin blog.csdn.net/stevenchen1989/article/details/105531134