From 75324cb4d0b7a523105c3450f056a007493d84c6 Mon Sep 17 00:00:00 2001 From: jansupol Date: Fri, 3 May 2024 20:24:29 +0200 Subject: [PATCH 1/3] Allow having multiple annotations for multipart endpoint with @FormDataParam in any order Signed-off-by: jansupol --- .../FormDataParamValueParamProvider.java | 68 ++++++++------- .../multipart/internal/OrderParamTest.java | 84 +++++++++++++++++++ 2 files changed, 124 insertions(+), 28 deletions(-) create mode 100644 media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/OrderParamTest.java diff --git a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/FormDataParamValueParamProvider.java b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/FormDataParamValueParamProvider.java index d2f33d8e95..e221107dcd 100644 --- a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/FormDataParamValueParamProvider.java +++ b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/FormDataParamValueParamProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -20,6 +20,8 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.lang.annotation.Annotation; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -232,7 +234,13 @@ public FormDataParamValueProvider(Parameter parameter, MultivaluedParameterExtra @Override public Object apply(ContainerRequest request) { // Return the field value for the field specified by the sourceName property. - final List parts = getEntity(request).getFields(parameter.getSourceName()); + final String sourceName = parameter.getSourceName() != null + ? parameter.getSourceName() + : Arrays.stream(parameter.getAnnotations()) + .filter(ann -> FormDataParam.class.isInstance(ann)) + .map(ann -> FormDataParam.class.cast(ann)) + .findFirst().get().value(); + final List parts = getEntity(request).getFields(sourceName); final FormDataBodyPart part = parts != null ? parts.get(0) : null; final MediaType mediaType = part != null ? part.getMediaType() : MediaType.TEXT_PLAIN_TYPE; @@ -357,34 +365,38 @@ public FormDataParamValueParamProvider(Provider Date: Sat, 4 May 2024 00:36:53 +0200 Subject: [PATCH 2/3] support also annotations with value Signed-off-by: jansupol --- .../FormDataParamValueParamProvider.java | 4 +--- .../multipart/internal/OrderParamTest.java | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/FormDataParamValueParamProvider.java b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/FormDataParamValueParamProvider.java index e221107dcd..17ecfc12a1 100644 --- a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/FormDataParamValueParamProvider.java +++ b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/FormDataParamValueParamProvider.java @@ -234,9 +234,7 @@ public FormDataParamValueProvider(Parameter parameter, MultivaluedParameterExtra @Override public Object apply(ContainerRequest request) { // Return the field value for the field specified by the sourceName property. - final String sourceName = parameter.getSourceName() != null - ? parameter.getSourceName() - : Arrays.stream(parameter.getAnnotations()) + final String sourceName = Arrays.stream(parameter.getAnnotations()) .filter(ann -> FormDataParam.class.isInstance(ann)) .map(ann -> FormDataParam.class.cast(ann)) .findFirst().get().value(); diff --git a/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/OrderParamTest.java b/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/OrderParamTest.java index 1a88a88c21..1758b46f34 100644 --- a/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/OrderParamTest.java +++ b/media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/OrderParamTest.java @@ -21,10 +21,10 @@ import org.glassfish.jersey.media.multipart.MultiPartFeature; import org.glassfish.jersey.message.internal.ReaderWriter; import org.glassfish.jersey.server.ResourceConfig; +import org.glassfish.jersey.server.model.ParamQualifier; import org.glassfish.jersey.test.JerseyTest; import org.junit.jupiter.api.Test; -import javax.validation.constraints.NotNull; import javax.ws.rs.Consumes; import javax.ws.rs.POST; import javax.ws.rs.Path; @@ -34,23 +34,34 @@ import javax.ws.rs.core.Response; import java.io.IOException; import java.io.InputStream; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import static org.junit.jupiter.api.Assertions.assertEquals; public class OrderParamTest extends JerseyTest { + @Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD}) + @Retention(RetentionPolicy.RUNTIME) + @ParamQualifier + public static @interface AnnoWithValue { + String value() default ""; + } + @Path("/order") public static class OrderTestResource { @POST @Path("/dataAfter") @Consumes(value = MediaType.MULTIPART_FORM_DATA) - public String orderBefore(@FormDataParam("file") @NotNull InputStream inputStream) throws IOException { + public String orderBefore(@FormDataParam("file") @AnnoWithValue("xxx") InputStream inputStream) throws IOException { return ReaderWriter.readFromAsString(inputStream, MediaType.TEXT_PLAIN_TYPE); } @POST @Path("/dataBefore") @Consumes(value = MediaType.MULTIPART_FORM_DATA) - public String orderAfter(@NotNull @FormDataParam("file") InputStream inputStream) throws IOException { + public String orderAfter(@AnnoWithValue("zzz") @FormDataParam("file") InputStream inputStream) throws IOException { return ReaderWriter.readFromAsString(inputStream, MediaType.TEXT_PLAIN_TYPE); } } From 0ca5ae47459b3bc4f4b23ffa725f99412501c035 Mon Sep 17 00:00:00 2001 From: jansupol Date: Sat, 4 May 2024 00:39:38 +0200 Subject: [PATCH 3/3] A little speedup for a single parameter annotation Signed-off-by: jansupol --- .../multipart/internal/FormDataParamValueParamProvider.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/FormDataParamValueParamProvider.java b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/FormDataParamValueParamProvider.java index 17ecfc12a1..fde9dc9d85 100644 --- a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/FormDataParamValueParamProvider.java +++ b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/internal/FormDataParamValueParamProvider.java @@ -234,7 +234,9 @@ public FormDataParamValueProvider(Parameter parameter, MultivaluedParameterExtra @Override public Object apply(ContainerRequest request) { // Return the field value for the field specified by the sourceName property. - final String sourceName = Arrays.stream(parameter.getAnnotations()) + final String sourceName = parameter.getAnnotations().length == 1 + ? parameter.getSourceName() + : Arrays.stream(parameter.getAnnotations()) .filter(ann -> FormDataParam.class.isInstance(ann)) .map(ann -> FormDataParam.class.cast(ann)) .findFirst().get().value();