gateway限制资源图片上传大小问题

问题:org.springframework.core.io.buffer.DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144
    at org.springframework.core.io.buffer.LimitedDataBufferList.raiseLimitException(LimitedDataBufferList.java:98)
    at org.springframework.core.io.buffer.LimitedDataBufferList.updateCount(LimitedDataBufferList.java:91)
    at org.springframework.core.io.buffer.LimitedDataBufferList.add(LimitedDataBufferList.java:57)
    at reactor.core.publisher.MonoCollect$CollectSubscriber.onNext(MonoCollect.java:118)
    at reactor.core.publisher.Operators$MonoSubscriber.complete(Operators.java:1816)

解决方案:

spring:
  codec:
    max-in-memory-size: 50MB

@Component
@Slf4j
public class GwReadBodyRoutePredicateFactory extends
        AbstractRoutePredicateFactory<GwReadBodyRoutePredicateFactory.Config> {

    private static final String TEST_ATTRIBUTE = "read_body_predicate_test_attribute";

    private static final String CACHE_REQUEST_BODY_OBJECT_KEY = "cachedRequestBodyObject";

    private final List<HttpMessageReader<?>> messageReaders;

    /**
     * 获取Spring配置,解决最大body问题
     */
    @Autowired
    ServerCodecConfigurer codecConfigurer;

    public GwReadBodyRoutePredicateFactory() {
        super(GwReadBodyRoutePredicateFactory.Config.class);
        this.messageReaders = HandlerStrategies.withDefaults().messageReaders();
    }

    public GwReadBodyRoutePredicateFactory(List<HttpMessageReader<?>> messageReaders) {
        super(GwReadBodyRoutePredicateFactory.Config.class);
        this.messageReaders = messageReaders;
    }

    @Override
    @SuppressWarnings("unchecked")
    public AsyncPredicate<ServerWebExchange> applyAsync(
            GwReadBodyRoutePredicateFactory.Config config
    ) {
        return new AsyncPredicate<ServerWebExchange>() {
            @Override
            public Publisher<Boolean> apply(ServerWebExchange exchange) {
                Class inClass = config.getInClass();

                Object cachedBody = exchange.getAttribute(CACHE_REQUEST_BODY_OBJECT_KEY);
                Mono<?> modifiedBody;
                // We can only read the body from the request once, once that happens if
                // we try to read the body again an exception will be thrown. The below
                // if/else caches the body object as a request attribute in the
                // ServerWebExchange so if this filter is run more than once (due to more
                // than one route using it) we do not try to read the request body
                // multiple times
                if (cachedBody != null) {
                    try {
                        boolean test = config.predicate.test(cachedBody);
                        exchange.getAttributes().put(TEST_ATTRIBUTE, test);
                        return Mono.just(test);
                    } catch (ClassCastException e) {
                        if (log.isDebugEnabled()) {
                            log.debug("Predicate test failed because class in predicate "
                                    + "does not match the cached body object", e);
                        }
                    }
                    return Mono.just(false);
                } else {
                    return ServerWebExchangeUtils.cacheRequestBodyAndRequest(exchange,
                            (serverHttpRequest) -> ServerRequest.create(
                                            exchange.mutate().request(serverHttpRequest).build(), codecConfigurer.getReaders())
                                    .bodyToMono(inClass)
                                    .doOnNext(objectValue -> exchange.getAttributes()
                                            .put(CACHE_REQUEST_BODY_OBJECT_KEY, objectValue))
                                    .map(objectValue -> config.getPredicate().test(objectValue))
                                    .thenReturn(true));
                }
            }

            @Override
            public String toString() {
                return String.format("ReadBody: %s", config.getInClass());
            }
        };
    }

    @Override
    @SuppressWarnings("unchecked")
    public Predicate<ServerWebExchange> apply(
            GwReadBodyRoutePredicateFactory.Config config
    ) {
        throw new UnsupportedOperationException("GwReadBodyPredicateFactory is only async.");
    }

    public static class Config {

        private Class inClass;

        private Predicate predicate;

        private Map<String, Object> hints;

        public Class getInClass() {
            return inClass;
        }

        public GwReadBodyRoutePredicateFactory.Config setInClass(Class inClass) {
            this.inClass = inClass;
            return this;
        }

        public Predicate getPredicate() {
            return predicate;
        }

        public GwReadBodyRoutePredicateFactory.Config setPredicate(Predicate predicate) {
            this.predicate = predicate;
            return this;
        }

        public <T> GwReadBodyRoutePredicateFactory.Config setPredicate(Class<T> inClass, Predicate<T> predicate) {
            setInClass(inClass);
            this.predicate = predicate;
            return this;
        }

        public Map<String, Object> getHints() {
            return hints;
        }

        public GwReadBodyRoutePredicateFactory.Config setHints(Map<String, Object> hints) {
            this.hints = hints;
            return this;
        }
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值