spring webmvc转webflux的事项

本文主要讲述从Spring MVC转到Spring WebFlux时遇到的配置问题,包括web、全局异常、统一返回、共享会话、swagger、shiro等方面的配置更改,还提到webflux中可通过WebFilter实现拦截。此外,作者在API网关选取上,因springcloud gateway坑多,转换成本大而纠结。

1、web的配置
原来mvc是引入WebMvcConfigurer ,需改成WebFluxConfigurer
注解EnableWebMvc改成EnableWebFlux

2、全局异常的配置

webflux有提供异常处理类,但也保留支持注解:ControllerAdvice,RestControllerAdvice等。

Component
public class ExceptionHandlerAdvice  implements WebExceptionHandler {

    /**
     * Handle the given exception. A completion signal through the return value
     * indicates error handling is complete while an error signal indicates the
     * exception is still not handled.
     *
     * @param exchange the current exchange
     * @param ex       the exception to handle
     * @return {@code Mono<Void>} to indicate when exception handling is complete
     */
    @Override
    public Mono<Void> handle(final ServerWebExchange exchange, final Throwable ex) {
        return handle(ex).flatMap(it -> it.writeTo(exchange,
                new HandlerStrategiesResponseContext(HandlerStrategies.withDefaults())))
                .flatMap(i -> Mono.empty());
    }


    private Mono<ServerResponse> handle(Throwable ex) {
        return createResponse(INTERNAL_SERVER_ERROR,   ex);
    }

    private Mono<ServerResponse> createResponse(final HttpStatus httpStatus, Throwable ex) {
        ErrorResponseData data = new ErrorResponseData();
        data.setCode(HttpCode.INTERNAL_SERVER_ERROR);
        data.setMsg(ex.getMessage());
        data.setStackMsg(ExceptionUtils.getStackTrace(ex));
        return ServerResponse.status(httpStatus).syncBody(data);
    }

    /**
     * The type Handler strategies response context.
     */
    static class HandlerStrategiesResponseContext implements ServerResponse.Context {

        private HandlerStrategies handlerStrategies;

        /**
         * Instantiates a new Handler strategies response context.
         *
         * @param handlerStrategies the handler strategies
         */
        public HandlerStrategiesResponseContext(final HandlerStrategies handlerStrategies) {
            this.handlerStrategies = handlerStrategies;
        }

        /**
         * Return the {@link HttpMessageWriter}s to be used for response body conversion.
         *
         * @return the list of message writers
         */
        @Override
        public List<HttpMessageWriter<?>> messageWriters() {
            return this.handlerStrategies.messageWriters();
        }

        /**
         * Return the  {@link ViewResolver}s to be used for view name resolution.
         *
         * @return the list of view resolvers
         */
        @Override
        public List<ViewResolver> viewResolvers() {
            return this.handlerStrategies.viewResolvers();
        }
    }


}

3、统一返回配置

  • webflux做不到统一返回的配置,因为他不知道你需要返回的是Flux还是Mono
  • 共享会话配置
    原来的公享会话配置为
@Configuration
@EnableRedisHttpSession
public class RedisSessionConfig {
    @Bean
    public static ConfigureRedisAction configureRedisAction() {
        return ConfigureRedisAction.NO_OP;
    }

    @Bean
    public HeaderHttpSessionIdResolver httpSessionStrategy() {
        return new HeaderHttpSessionIdResolver("x-auth-token");
    }
}

需要改为

@Configuration
@EnableRedisWebSession
public class RedisSessionConfig {
    @Bean
    public static ConfigureRedisAction configureRedisAction() {
        return ConfigureRedisAction.NO_OP;
    }

    @Bean
    public HeaderHttpSessionIdResolver httpSessionStrategy() {
        return new HeaderHttpSessionIdResolver("x-auth-token");
    }
}

只是换个注解

4、swagger配置

很可惜的说一句,swagger不支持webflux,官方不支持,没办法。
后来在寻求解决办法时,我在github发现在有人定制了springfox-spring-webflux,但这个jar我下载不了,各位有兴趣可以看看

