From e96b71acf3af4df7d00270e93659ec1f00495fdc Mon Sep 17 00:00:00 2001 From: Oleh Faizulin Date: Sat, 4 Jan 2020 09:54:53 +0200 Subject: [PATCH 1/2] contentLength support for Resource decoding Expose the known content length, if known, in the InputStreamResource returned by ResourceHttpMessageConverter or ResourceDecoder. See gh-24292 --- .../core/codec/ResourceDecoder.java | 5 +++++ .../core/codec/ResourceDecoderTests.java | 18 ++++++++++++++++++ .../ResourceHttpMessageConverter.java | 5 +++++ .../ResourceHttpMessageConverterTests.java | 2 ++ 4 files changed, 30 insertions(+) diff --git a/spring-core/src/main/java/org/springframework/core/codec/ResourceDecoder.java b/spring-core/src/main/java/org/springframework/core/codec/ResourceDecoder.java index eeb307cfcdf9..b19e6f954500 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/ResourceDecoder.java +++ b/spring-core/src/main/java/org/springframework/core/codec/ResourceDecoder.java @@ -83,6 +83,11 @@ public Resource decode(DataBuffer dataBuffer, ResolvableType elementType, public String getFilename() { return filename; } + + @Override + public long contentLength() { + return bytes.length; + } }; } else if (Resource.class.isAssignableFrom(clazz)) { diff --git a/spring-core/src/test/java/org/springframework/core/codec/ResourceDecoderTests.java b/spring-core/src/test/java/org/springframework/core/codec/ResourceDecoderTests.java index 1c3a531f7a3e..3c129428f555 100644 --- a/spring-core/src/test/java/org/springframework/core/codec/ResourceDecoderTests.java +++ b/spring-core/src/test/java/org/springframework/core/codec/ResourceDecoderTests.java @@ -105,4 +105,22 @@ public void decodeToMono() { Collections.singletonMap(ResourceDecoder.FILENAME_HINT, "testFile")); } + @Test + public void decodeInputStreamResource() { + Flux input = Flux.concat(dataBuffer(this.fooBytes), dataBuffer(this.barBytes)); + testDecodeAll(input, InputStreamResource.class, step -> step + .consumeNextWith(resource -> { + try { + byte[] bytes = StreamUtils.copyToByteArray(resource.getInputStream()); + assertThat(new String(bytes)).isEqualTo("foobar"); + assertThat(resource.contentLength()).isEqualTo(fooBytes.length + barBytes.length); + } + catch (IOException ex) { + throw new AssertionError(ex.getMessage(), ex); + } + }) + .expectComplete() + .verify()); + } + } diff --git a/spring-web/src/main/java/org/springframework/http/converter/ResourceHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/ResourceHttpMessageConverter.java index 582ab859de16..3fd720831578 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/ResourceHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/ResourceHttpMessageConverter.java @@ -84,6 +84,11 @@ protected Resource readInternal(Class clazz, HttpInputMessag public String getFilename() { return inputMessage.getHeaders().getContentDisposition().getFilename(); } + + @Override + public long contentLength() { + return inputMessage.getHeaders().getContentLength(); + } }; } else if (Resource.class == clazz || ByteArrayResource.class.isAssignableFrom(clazz)) { diff --git a/spring-web/src/test/java/org/springframework/http/converter/ResourceHttpMessageConverterTests.java b/spring-web/src/test/java/org/springframework/http/converter/ResourceHttpMessageConverterTests.java index efc1163bd75f..082ec788ca31 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/ResourceHttpMessageConverterTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/ResourceHttpMessageConverterTests.java @@ -80,10 +80,12 @@ public void shouldReadInputStreamResource() throws IOException { inputMessage.getHeaders().setContentType(MediaType.IMAGE_JPEG); inputMessage.getHeaders().setContentDisposition( ContentDisposition.builder("attachment").filename("yourlogo.jpg").build()); + inputMessage.getHeaders().setContentLength(123); Resource actualResource = converter.read(InputStreamResource.class, inputMessage); assertThat(actualResource).isInstanceOf(InputStreamResource.class); assertThat(actualResource.getInputStream()).isEqualTo(body); assertThat(actualResource.getFilename()).isEqualTo("yourlogo.jpg"); + assertThat(actualResource.contentLength()).isEqualTo(123); } } From 01827389ef2e8297ff572ac3ffa8bb5e8ac604d8 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 8 Jan 2020 16:16:07 +0000 Subject: [PATCH 2/2] Polishing contribution See gh-24292 --- .../org/springframework/core/codec/ResourceDecoder.java | 3 +-- .../springframework/core/codec/ResourceDecoderTests.java | 7 ++----- .../http/converter/ResourceHttpMessageConverter.java | 8 ++++---- .../http/converter/ResourceHttpMessageConverterTests.java | 2 +- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/spring-core/src/main/java/org/springframework/core/codec/ResourceDecoder.java b/spring-core/src/main/java/org/springframework/core/codec/ResourceDecoder.java index b19e6f954500..4e9552a650a0 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/ResourceDecoder.java +++ b/spring-core/src/main/java/org/springframework/core/codec/ResourceDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -83,7 +83,6 @@ public Resource decode(DataBuffer dataBuffer, ResolvableType elementType, public String getFilename() { return filename; } - @Override public long contentLength() { return bytes.length; diff --git a/spring-core/src/test/java/org/springframework/core/codec/ResourceDecoderTests.java b/spring-core/src/test/java/org/springframework/core/codec/ResourceDecoderTests.java index 3c129428f555..f060ce4f3598 100644 --- a/spring-core/src/test/java/org/springframework/core/codec/ResourceDecoderTests.java +++ b/spring-core/src/test/java/org/springframework/core/codec/ResourceDecoderTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -82,10 +82,7 @@ public void decode() { @Override @Test public void decodeToMono() { - Flux input = Flux.concat( - dataBuffer(this.fooBytes), - dataBuffer(this.barBytes)); - + Flux input = Flux.concat(dataBuffer(this.fooBytes), dataBuffer(this.barBytes)); testDecodeToMonoAll(input, ResolvableType.forClass(Resource.class), step -> step .consumeNextWith(value -> { diff --git a/spring-web/src/main/java/org/springframework/http/converter/ResourceHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/ResourceHttpMessageConverter.java index 3fd720831578..f587aecf7ff9 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/ResourceHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/ResourceHttpMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -84,10 +84,10 @@ protected Resource readInternal(Class clazz, HttpInputMessag public String getFilename() { return inputMessage.getHeaders().getContentDisposition().getFilename(); } - @Override - public long contentLength() { - return inputMessage.getHeaders().getContentLength(); + public long contentLength() throws IOException { + long length = inputMessage.getHeaders().getContentLength(); + return (length != -1 ? length : super.contentLength()); } }; } diff --git a/spring-web/src/test/java/org/springframework/http/converter/ResourceHttpMessageConverterTests.java b/spring-web/src/test/java/org/springframework/http/converter/ResourceHttpMessageConverterTests.java index 082ec788ca31..5a05d431c792 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/ResourceHttpMessageConverterTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/ResourceHttpMessageConverterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License.