Repository: vaadin/flow
Pull request #21418: chore: deprecate StreamResource api
Author: login: caalador
Labels: name: +0.1.0
Created: 2025-05-12T11:10:57Z | Merged: 2025-05-13T06:45:52Z

Mark StreamResource api as deprecated
and point to Upload-/DownloadHandler
instead.

part of #21414



Diff:
diff --git a/flow-html-components/src/main/java/com/vaadin/flow/component/html/Anchor.java b/flow-html-components/src/main/java/com/vaadin/flow/component/html/Anchor.java
index 84a1147a75b..7582176a86a 100644
--- a/flow-html-components/src/main/java/com/vaadin/flow/component/html/Anchor.java
+++ b/flow-html-components/src/main/java/com/vaadin/flow/component/html/Anchor.java
@@ -105,7 +105,10 @@ public Anchor(String href, String text, AnchorTarget target) {
      *            the resource value, not null
      * @param text
      *            the text content to set
+     *
+     * @deprecated use {@link #Anchor(DownloadHandler, String)} instead
      */
+    @Deprecated(since = "24.8", forRemoval = true)
     public Anchor(AbstractStreamResource href, String text) {
         setHref(href);
         setText(text);
@@ -133,7 +136,7 @@ public Anchor(DownloadHandler downloadHandler, String text) {
      * Creates an anchor component with the given href and components as
      * children of this component.
      *
-     * @see #setHref(AbstractStreamResource)
+     * @see #setHref(DownloadHandler)
      * @see #add(Component...)
      *
      * @param href
@@ -156,7 +159,7 @@ public Anchor(String href, Component... components) {
      * instead of setting it to an empty string.
      *
      * @see #removeHref()
-     * @see #setHref(AbstractStreamResource)
+     * @see #setHref(DownloadHandler)
      *
      * @param href
      *            the href to set
@@ -186,7 +189,9 @@ public void removeHref() {
      *
      * @param href
      *            the resource value, not null
+     * @deprecated use {@link #setHref(DownloadHandler)} instead
      */
+    @Deprecated(since = "24.8", forRemoval = true)
     public void setHref(AbstractStreamResource href) {
         this.href = href;
         setRouterIgnore(true);
diff --git a/flow-html-components/src/main/java/com/vaadin/flow/component/html/HtmlObject.java b/flow-html-components/src/main/java/com/vaadin/flow/component/html/HtmlObject.java
index 661da0c8712..51e1be4fea9 100644
--- a/flow-html-components/src/main/java/com/vaadin/flow/component/html/HtmlObject.java
+++ b/flow-html-components/src/main/java/com/vaadin/flow/component/html/HtmlObject.java
@@ -104,7 +104,9 @@ public HtmlObject(String data, String type, Param... params) {
      *            the resource value, not null
      * @param type
      *            a type attribute value
+     * @deprecated use {@link #HtmlObject(DownloadHandler,String)} instead
      */
+    @Deprecated(since = "24.8", forRemoval = true)
     public HtmlObject(AbstractStreamResource data, String type) {
         setData(data);
         setType(type);
@@ -125,7 +127,10 @@ public HtmlObject(AbstractStreamResource data, String type) {
      *            a type attribute value
      * @param params
      *            parameter components
+     * @deprecated use {@link #HtmlObject(DownloadHandler,String, Param...)}
+     *             instead
      */
+    @Deprecated(since = "24.8", forRemoval = true)
     public HtmlObject(AbstractStreamResource data, String type,
             Param... params) {
         setData(data);
@@ -138,7 +143,7 @@ public HtmlObject(AbstractStreamResource data, String type,
      * {@link DownloadHandler} callback for providing an object data and type
      * value.
      *
-     * @see #setData(AbstractStreamResource)
+     * @see #setData(DownloadHandler)
      * @see #setType(String)
      *
      * @param data
@@ -174,6 +179,45 @@ public HtmlObject(DownloadHandler data, String type, Param... params) {
         add(params);
     }
 
+    /**
+     * Creates a new <code>&lt;object&gt;</code> component with given data
+     * resource, type value and "param" components.
+     *
+     * @see #setData(String)
+     * @see #setType(String)
+     * @see #add(Component...)
+     *
+     *
+     * @param data
+     *            a handler that defines the data to be set to this object
+     *            component
+     * @param params
+     *            parameter components
+     */
+    public HtmlObject(DownloadHandler data, Param... params) {
+        setData(new StreamResourceRegistry.ElementStreamResource(data,
+                this.getElement()));
+        add(params);
+    }
+
+    /**
+     * Creates a new <code>&lt;object&gt;</code> component with given data
+     * resource, type value and "param" components.
+     *
+     * @see #setData(String)
+     * @see #setType(String)
+     * @see #add(Component...)
+     *
+     *
+     * @param data
+     *            a handler that defines the data to be set to this object
+     *            component
+     */
+    public HtmlObject(DownloadHandler data) {
+        setData(new StreamResourceRegistry.ElementStreamResource(data,
+                this.getElement()));
+    }
+
     /**
      * Creates a new <code>&lt;object&gt;</code> component with given data and
      * "param" components.
@@ -200,7 +244,9 @@ public HtmlObject(String data, Param... params) {
      *
      * @param data
      *            the resource value, not {@code null}
+     * @deprecated use {@link #HtmlObject(DownloadHandler)} instead
      */
+    @Deprecated(since = "24.8", forRemoval = true)
     public HtmlObject(AbstractStreamResource data) {
         setData(data);
     }
@@ -216,7 +262,9 @@ public HtmlObject(AbstractStreamResource data) {
      *            the resource value, not {@code null}
      * @param params
      *            parameter components
+     * @deprecated use {@link #HtmlObject(DownloadHandler,Param...)} instead
      */
+    @Deprecated(since = "24.8", forRemoval = true)
     public HtmlObject(AbstractStreamResource data, Param... params) {
         setData(data);
         add(params);
@@ -237,7 +285,9 @@ public void setData(String data) {
      *
      * @param data
      *            a "data" attribute value,, not {@code null}
+     * @deprecated use {@link #setData(DownloadHandler)} instead
      */
+    @Deprecated(since = "24.8", forRemoval = true)
     public void setData(AbstractStreamResource data) {
         getElement().setAttribute("data", data);
     }
@@ -261,7 +311,7 @@ public void setData(DownloadHandler data) {
      * @return the "data" attribute value
      *
      * @see #setData(String)
-     * @see #setData(AbstractStreamResource)
+     * @see #setData(DownloadHandler)
      */
     public String getData() {
         return get(dataDescriptor);
diff --git a/flow-html-components/src/main/java/com/vaadin/flow/component/html/IFrame.java b/flow-html-components/src/main/java/com/vaadin/flow/component/html/IFrame.java
index 637cb9a0c55..d25793e8c26 100644
--- a/flow-html-components/src/main/java/com/vaadin/flow/component/html/IFrame.java
+++ b/flow-html-components/src/main/java/com/vaadin/flow/component/html/IFrame.java
@@ -168,7 +168,9 @@ public void setSrc(String src) {
      *
      * @param src
      *            the resource value, not null
+     * @deprecated use {@link #setSrc(DownloadHandler)} instead
      */
+    @Deprecated(since = "24.8", forRemoval = true)
     public void setSrc(AbstractStreamResource src) {
         getElement().setAttribute("src", src);
     }
diff --git a/flow-html-components/src/main/java/com/vaadin/flow/component/html/Image.java b/flow-html-components/src/main/java/com/vaadin/flow/component/html/Image.java
index 787d4db16b5..0a441bee663 100644
--- a/flow-html-components/src/main/java/com/vaadin/flow/component/html/Image.java
+++ b/flow-html-components/src/main/java/com/vaadin/flow/component/html/Image.java
@@ -81,7 +81,9 @@ public Image(String src, String alt) {
      *
      * @see #setSrc(AbstractStreamResource)
      * @see #setAlt(String)
+     * @deprecated use {@link #Image(DownloadHandler, String)} instead
      */
+    @Deprecated(since = "24.8", forRemoval = true)
     public Image(AbstractStreamResource src, String alt) {
         setSrc(src);
         setAlt(alt);
@@ -100,7 +102,7 @@ public Image(AbstractStreamResource src, String alt) {
      * @param alt
      *            the alternate text
      *
-     * @see #setSrc(AbstractStreamResource)
+     * @see #setSrc(DownloadHandler)
      * @see #setAlt(String)
      */
     public Image(DownloadHandler downloadHandler, String alt) {
@@ -132,7 +134,9 @@ public void setSrc(String src) {
      *
      * @param src
      *            the resource value, not null
+     * @deprecated use {@link #setSrc(DownloadHandler)} instead
      */
+    @Deprecated(since = "24.8", forRemoval = true)
     public void setSrc(AbstractStreamResource src) {
         getElement().setAttribute("src", src);
     }
diff --git a/flow-server/src/main/java/com/vaadin/flow/server/StreamReceiver.java b/flow-server/src/main/java/com/vaadin/flow/server/StreamReceiver.java
index 4e0e5a98a60..555d1e01628 100644
--- a/flow-server/src/main/java/com/vaadin/flow/server/StreamReceiver.java
+++ b/flow-server/src/main/java/com/vaadin/flow/server/StreamReceiver.java
@@ -27,7 +27,9 @@
  * @author Vaadin Ltd
  * @since 1.0
  *
+ * @deprecated use {@link com.vaadin.flow.server.streams.UploadHandler} instead
  */
+@Deprecated(since = "24.8", forRemoval = true)
 public class StreamReceiver extends AbstractStreamResource {
 
     private StateNode node;
diff --git a/flow-server/src/main/java/com/vaadin/flow/server/StreamResource.java b/flow-server/src/main/java/com/vaadin/flow/server/StreamResource.java
index 91522f88757..f0bf7cb5d31 100644
--- a/flow-server/src/main/java/com/vaadin/flow/server/StreamResource.java
+++ b/flow-server/src/main/java/com/vaadin/flow/server/StreamResource.java
@@ -42,7 +42,11 @@
  *
  * @author Vaadin Ltd
  * @since 1.0
+ *
+ * @deprecated use {@link com.vaadin.flow.server.streams.DownloadHandler}
+ *             instead
  */
+@Deprecated(since = "24.8", forRemoval = true)
 public class StreamResource extends AbstractStreamResource {
 
     private static final String DEFAULT_CONTENT_TYPE = "application/octet-stream";
diff --git a/flow-server/src/main/java/com/vaadin/flow/server/StreamVariable.java b/flow-server/src/main/java/com/vaadin/flow/server/StreamVariable.java
index 35eda100369..aa36a4e5196 100644
--- a/flow-server/src/main/java/com/vaadin/flow/server/StreamVariable.java
+++ b/flow-server/src/main/java/com/vaadin/flow/server/StreamVariable.java
@@ -31,7 +31,10 @@
  *
  * @author Vaadin Ltd
  * @since 1.0.
+ *
+ * @deprecated use {@link com.vaadin.flow.server.streams.UploadHandler} instead
  */
+@Deprecated(since = "24.8", forRemoval = true)
 public interface StreamVariable extends Serializable {
 
     /**
diff --git a/flow-server/src/main/java/com/vaadin/flow/server/streams/TransferProgressAwareHandler.java b/flow-server/src/main/java/com/vaadin/flow/server/streams/TransferProgressAwareHandler.java
index cdba6a617f2..68050102539 100644
--- a/flow-server/src/main/java/com/vaadin/flow/server/streams/TransferProgressAwareHandler.java
+++ b/flow-server/src/main/java/com/vaadin/flow/server/streams/TransferProgressAwareHandler.java
@@ -26,6 +26,7 @@
 import com.vaadin.flow.function.SerializableBiConsumer;
 import com.vaadin.flow.function.SerializableConsumer;
 import com.vaadin.flow.function.SerializableRunnable;
+import com.vaadin.flow.server.Command;
 import com.vaadin.flow.shared.Registration;
 
 /**
diff --git a/flow-server/src/main/java/com/vaadin/flow/server/streams/TransferProgressListener.java b/flow-server/src/main/java/com/vaadin/flow/server/streams/TransferProgressListener.java
index ea5141c1027..e8d2d0d57d2 100644
--- a/flow-server/src/main/java/com/vaadin/flow/server/streams/TransferProgressListener.java
+++ b/flow-server/src/main/java/com/vaadin/flow/server/streams/TransferProgressListener.java
@@ -25,7 +25,6 @@
 import java.util.Map;
 import java.util.Objects;
 
-import com.vaadin.flow.server.Command;
 import com.vaadin.flow.server.VaadinSession;
 
 /**


Reviews:
user: login: mshabarov
body: Minor comments otherwise LGTM.
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T13:11:08Z
user: login: caalador
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-13T03:50:26Z
user: login: mshabarov
state: DISMISSED
author_association: CONTRIBUTOR
submitted_at: 2025-05-13T06:25:59Z
user: login: mshabarov
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-13T06:26:21Z

Review comments:
diff_hunk: @@ -174,6 +179,43 @@ public HtmlObject(DownloadHandler data, String type, Param... params) {
         add(params);
     }
 
+    /**
+     * Creates a new <code>&lt;object&gt;</code> component with given data
+     * resource, type value and "param" components.
+     *
+     * @see #setData(String)
+     * @see #setType(String)
+     * @see #add(Component...)
+     *
+     *
+     * @param data
+     *            a data attribute value
path: flow-html-components/src/main/java/com/vaadin/flow/component/html/HtmlObject.java
user: login: mshabarov
body: ```suggestion
     *            a handler that defines the data to be set to this object component
```
created_at: 2025-05-12T13:01:23Z
author_association: CONTRIBUTOR
diff_hunk: @@ -174,6 +179,43 @@ public HtmlObject(DownloadHandler data, String type, Param... params) {
         add(params);
     }
 
+    /**
+     * Creates a new <code>&lt;object&gt;</code> component with given data
+     * resource, type value and "param" components.
+     *
+     * @see #setData(String)
+     * @see #setType(String)
+     * @see #add(Component...)
+     *
+     *
+     * @param data
+     *            a data attribute value
+     * @param params
+     *            parameter components
+     */
+    public HtmlObject(DownloadHandler data, Param... params) {
+        setData(new StreamResourceRegistry.ElementStreamResource(data,
+                this.getElement()));
+        add(params);
+    }
+
+    /**
+     * Creates a new <code>&lt;object&gt;</code> component with given data
+     * resource, type value and "param" components.
+     *
+     * @see #setData(String)
+     * @see #setType(String)
+     * @see #add(Component...)
+     *
+     *
+     * @param data
+     *            a data attribute value
path: flow-html-components/src/main/java/com/vaadin/flow/component/html/HtmlObject.java
user: login: mshabarov
body: ```suggestion
     *            a handler that defines the data to be set to this object component
```
created_at: 2025-05-12T13:02:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -27,7 +27,9 @@
  * @author Vaadin Ltd
  * @since 1.0
  *
+ * @deprecated use {@link com.vaadin.flow.server.streams.UploadHandler} instead
  */
+@Deprecated(since = "24.8", forRemoval = true)
path: flow-server/src/main/java/com/vaadin/flow/server/StreamReceiver.java
user: login: mshabarov
body: The deprecated API in the html components perhaps also needs `forRemoval = true`.
We may want to eventually remove all of them in some major release.
created_at: 2025-05-12T13:09:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -26,6 +26,7 @@
 import com.vaadin.flow.function.SerializableBiConsumer;
 import com.vaadin.flow.function.SerializableConsumer;
 import com.vaadin.flow.function.SerializableRunnable;
+import com.vaadin.flow.server.Command;
path: flow-server/src/main/java/com/vaadin/flow/server/streams/TransferProgressAwareHandler.java
user: login: mshabarov
body: Not used import?
created_at: 2025-05-12T13:10:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -26,6 +26,7 @@
 import com.vaadin.flow.function.SerializableBiConsumer;
 import com.vaadin.flow.function.SerializableConsumer;
 import com.vaadin.flow.function.SerializableRunnable;
+import com.vaadin.flow.server.Command;
path: flow-server/src/main/java/com/vaadin/flow/server/streams/TransferProgressAwareHandler.java
user: login: caalador
body: It's for the broken javadoc links, but it shouldnt be part of this PR. I'll fix it in another. 
Removed.
created_at: 2025-05-13T03:45:00Z
author_association: CONTRIBUTOR
diff_hunk: @@ -174,6 +179,43 @@ public HtmlObject(DownloadHandler data, String type, Param... params) {
         add(params);
     }
 
+    /**
+     * Creates a new <code>&lt;object&gt;</code> component with given data
+     * resource, type value and "param" components.
+     *
+     * @see #setData(String)
+     * @see #setType(String)
+     * @see #add(Component...)
+     *
+     *
+     * @param data
+     *            a data attribute value
path: flow-html-components/src/main/java/com/vaadin/flow/component/html/HtmlObject.java
user: login: caalador
body: done
created_at: 2025-05-13T03:46:41Z
author_association: CONTRIBUTOR
diff_hunk: @@ -174,6 +179,43 @@ public HtmlObject(DownloadHandler data, String type, Param... params) {
         add(params);
     }
 
+    /**
+     * Creates a new <code>&lt;object&gt;</code> component with given data
+     * resource, type value and "param" components.
+     *
+     * @see #setData(String)
+     * @see #setType(String)
+     * @see #add(Component...)
+     *
+     *
+     * @param data
+     *            a data attribute value
+     * @param params
+     *            parameter components
+     */
+    public HtmlObject(DownloadHandler data, Param... params) {
+        setData(new StreamResourceRegistry.ElementStreamResource(data,
+                this.getElement()));
+        add(params);
+    }
+
+    /**
+     * Creates a new <code>&lt;object&gt;</code> component with given data
+     * resource, type value and "param" components.
+     *
+     * @see #setData(String)
+     * @see #setType(String)
+     * @see #add(Component...)
+     *
+     *
+     * @param data
+     *            a data attribute value
path: flow-html-components/src/main/java/com/vaadin/flow/component/html/HtmlObject.java
user: login: caalador
body: done
created_at: 2025-05-13T03:46:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -27,7 +27,9 @@
  * @author Vaadin Ltd
  * @since 1.0
  *
+ * @deprecated use {@link com.vaadin.flow.server.streams.UploadHandler} instead
  */
+@Deprecated(since = "24.8", forRemoval = true)
path: flow-server/src/main/java/com/vaadin/flow/server/StreamReceiver.java
user: login: caalador
body: certainly.
created_at: 2025-05-13T03:47:48Z
author_association: CONTRIBUTOR
diff_hunk: @@ -81,7 +81,9 @@ public Image(String src, String alt) {
      *
      * @see #setSrc(AbstractStreamResource)
      * @see #setAlt(String)
+     * @deprecated use {@link #Image(DownloadHandler, String)} instead
      */
+    @Deprecated(since = "24.8")
path: flow-html-components/src/main/java/com/vaadin/flow/component/html/Image.java
user: login: mshabarov
body: ```suggestion
    @Deprecated(since = "24.8", forRemoval = true)
```
created_at: 2025-05-13T06:25:12Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-05-12T11:25:08Z
body: ## Test Results
1 228 files  ±0  1 228 suites  ±0   1h 12m 40s ⏱️ -53s
8 438 tests ±0  8 382 ✅ ±0  56 💤 ±0  0 ❌ ±0 
8 842 runs   - 5  8 777 ✅  - 5  65 💤 ±0  0 ❌ ±0 

Results for commit ae2abedb. ± Comparison against base commit 7811f8cc.

[test-results]:data:application/gzip;base64,H4sIAJPqImgC/03MRw7DIBRF0a1YjDOgl2zGokooLhGGkZW9Bzs2YfjO/7o7CHHyG3gOCGP5GMBWYu63K0nnuC5VKOGwSj3n40FSIu85bsXaw4jEf3vFdzXGmwQdpyqtMvqU1nRJKsuZlRRfq1WFEI1+Uc5u6Jrn7pN2neeY6wDaY228M8IEBqFySgdEhDaKCe6DNdAqLxGi4PMF0htyAhIBAAA=

:recycle: This comment has been updated with latest results.
author_association: NONE
user: login: knoobie
created_at: 2025-05-12T11:56:47Z
body: Vote for `@Deprecated` so that IDEs can complain about the old usage 
author_association: CONTRIBUTOR
user: login: sonarqubecloud[bot]
created_at: 2025-05-13T06:35:10Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=vaadin_flow&pullRequest=21418) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [117 New issues](https://sonarcloud.io/project/issues?id=vaadin_flow&pullRequest=21418&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=vaadin_flow&pullRequest=21418&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=vaadin_flow&pullRequest=21418&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=vaadin_flow&pullRequest=21418&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=vaadin_flow&pullRequest=21418&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=vaadin_flow&pullRequest=21418)


author_association: NONE