RouterFunction可以运行在servlet或netty上,所以我们需要将两个容器间的不同点抽象出来。
整个开发过程有几步:
1.HandleFunction,实现输入ServerRequest,输出ServerResponse
2.RouterFunction,把请求url和HandlerFunction对应起来
3.把RouterFunction包装成HttpHandler,交给容器Server处理。
代码:
实体类和仓库不变
handler:
@Component
public class UserHandler {
private final UserRepository repository;
public UserHandler(UserRepository repository) {
this.repository = repository;
}
public Mono<ServerResponse> getAllUser(ServerRequest request){
return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
.body(repository.findAll() , User.class);
}
public Mono<ServerResponse> createUser(ServerRequest request){
Mono<User> userMono = request.bodyToMono(User.class);
return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
.body(repository.saveAll(userMono) , User.class);
}
public Mono<ServerResponse> deleteUserById(ServerRequest request){
String id = request.pathVariable("id");
return this.repository.findById(id)
.flatMap(user -> this.repository.delete(user)
.then(ServerResponse.ok().build()))
.switchIfEmpty(ServerResponse.notFound().build());
}
}
router:
@Configuration
public class AllRouters {
@Bean
RouterFunction<ServerResponse> userRouter(UserHandler handler){
return RouterFunctions.nest(
//相当于requestMapping
RequestPredicates.path("/user") ,
RouterFunctions.route(RequestPredicates.GET("/") , handler::getAllUser)
.andRoute(RequestPredicates.POST("/").and(RequestPredicates.accept(MediaType.APPLICATION_JSON)) , handler::createUser)
.andRoute(RequestPredicates.DELETE("/{id}") , handler::deleteUserById));
}
}
接下来看看routerFunction下的参数校验:
改造下代码(这里只写一个做例子)
public Mono<ServerResponse> createUser(ServerRequest request){
Mono<User> userMono = request.bodyToMono(User.class);
return userMono.flatMap(user -> {
//在这里做校验
//xxx
return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
.body(repository.saveAll(userMono) , User.class);
});
}
异常捕获,用aop的方式:
@Component
@Order(-99)
public class ExceptionHandler implements WebExceptionHandler {
@Override
public Mono<Void> handle(ServerWebExchange serverWebExchange, Throwable throwable) {
ServerHttpResponse response = serverWebExchange.getResponse();
response.setStatusCode(HttpStatus.BAD_REQUEST);
response.getHeaders().setContentType(MediaType.TEXT_PLAIN);
String errorMsg = toStr(throwable);
DataBuffer db = response.bufferFactory().wrap(errorMsg.getBytes());
return response.writeWith(Mono.just(db));
}
private String toStr(Throwable throwable) {
//已知异常,自定义异常,这里懒得写了,就随便找一个代替
if (throwable instanceof NumberFormatException){
NumberFormatException e = (NumberFormatException) throwable;
return e.getMessage();
}
//未知异常
else {
throwable.printStackTrace();
return throwable.toString();
}
}
}