首页 > 解决方案 > spring webflux中带有多部分数据的POST请求

问题描述

当我为我的应用程序添加安全性时,我正在使用 spring webflux,在控制器中可以找到关于 POST 请求的多部分或有效负载数据,您可以在我的安全配置类和我的自定义 webfilter 类下面找到

 import java.util.Collections;
    
        import org.springframework.context.annotation.Bean;
        import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity;
        import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
        import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
        import org.springframework.security.config.web.server.ServerHttpSecurity;
        import org.springframework.security.web.server.SecurityWebFilterChain;
        import org.springframework.security.web.server.csrf.CookieServerCsrfTokenRepository;
        import org.springframework.web.cors.CorsConfiguration;
        import org.springframework.web.cors.reactive.CorsConfigurationSource;
        import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;
        
        @EnableWebFluxSecurity 
        @EnableReactiveMethodSecurity 
        public class SecurityConfiguration {
        
            @Bean
            public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
                // @formatter:off
                return http
                        .csrf()
                            .csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse()) 
                            .and().addFilterBefore( new CustomWebFilter(), SecurityWebFiltersOrder.ANONYMOUS_AUTHENTICATION)
                        .authorizeExchange()
                            .pathMatchers("/ws/**").permitAll() 
                            .anyExchange().authenticated()
                            .and()
                        .oauth2Login()
                            .and()
                        .oauth2ResourceServer()
                            .jwt().and().and().build();
                // @formatter:on
            }
        
            @Bean 
            CorsConfigurationSource corsConfigurationSource() {
                CorsConfiguration configuration = new CorsConfiguration();
                configuration.setAllowCredentials(true);
                configuration.setAllowedOrigins(Collections.singletonList("http://localhost:4200"));
                configuration.addAllowedMethod(CorsConfiguration.ALL);
                configuration.setAllowedHeaders(Collections.singletonList("*"));
                UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
                source.registerCorsConfiguration("/**", configuration);
                return source;
            }
        }
    

这是我的自定义 webfilter 类我为多部分过滤器制作了一个自定义过滤器,以将其集成到 spring 安全链中,但问题是过滤器是基于 servlet

  import org.springframework.core.Ordered;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
    import org.springframework.web.multipart.support.MultipartFilter;
    import org.springframework.web.server.ServerWebExchange;
    import org.springframework.web.server.WebFilter;
    import org.springframework.web.server.WebFilterChain;
    
    import lombok.extern.slf4j.Slf4j;
    import reactor.core.publisher.Mono;
    
    @Component
    @Order(Ordered.HIGHEST_PRECEDENCE)
    @Slf4j
    public class CustomWebFilter implements WebFilter {
    
      @Override
      public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        log.info("My Custom Web Filter.");
        new MultipartFilter();//java.lang.NoClassDefFoundError: javax/servlet/Filter
        return chain.filter(exchange);
      }
    }

这是我调用控制器保存文件时引发的原始错误

