Spring WebFlux 基础教程:构建简单RESTful API
我们通过使用 Spring WebFlux 来实现对 Person 对象操作的 RESTful API。
主要有 3 步操作:
- 实体的定义
- 实体的相关操作
- 路由规则的配置
定义 Person 实体
public class Person {
private Integer age;
private String name;
public Person(String name, Integer age) {
this.age = age;
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
使用内存Map, 模拟数据存储
public interface PersonRepository {
Mono<Person> getPerson(int id);
Flux<Person> allPeople();
Mono<Void> savePerson(Mono<Person> personMono);
Mono<Void> deletePerson(int id);
Mono<Void> updatePerson(int id, Mono<Person> personMono);
}
实体操作
@Slf4j
public class DummyPersonRepository implements PersonRepository {
private final Map<Integer, Person> people = new ConcurrentHashMap<>();
public DummyPersonRepository() {
this.people.put(1, new Person("John Doe", 42));
this.people.put(2, new Person("Jane Doe", 36));
}
@Override
public Mono<Person> getPerson(int id) {
return Mono.justOrEmpty(this.people.get(id));
}
@Override
public Flux<Person> allPeople() {
return Flux.fromIterable(this.people.values());
}
@Override
public Mono<Void> savePerson(Mono<Person> personMono) {
return personMono.doOnNext(person -> {
int id = this.people.size() + 1;
this.people.put(id, person);
log.info("Save id = {}, person = {}", id, person);
}).then(Mono.empty());
}
@Override
public Mono<Void> deletePerson(int id) {
this.people.remove(id);
return Mono.empty();
}
@Override
public Mono<Void> updatePerson(int id, Mono<Person> personMono) {
return personMono.doOnNext(person -> {
this.people.put(id, person);
log.info("Update id = {}, person = {}", id, person);
}).then(Mono.empty());
}
}
Handler 处理
public class PersonHandler {
private final PersonRepository repository;
public PersonHandler(PersonRepository repository) {
this.repository = repository;
}
public Mono<ServerResponse> getPerson(ServerRequest request) {
int personId = Integer.parseInt(request.pathVariable("id"));
Mono<Person> personMono = this.repository.getPerson(personId);
return personMono.flatMap(person -> ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(person))).switchIfEmpty(ServerResponse.notFound().build());
}
public Mono<ServerResponse> savePerson(ServerRequest request) {
Mono<Person> personMono = request.bodyToMono(Person.class);
return ServerResponse.ok().build(this.repository.savePerson(personMono));
}
public Mono<ServerResponse> allPeople(ServerRequest request) {
Flux<Person> personFlux = this.repository.allPeople();
return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(personFlux, Person.class);
}
public Mono<ServerResponse> deletePerson(ServerRequest request) {
int id = Integer.parseInt(request.pathVariable("id"));
return ServerResponse.ok().build(this.repository.deletePerson(id));
}
public Mono<ServerResponse> updatePerson(ServerRequest request) {
int personId = Integer.parseInt(request.pathVariable("id"));
Mono<Person> personMono = request.bodyToMono(Person.class);
return ServerResponse.ok().build(this.repository.updatePerson(personId, personMono));
}
}
路由规则配置
@Configuration
public class RoutingConfiguration {
@Bean
public PersonRepository repository() {
return new DummyPersonRepository();
}
@Bean
public PersonHandler handler(PersonRepository repository) {
return new PersonHandler(repository);
}
@Bean
public RouterFunction<ServerResponse> routes(PersonHandler handler) {
return RouterFunctions.route().GET("/person/{id}",
RequestPredicates.accept(MediaType.APPLICATION_JSON), handler::getPerson)
.GET("/person", RequestPredicates.accept(MediaType.APPLICATION_JSON), handler::allPeople)
.POST("/person", RequestPredicates.accept(MediaType.APPLICATION_JSON), handler::savePerson)
.DELETE("/person/{id}", RequestPredicates.accept(MediaType.APPLICATION_JSON), handler::deletePerson)
.PUT("/person/{id}", RequestPredicates.accept(MediaType.APPLICATION_JSON), handler::updatePerson)
.build();
}
}
测试效果
1.GET 方法,请求所有的 Person 对象。
2.GET 方法,请求单个 Person 对象。
3.POST 方法,增加一个 Person。
4.DELETE 方法,删除一个Person。
5.PUT方法,更新一个 Person。
至此,一个简单的 RESTful 项目构建完成了。