5、shiro配置
最可惜的是shiro不支持webflux,我现在项目转成webflux,无法使用。
有人建议我转成security,但考虑成本,只能放弃!

 

6、interceptor实现,拦截HandlerMethod

webflux已经没有了Interceptor的概念,但是可以通过WebFilter的方式实现

@Component
public class CustomWebFilter implements WebFilter {

    @Autowired
    private RequestMappingHandlerMapping requestMappingHandlerMapping;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        Object handlerMethod = requestMappingHandlerMapping.getHandler(exchange).toProcessor().peek();
        //注意跨域时的配置,跨域时浏览器会先发送一个option请求,这时候getHandler不会时真正的HandlerMethod
        if(handlerMethod instanceof HandlerMethod){
            Valid valid = ((HandlerMethod) handlerMethod).getMethodAnnotation(Valid.class);
            //do your logic
        }
        //preprocess()
        Mono<Void> response = chain.filter(exchange);
        //postprocess()
        return response;
    }
}

转载链接:https://www.jianshu.com/p/96039cfddbda
 

总之这几天在搞API网关,一开始想用springcloud gateway,但坑太多了,要从spring mvc转到spring webflux就走了很多的弯路,成本有点大,最后下面链接探讨有关springcloud--网关的选取,仁者见仁,智者见智吧

https://www.jianshu.com/p/0acf308cf59a

 

 

### Spring Boot Starter WebFluxSpring MVC 的功能对比 #### 功能特性比较 Spring Boot 提供了两种不同的编程模型来构建 HTTP 响应式应用程序:基于注解的传统 Spring MVC 和响应式的 WebFlux。 - **同步 vs 非阻塞异步** Spring MVC 是一种传统的、基于 Servlet API 实现的服务器端技术,它采用线程每请求的方式处理客户端请求。这种方式对于大多数场景来说已经足够好,但在高并发环境下可能会遇到性能瓶颈[^2]。 相较之下,WebFlux 则是一个完全非阻塞的框架,能够更好地利用现代多核 CPU 架构的优势,在面对大量短时间内的突发流量时表现更佳。其内部实现不依赖于 Java EE Servlet 容器,而是通过 Netty 或 Undertow 这样的反应堆模式网络库来进行事件驱动 I/O 操作[^1]。 - **API 设计风格** 尽管两者都支持函数式编程接口(Functional Endpoints),但主流还是控制器类方式编写 RESTful 接口。值得注意的是,虽然它们共享相同的注解集(如 `@RestController`),然而底层机制却有所不同——MVC 使用反射调用方法执行业务逻辑;而 Flux 中的方法会返回 Mono/Flux 类型的对象表示潜在的数据流操作序列。 - **生态系统兼容性** 对于现有系统的迁移而言,由于历史原因以及社区贡献者的努力,围绕着 Spring MVC 形成了庞大的插件生态体系,包括但不限于各种安全认证方案集成、缓存管理工具链等。相比之下,尽管官方也在积极推广和完善 WebFlux 生态圈建设,但是目前可用资源相对较少一些[^3]。 ```java // 示例代码展示如何定义一个简单的REST Controller使用Spring MVC @RestController public class HelloController { @GetMapping("/hello") public String hello() { return "Hello, world!"; } } // 同样地,这里有一个类似的例子展示了怎样创建相同功能的服务程序片段借助Reactor核心概念之一Publisher<T> @Controller public class ReactiveGreetingHandler implements HandlerFunction<ServerResponse> { private static final Logger log = LoggerFactory.getLogger(ReactiveGreetingHandler.class); @Override public Mono<ServerResponse> handle(ServerRequest request) { return ServerResponse.ok().body(Mono.just("Hello, reactive world!"), String.class); } } ``` #### 性能考量 当涉及到具体应用场景的选择时,如果项目主要关注点在于低延迟和高效处理大规模连接,则应该优先考虑选用 WebFlux 来替代传统意义上的 Spring MVC 。不过需要注意的是,这并不意味着前者一定优于后者 —— 许多实际生产环境中的工作负载可能并不会从这种变中受益太多甚至反而增加了不必要的复杂度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值