{ “时间戳”:“2021-04-01T17:17:26.373+00:00”,“路径”:“/users/addPhoto/60648bfa9b3b60106bdabc93”,“状态”:400,“错误”:“错误请求”,“ message”:“所需的 MultipartFile 参数 'file' 不存在”,“requestId”:“a763eee0-16”,“trace”:“org.springframework.web.server.ServerWebInputException:400 BAD_REQUEST “所需的 MultipartFile 参数 'file' 是在 org.springframework.web.reactive.result.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:114) 处不存在” 已抑制:reactor.core.publisher.FluxOnAssembly$OnAssemblyException:在以下站点观察到错误): |_ 检查点 ⇢ org.springframework.security.web。server.authorization.AuthorizationWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.authorization.ExceptionTranslationWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.authentication.logout.LogoutWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.savedrequest.ServerRequestCacheWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.context.SecurityContextServerWebExchangeWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security。 web.server.ui.LogoutPageGeneratingWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.ui.LoginPageGeneratingWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ tn.talan.cra.security。CustomWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.config.web.server.ServerHttpSecurity$OAuth2ResourceServerSpec$BearerTokenAuthenticationWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.oauth2.client.web.server.authentication.OAuth2LoginAuthenticationWebFilter [ DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.oauth2.client.web.server.OAuth2AuthorizationRequestRedirectWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.context.ReactorContextWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org. springframework.security.web.server.csrf.CsrfWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.web.cors.reactive.CorsWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.header。HttpHeaderWriterWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.config.web.server.ServerHttpSecurity$ServerWebExchangeReactorContextWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ org.springframework.security.web.server.WebFilterChainProxy [DefaultWebFilterChain] |_ checkpoint ⇢ tn. talan.cra.security.CustomWebFilter [DefaultWebFilterChain] |_ checkpoint ⇢ HTTP POST "/users/addPhoto/60648bfa9b3b60106bdabc93" [ExceptionHandlingWebHandler] 堆栈跟踪:在 org.springframework.web.reactive.result.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver .java:114) 在 org.springframework.web.reactive.result.method.annotation.AbstractNamedValueArgumentResolver.lambda$getDefaultValue$1(AbstractNamedValueArgumentResolver.java:215) 在 reactor.core.publisher。MonoSupplier.subscribe(MonoSupplier.java:56) 在 reactor.core.publisher.Mono.subscribe(Mono.java:4046) 在 reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:81) 在 reactor.core .publisher.Operators.complete(Operators.java:136) 在 reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:144) 在 reactor.core.publisher.MonoFlatMap.subscribeOrReturn(MonoFlatMap.java:53) 在反应堆。 core.publisher.Mono.subscribe(Mono.java:4031) 在 reactor.core.publisher.MonoZip.subscribe(MonoZip.java:128) 在 reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) 在 reactor .core.publisher.MonoDefer.subscribe(MonoDefer.java:52) 在 reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:154) 在 reactor.core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56) 在 reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) 在 reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157) 在 reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber .onNext(FluxSwitchIfEmpty.java:73) 在 reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82) 在 reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.innerNext(FluxConcatMap.java:281) 在反应堆。 core.publisher.FluxConcatMap$ConcatMapInner.onNext(FluxConcatMap.java:860) 在 reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:127) 在 reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onNext(MonoPeekTerminal. java:180) 在 reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2397) 在 reactor.core.publisher。MonoPeekTerminal$MonoTerminalPeekSubscriber.request(MonoPeekTerminal.java:139) 在 reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:169) 在 reactor.core.publisher.Operators$MultiSubscriptionSubscriber.set(Operators.java:2193)在 reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2067) 在 reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java:96) 在 reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onSubscribe (MonoPeekTerminal.java:152) 在 reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54) 在 reactor.core.publisher.Mono.subscribe(Mono.java:4046) 在 reactor.core.publisher.FluxConcatMap$在 reactor.core.publisher.FluxConcatMap$ConcatMapImmediate 的 ConcatMapImmediate.drain(FluxConcatMap.java:448)。onSubscribe(FluxConcatMap.java:218) 在 reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:164) 在 reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:86) 在 reactor.core.publisher.InternalMonoOperator .subscribe(InternalMonoOperator.java:64) 在 reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) 在 reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) 在 reactor.core.publisher。 Mono.subscribe(Mono.java:4046) 在 reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:81) 在 reactor.core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onComplete(MonoPeekTerminal.java:299) 在 reactor .core.publisher.MonoPeekTerminal$MonoTerminalPeekSubscriber.onComplete(MonoPeekTerminal.java:299) 在 reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:148) 在 reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:73) 在 reactor.core.publisher.FluxFilter$FilterSubscriber.onNext(FluxFilter.java:113) 在 reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber .onNext(FluxDefaultIfEmpty.java:100) 在 reactor.core.publisher.MonoNext$NextSubscriber.onNext(MonoNext.java:82) 在 reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.innerNext(FluxConcatMap.java:281) 在反应堆。 core.publisher.FluxConcatMap$ConcatMapInner.onNext(FluxConcatMap.java:860) 在 reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1815) 在 reactor.core.publisher.MonoFlatMap$FlatMapInner.onNext(MonoFlatMap. java:249) 在 reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.onNext(FluxDefaultIfEmpty.java:100) 在 reactor.core.publisher。FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:127) 在 reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onNext(FluxFilterFuseable.java:118) 在 reactor.core.publisher.FluxMapFuseable$MapFuseableConditionalSubscriber.onNext(FluxMapFuseable.java:295)在 reactor.core.publisher.FluxFilterFuseable$FilterFuseableConditionalSubscriber.onNext(FluxFilterFuseable.java:337) 在 reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1815) 在 reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext (MonoFlatMap.java:151) 在 reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onNext(FluxFilterFuseable.java:118) 在 reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2397) 在 reactor.core。 publisher.FluxFilterFuseable$FilterFuseableSubscriber.request(FluxFilterFuseable.java:191) 在 reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:110) 在 reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onSubscribe(FluxFilterFuseable.java:87) 在 reactor.core.publisher.MonoCurrentContext.subscribe (MonoCurrentContext.java:36) 在 reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) 在 reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157) 在 reactor.core.publisher。 FluxMapFuseable$MapFuseableSubscriber.onNext(FluxMapFuseable.java:127) 在 reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onNext(FluxFilterFuseable.java:118) 在 reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2397)在 reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.request(FluxFilterFuseable.java:191) 在 reactor.core。publisher.FluxMapFuseable$MapFuseableSubscriber.request(FluxMapFuseable.java:169) 在 reactor.core.publisher.MonoFlatMap$FlatMapMain.onSubscribe(MonoFlatMap.java:110) 在 reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onSubscribe(FluxMapFuseable.java: 96) 在 reactor.core.publisher.FluxFilterFuseable$FilterFuseableSubscriber.onSubscribe(FluxFilterFuseable.java:87) 在 reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54) 在 reactor.core.publisher.Mono.subscribe(Mono .java:4046) 在 reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.onSubscribe(FluxConcatMap.java:218) 在 reactor.core.publisher.reactor.core.publisher.FluxConcatMap$ConcatMapImmediate.drain(FluxConcatMap.java:448)。 FluxIterable.subscribe(FluxIterable.java:164) 在 reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:86) 在 reactor.core.publisher。InternalMonoOperator.subscribe(InternalMonoOperator.java:64) 在 reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:52) 在 reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) 在 reactor.core.publisher .MonoDefer.subscribe(MonoDefer.java:52) 在 reactor.core.publisher.Mono.subscribe(Mono.java:4046) 在 reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:173) 在反应堆。 core.publisher.MonoIgnoreThen.subscribe(MonoIgnoreThen.java:56) 在 reactor.core.publisher.Mono.subscribe(Mono.java:4046) 在 reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:81)在 reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:166) 在 reactor.core.publisher.FluxPeekFuseable$PeekConditionalSubscriber.onComplete(FluxPeekFuseable.java:940) 在 reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:84) 在 reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2399) 在 reactor.core.publisher.Operators$MultiSubscriptionSubscriber .set(Operators.java:2193) 在 reactor.core.publisher.Operators$MultiSubscriptionSubscriber.onSubscribe(Operators.java:2067) 在 reactor.core.publisher.MonoJust.subscribe(MonoJust.java:54) 在 reactor.core。发布者.Mono.subscribe(Mono.java:4046) 在 reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onComplete(FluxSwitchIfEmpty.java:81) 在 reactor.core.publisher.MonoNext$NextSubscriber.onComplete(MonoNext.java:102)在 reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:166) 在 reactor.core.publisher.FluxFlatMap$FlatMapMain.checkTerminated(FluxFlatMap.java:845) 在 reactor.core.publisher.FluxFlatMap$FlatMapMain.drainLoop(FluxFlatMap.java:607) 在 reactor.core.publisher.FluxFlatMap$FlatMapMain.drain(FluxFlatMap.java:587) 在 reactor.core.publisher.FluxFlatMap$FlatMapMain .onComplete(FluxFlatMap.java:464) 在 reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onComplete(FluxPeekFuseable.java:277) 在 reactor.core.publisher.FluxIterable$IterableSubscription.slowPath(FluxIterable.java:292) 在反应堆。 core.publisher.FluxIterable$IterableSubscription.request(FluxIterable.java:228) 在 reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.request(FluxPeekFuseable.java:144) 在 reactor.core.publisher.FluxFlatMap$FlatMapMain.onSubscribe(FluxFlatMap. java:370) 在 reactor.core.publisher.FluxPeekFuseable$PeekFuseableSubscriber.onSubscribe(FluxPeekFuseable.java:178) 在 reactor.core.publisher。FluxIterable.subscribe(FluxIterable.java:164) 在 reactor.core.publisher.FluxIterable.subscribe(FluxIterable.java:86) 在 reactor.core.publisher.InternalMonoOperator.subscribe(InternalMonoOperator.java:64) 在 reactor.core.publisher .MonoDefer.subscribe(MonoDefer.java:52) 在 reactor.core.publisher.MonoFlatMap$FlatMapMain.onNext(MonoFlatMap.java:157) 在 reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1815) 在reactor.core.publisher.FluxDefaultIfEmpty$DefaultIfEmptySubscriber.onComplete(FluxDefaultIfEmpty.java:108) 在 reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:142) 在 reactor.core.publisher.FluxMap$MapSubscriber.onComplete( FluxMap.java:142) 在 reactor.core.publisher.FluxFilter$FilterSubscriber.onComplete(FluxFilter.java:166) 在 reactor.core.publisher.FluxMap$MapConditionalSubscriber.onComplete(FluxMap.java:269) 在 reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1816) 在 reactor.core.publisher.MonoCacheTime$CoordinatorSubscriber.signalCached(MonoCacheTime.java:328) 在 reactor.core.publisher.MonoCacheTime $CoordinatorSubscriber.onNext(MonoCacheTime.java:345) 在 reactor.core.publisher.FluxPeek$PeekSubscriber.onNext(FluxPeek.java:199) 在 reactor.core.publisher.FluxSwitchIfEmpty$SwitchIfEmptySubscriber.onNext(FluxSwitchIfEmpty.java:73) 在reactor.core.publisher.FluxSubscribeOnCallable$CallableSubscribeOnSubscription.run(FluxSubscribeOnCallable.java:251) 在 reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java:68) 在 reactor.core.scheduler.SchedulerTask.call(SchedulerTask.java: 28) 在 java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) 在 java.base/java.util.concurrent。ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run( ThreadPoolExecutor.java:630) 在 java.base/java.lang.Thread.run(Thread.java:832)" }

这是我的控制器代码

@PostMapping("/users/addPhoto/{id}")
    public Mono<User> addPhoto(@RequestParam MultipartFile file,@PathVariable String id) throws IOException { 
        return userService.findById(id).flatMap(user->{
            try {
                user.setPhoto(new Binary(BsonBinarySubType.BINARY, file.getBytes()));
            return  userService.save(user);
            } catch (IOException e) {
                e.printStackTrace();
                return Mono.just(user);

            }
        });
        
    }

标签: spring-bootspring-securityspring-webfluxspring-restcontrollerspring5

解决方案


推荐阅读