1. 路由和过滤器:
WebFlux提供了一套功能强大的路由和过滤器机制,用于处理HTTP请求和响应。您可以使用RouterFunctions类来定义路由规则,并使用Filter类来创建过滤器链。以下是一个简单的示例:
@Bean
public RouterFunction<ServerResponse> route(UserHandler userHandler) {
return RouterFunctions.route()
.GET("/users", userHandler::getAllUsers)
.POST("/users", userHandler::createUser)
.GET("/users/{id}", userHandler::getUserById)
.PUT("/users/{id}", userHandler::updateUser)
.DELETE("/users/{id}", userHandler::deleteUser)
.build();
}
@Bean
public HandlerFilterFunction<ServerResponse, ServerResponse> loggingFilter() {
return (request, next) -> {
log.info("Request: {}", request.path());
return next.handle(request);
};
}
在上面的示例中,我们使用RouterFunctions定义了一组路由规则,并将它们映射到相应的处理函数。我们还定义了一个过滤器函数,用于记录请求的路径。
2. 响应式数据访问:
使用WebFlux,您可以使用响应式数据访问库(例如Spring Data R2DBC或Project Reactor)来处理数据库访问和其他外部数据源。这使您能够以非阻塞的方式进行数据访问操作。以下是一个示例:
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public Flux<User> getAllUsers() {
return userRepository.findAll();
}
public Mono<User> getUserById(String id) {
return userRepository.findById(id);
}
public Mono<User> createUser(User user) {
return userRepository.save(user);
}
public Mono<User> updateUser(String id, User user) {
return userRepository.findById(id)
.flatMap(existingUser -> {
existingUser.setName(user.getName());
return userRepository.save(existingUser);
});
}
public Mono<Void> deleteUser(String id) {
return userRepository.deleteById(id);
}
}
在上面的示例中,UserService使用响应式的UserRepository来处理与数据库的交互。它定义了一组方法,用于执行不同的数据访问操作。
3. 文件上传和下载:
WebFlux提供了内置的功能来处理文件上传和下载。您可以使用MultipartResolver类来处理文件上传,并使用ServerResponse类来生成文件下载的响应。以下是一个简单的示例:
@Bean
public RouterFunction<ServerResponse> fileRouter(FileHandler fileHandler) {
return RouterFunctions.route()
.POST("/upload", fileHandler::handleFileUpload)
.GET("/download/{filename}", fileHandler::handleFileDownload)
.build();
}
@Component
public class FileHandler {
public Mono<ServerResponse> handleFileUpload(ServerRequest request) {
return request.body(BodyExtractors.toMultipartData())
.flatMap(part -> {
// 处理文件上传逻辑
return ServerResponse.ok().build();
});
}
public Mono<ServerResponse> handleFileDownload(ServerRequest request) {
String filename = request.pathVariable("filename");
// 处理文件下载逻辑
return ServerResponse.ok()
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(/* file content */);
}
}
在上面的示例中,我们定义了一个文件处理器(FileHandler),它包含了处理文件上传和下载的方法。使用RouterFunctions,我们将这些方法映射到相应的URL路径。
4. 响应式验证:
使用WebFlux,您可以轻松地实现响应式验证逻辑。您可以使用Spring的@Validated
和@Valid
注解结合Validator
接口来执行输入验证。以下是一个示例:
@RestController
public class UserController {
private final UserService userService;
public UserController(UserService userService) {
this.userService = userService;
}
@PostMapping("/users")
public Mono<User> createUser(@Valid @RequestBody User user) {
return userService.createUser(user);
}
}
在上面的示例中,createUser
方法使用@Valid
注解对User
对象进行验证。如果验证失败,将抛出MethodArgumentNotValidException
异常。
5. 响应式安全性:
WebFlux提供了一套强大的安全性框架,使您能够轻松地保护您的响应式Web应用程序。您可以使用Spring Security来实现身份验证和授权。以下是一个示例:
@Configuration
public class SecurityConfig {
@Bean
public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
return http
.authorizeExchange()
.pathMatchers("/admin/**").hasRole("ADMIN")
.pathMatchers("/**").permitAll()
.and()
.httpBasic()
.and()
.build();
}
@Bean
public MapReactiveUserDetailsService userDetailsService() {
UserDetails user = User.withDefaultPasswordEncoder()
.username("user")
.password("password")
.roles("USER")
.build();
UserDetails admin = User.withDefaultPasswordEncoder()
.username("admin")
.password("password")
.roles("ADMIN")
.build();
return new MapReactiveUserDetailsService(user, admin);
}
}
在上面的示例中,我们定义了一个安全配置类,配置了URL路径的访问规则和用户信息。/admin/**
路径需要具有"ADMIN"角色的用户才能访问,而其他路径则允许所有用户访问。
6. Server-Sent Events (SSE):
WebFlux支持Server-Sent Events,这是一种用于实现服务器向客户端推送事件的技术。您可以使用WebFlux的SseEmitter
来创建SSE端点,并使用Flux
来生成事件流。以下是一个示例:
@RestController
public class EventController {
@GetMapping("/events")
public SseEmitter getEvents() {
SseEmitter emitter = new SseEmitter();
Flux.interval(Duration.ofSeconds(1))
.map(sequence -> new Event("Event " + sequence))
.doOnNext(event -> {
try {
emitter.send(event);
} catch (IOException e) {
emitter.completeWithError(e);
}
})
.doOnComplete(emitter::complete)
.subscribe();
return emitter;
}
}
在上面的示例中,getEvents
方法返回一个SseEmitter
对象,它用于向客户端推送事件。使用Flux
和interval
操作符,我们生成一个每秒发送一个事件的事件流,并将事件发送到SseEmitter
。