1、注解式开发实现HelloWorld
1.1、配置依赖
在SpringBoot的基础依赖中添加了如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
1. 2、编写控制器
如下:
@RestController
public class HelloWorldController {
@GetMapping("/helloworld")
public Mono<String> helloworld(){
return Mono.just("This is WebFlux demo");
}
}
1.3、编写启动类
如下:
@SpringBootApplication
public class WebFluxDemoHelloWorldApplication {
public static void main(String[] args) {
SpringApplication.run(WebFluxDemoHelloWorldApplication.class, args);
}
}
2、注解式开发模拟用户新增、修改、删除
主要是模拟一个业务流程,如何获取数据。
2.1、创建实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private long id;
private String name;
private int age;
}
2.2、编写控制器
实现WebFlux的操作数据功能
@RestController
@RequestMapping(path = "/user")
public class UserController {
Map<Long, User> users = new HashMap<>();
@PostConstruct//依赖关系注入完成之后,执行初始化
public void init() throws Exception {
users.put(Long.valueOf(1), new User(1, "郭大狗", 22));
users.put(Long.valueOf(2), new User(2, "郭二狗", 21));
}
/**
* 获取所有用户
*
* @return
*/
@GetMapping("/list")
public Flux<User> getAll() {
return Flux.fromIterable(users.entrySet().stream()
.map(entry -> entry.getValue())
.collect(Collectors.toList()));
}
/**
* 获取单个用户
*
* @param id
* @return
*/
@GetMapping("/{id}")
public Mono<User> getUser(@PathVariable Long id) {
return Mono.justOrEmpty(users.get(id));
}
/**
* 创建用户
*
* @param user
* @return
*/
@PostMapping("")
public Mono<ResponseEntity<String>> addUser(User user) {
users.put(user.getId(), user);
return Mono.just(new ResponseEntity<>("添加成功", HttpStatus.CREATED));
}
/**
* 修改用户
*
* @param id
* @param user
* @return
*/
@PutMapping("/{id}")
public Mono<ResponseEntity<User>> putUser(@PathVariable Long id, User user) {
user.setId(id);
users.put(id, user);
return Mono.just(new ResponseEntity<>(user, HttpStatus.CREATED));
}
/**
* 删除用户
*
* @param id
* @return
*/
@DeleteMapping("/{id}")
public Mono<ResponseEntity<String>> deleteUser(@PathVariable Long id) {
users.remove(id);
return Mono.just(new ResponseEntity<>("删除成功", HttpStatus.ACCEPTED));
}
}
3、测试API功能
3.1、获取数据
启动项目后访问路径"http://localhost:8080/user/list"会得到两个初始化成功的数据。
[{"id":1,"name":"郭大狗","age":22},{"id":2,"name":"郭二狗","age":21}]
如果要得到id为1的对象信息,可以访问路径:"http://localhost:8080/user/1"
{"id":1,"name":"郭大狗","age":22}
3.2、修改数据
通过PUT方式进行数据的修改。
修改后的数据为
3.3、添加数据
通过POST方式提交了数据
可以查看:
3.4、删除数据
通过DELETE方式删除数据。
再看看目前的数据有多少,是否删除成功:
3、用响应式方式开发WebFlux
3.1、编写处理类Handler
Handler相当于MVC中的Controller,用于提供实现功能的方法。代码如下:
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
/**
* @Author:
* @License: (C) Copyright 2019-2029, wrwl Corporation Limited.
* @Date: 2020/12/17 14:09
* @Description: ::
*/
@Component
public class HelloWorldHandler {
public Mono<ServerResponse> sayHello(ServerRequest serverRequest) {
return ServerResponse.ok().contentType(MediaType.TEXT_PLAIN).body(Mono.just("This is WebFlux demo"), String.class);
}
}
3.2、编写路由器类Router
Router主要是提供路由映射,相当于MVC模式中的注解RequestMapping。
import com.zqj.handler.HelloWorldHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
/**
* @Author:
* @License: (C) Copyright 2019-2029, wrwl Corporation Limited.
* @Date: 2020/12/17 14:14
* @Description: ::
*/
@Configuration
public class Router {
@Autowired
private HelloWorldHandler helloWorldHandler;
@Bean
public RouterFunction<ServerResponse> getString(){
return route(GET("/helloworld"),req->helloWorldHandler.sayHello(req));
}
}
上诉代码中,通过 return route(GET("/helloworld"),req->helloWorldHandler.sayHello(req));来指定路由,baohanHTTP方法和对应的功能方法。
3.3、启动类
@SpringBootApplication
public class WebFluxApplication {
public static void main(String[] args) {
SpringApplication.run(WebFluxApplication.class,args);
}
}
整体启动即可。
4、用WebFlux模式操作MongoDB数据库,实现对数据库的增删改查
4.1、添加依赖
要实现对数据库的操作,可以通过Springboot对MongoDB的依赖进行快速配置和操作。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>WebFluxMongodb</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
在配置文件中配置MongoDB地址信息(MongoDB2.4版本以上)
spring.data.mongodb.uri=mongodb://127.0.0.1:27017/test
格式如下:
spring.data.mongodb.uri=mongodb://用户名:密码@ip地址:端口号/数据库
4.2、创建实体
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@Id
private String id;
// 为name创建索引,如果需要值唯一,则设置@Indexed(unique = true)。
private String name;
private int age;
}
4.3、编写接口
Spring Boot 的Starter 提供了ReactiveMongoRepository接口,用于操作Mongo数据库:
public interface UserRepository extends ReactiveMongoRepository<User,String> {
}
4.4、编写API
通过用WebFlux模式操作数据的API,具体参考以下代码:
@RestController
@RequestMapping(path = "/user")
public class UserController {
@Autowired
private UserRepository userRepository;
@GetMapping(value = "/list")
public Flux<User> getAll() {
return userRepository.findAll();
}
//启动测试就可以发现查询是一个一个出来的,而不是一下返回。
@GetMapping(value = "/listdelay", produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
public Flux<User> getAlldelay() {
return userRepository.findAll().delayElements(Duration.ofSeconds(1));
}
@GetMapping("/{id}")
public Mono<ResponseEntity<User>> getUser(@PathVariable String id) {
return userRepository.findById(id)
.map(getUser -> ResponseEntity.ok(getUser))
.defaultIfEmpty(ResponseEntity.notFound().build());
}
@PostMapping("")
public Mono<User> createUser(@Valid User user) {
return userRepository.save(user);
}
@PutMapping("/{id}")
public Mono updateUser(@PathVariable(value = "id") String id,
@Valid User user) {
return userRepository.findById(id)
.flatMap(existingUser -> {
existingUser.setName(user.getName());
return userRepository.save(existingUser);
})
.map(updateUser -> new ResponseEntity<>(updateUser, HttpStatus.OK))
.defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
@DeleteMapping("/{id}")
public Mono<ResponseEntity<Void>> deleteUser(@PathVariable(value = "id") String id) {
return userRepository.findById(id)
.flatMap(existingUser ->
userRepository.delete(existingUser)
.then(Mono.just(new ResponseEntity<Void>(HttpStatus.OK)))
)
.defaultIfEmpty(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
}
4.5、启动类编写
@ComponentScan(basePackages = {"com.example.*"}) //根据自己配置来添加
@EnableReactiveMongoRepositories
@SpringBootApplication
public class WebFluxMongodbApplication {
public static void main(String[] args) {
SpringApplication.run(WebFluxMongodbApplication.class, args);
}
}
代码解释如下:
- produces = MediaType.APPLICATION_ STREAM_ JSON_ VALUE:这里媒体类型必须是APPLICATION_ STREAM JSON_ _VALUE,否则调用端无法滚动得到结果,将一直阻塞直到数据流结束或超时。
- Duration.ofSeconds(1): 代表一 秒-秒地返回数据,而不是下 全部返回。
- ResponseEntity.ok: ResponseEntity继承了HttpEntity, 是HttpEntity的子类,且可以添加HttpStatus状态码。
- flatMap: 返回的是迭代器中的元素。
- HttpStatus.NOT_ FOUND:代表HTTP状态是404,表示没有找到。
- HttpStatus.OK: 代表HTTP状态是200,表示处理成功。
结尾:
做了两年开发,发现对Spring Boot 的认知上缺少了很多东西。因此想重新认识 Spring Boot 框架 仅此而已。