Spring Boot 2.2.0 – WebMvc.fn
Spring Boot 2.2.0 – WebMvc.fn
Pojawienie się wersji Spring Boota 2.2.0 niesie za sobą nową funkcjonalność WebMvc.fn. Jest to podejście które pozwala na definiowanie endpointów w sposób funkcyjny. Nie musimy rezygnować ze starego podejścia z użyciem adnotacji @Controller. Te dwa podejścia mogą być używane wymiennie. Do dzieła!
Tworzymy nowy projekt Spring Boot (wersja 2.2.0.BUILD-SNAPSHOT) – plik pom.xml:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>http://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>http://repo.spring.io/milestone</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>http://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> <pluginRepository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>http://repo.spring.io/milestone</url> </pluginRepository> </pluginRepositories>
Klasa modelu:
public class User { String name; String surname; public User() { } public User(String name, String surname) { this.name = name; this.surname = surname; } // getters & setters }
Klasa serwisu:
public interface UserDataService { List<User> getAllUsers(); void addNewUser(User jsonUser); }
Implementacja serwisu:
@Service class UserDataServiceImpl implements UserDataService { @Override public List<User> getAllUsers() { return UsersDatabaseHelper.getAllUsers(); } @Override public void addNewUser(User jsonUser) { UsersDatabaseHelper.addUser(jsonUser); } }
Klasa konfiguracyjna dla kontrolera:
Metoda oznaczona adnotacją @Bean tworzy ziarno zarządzane przez Springa. Jako argument do metody Spring wstrzykuje obiekt UserDataService ponieważ jest to ziarno zarządzane przez Springa o czym świadczy użycie adnotacji @Service dla klasy UserDataServiceImpl.
@Configuration public class ConfigurationControllersRouting { @Bean public RouterFunction<ServerResponse> routes(UserDataService userDataService) { return route() .GET("/getAllUsers", serverRequest -> ServerResponse.ok() .body(userDataService.getAllUsers())) . POST("/addNewUser", request -> { userDataService.addNewUser(request.body(User.class)); return ServerResponse.created(URI.create("/location")).build(); }) .build(); } }
Klasa pomocnicza która generuje przykładowych użytkowników:
public class UsersDatabaseHelper { static List<User> users = new ArrayList(); static { User user1 = new User("user-1", "user-1"); User user2 = new User("user-2", "user-2"); User user3 = new User("user-3", "user-3"); User user4 = new User("user-4", "user-4"); User user5 = new User("user-5", "user-5"); users.add(user1); users.add(user2); users.add(user3); users.add(user4); users.add(user5); } public static List<User> getAllUsers() { return users; } public static void addUser(User user) { users.add(user); } }
Testy:
Pobranie wszystkich użytkowników – żądanie GET:
http://localhost:8080/getAllUsers
Dodanie nowego użytkownika z użyciem narzędzia Advanced Rest Client – żądanie POST:
http://localhost:8080/addNewUser
JSON:
{"name":"newUser","surname":"newUser"}
Zamieszczony wyżej kod można usprawnić tworząc klasę która reprezentuje wykonywane operacje dla poszczególnych metod protokołu HTTP, np. dla metody POST będzie to:
@Component class Handler { public ServerResponse handlePost(ServerRequest serverRequest) throws ServletException, IOException { userDataService.addNewUser(serverRequest.body(User.class)); return ServerResponse.created(URI.create("/location")).build(); } }
Wtedy klasa ConfigurationControllersRouting po modyfikacji wygląda następująco:
@Configuration public class ConfigurationControllersRouting { @Autowired UserDataService userDataService; @Component class Handler { public ServerResponse handlePost(ServerRequest serverRequest) throws ServletException, IOException { userDataService.addNewUser(serverRequest.body(User.class)); return ServerResponse.created(URI.create("/location")).build(); } } @Bean public RouterFunction<ServerResponse> routes(Handler handler) { return route() .GET("/getAllUsers", serverRequest -> ServerResponse.ok() .body(userDataService.getAllUsers())) .POST("/addNewUser", handler::handlePost) .build(); } }
Polecam dodatkowo materiał dostępny na oficjalnej stronie springa:
Leave a comment