Skip to content

Commit f5abcaf

Browse files
jansupolsenivam
authored andcommittedSep 7, 2023
Support a single EntityPart as an entity
Signed-off-by: jansupol <jan.supol@oracle.com>
1 parent 4d39156 commit f5abcaf

File tree

4 files changed

+170
-1
lines changed

4 files changed

+170
-1
lines changed
 

‎media/multipart/src/main/java/org/glassfish/jersey/media/multipart/MultiPartFeature.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
33
*
44
* This program and the accompanying materials are made available under the
55
* terms of the Eclipse Public License v. 2.0, which is available at
@@ -26,6 +26,8 @@
2626
import org.glassfish.jersey.media.multipart.internal.MultiPartReaderClientSide;
2727
import org.glassfish.jersey.media.multipart.internal.MultiPartReaderServerSide;
2828
import org.glassfish.jersey.media.multipart.internal.MultiPartWriter;
29+
import org.glassfish.jersey.media.multipart.internal.SingleEntityPartReader;
30+
import org.glassfish.jersey.media.multipart.internal.SingleEntityPartWriter;
2931

3032
/**
3133
* Feature used to register Multipart providers.
@@ -49,6 +51,8 @@ public boolean configure(final FeatureContext context) {
4951

5052
context.register(EntityPartReader.class);
5153
context.register(EntityPartWriter.class);
54+
context.register(SingleEntityPartReader.class);
55+
context.register(SingleEntityPartWriter.class);
5256

5357
return true;
5458
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0, which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the
10+
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11+
* version 2 with the GNU Classpath Exception, which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
*/
16+
17+
package org.glassfish.jersey.media.multipart.internal;
18+
19+
import jakarta.inject.Inject;
20+
import jakarta.ws.rs.WebApplicationException;
21+
import jakarta.ws.rs.core.Context;
22+
import jakarta.ws.rs.core.EntityPart;
23+
import jakarta.ws.rs.core.MediaType;
24+
import jakarta.ws.rs.core.MultivaluedMap;
25+
import jakarta.ws.rs.ext.MessageBodyReader;
26+
import jakarta.ws.rs.ext.Providers;
27+
import org.glassfish.jersey.media.multipart.BodyPart;
28+
import org.glassfish.jersey.media.multipart.FormDataBodyPart;
29+
import org.glassfish.jersey.media.multipart.JerseyEntityPartBuilderProvider;
30+
import org.glassfish.jersey.media.multipart.MultiPart;
31+
32+
import java.io.IOException;
33+
import java.io.InputStream;
34+
import java.lang.annotation.Annotation;
35+
import java.lang.reflect.Type;
36+
import java.util.LinkedList;
37+
import java.util.List;
38+
39+
public class SingleEntityPartReader implements MessageBodyReader<EntityPart> {
40+
41+
private MultiPartReaderClientSide multiPartReaderClientSide;
42+
43+
private final Providers providers;
44+
45+
@Inject
46+
public SingleEntityPartReader(@Context Providers providers) {
47+
this.providers = providers;
48+
}
49+
50+
@Override
51+
public boolean isReadable(Class<?> type, Type generic, Annotation[] annotations, MediaType mediaType) {
52+
return EntityPart.class.isAssignableFrom(type);
53+
}
54+
55+
@Override
56+
public EntityPart readFrom(Class<EntityPart> type, Type genericType, Annotation[] annotations,
57+
MediaType mediaType, MultivaluedMap<String, String> httpHeaders,
58+
InputStream entityStream) throws IOException, WebApplicationException {
59+
60+
if (multiPartReaderClientSide == null) {
61+
multiPartReaderClientSide = (MultiPartReaderClientSide) providers.getMessageBodyReader(
62+
MultiPart.class, MultiPart.class, new Annotation[0], MediaType.MULTIPART_FORM_DATA_TYPE);
63+
}
64+
65+
final MultiPart multiPart = multiPartReaderClientSide.readFrom(
66+
MultiPart.class, MultiPart.class, annotations, mediaType, httpHeaders, entityStream);
67+
final List<BodyPart> bodyParts = multiPart.getBodyParts();
68+
final List<EntityPart> entityParts = new LinkedList<>();
69+
70+
for (BodyPart bp : bodyParts) {
71+
if (FormDataBodyPart.class.isInstance(bp)) {
72+
entityParts.add((EntityPart) bp);
73+
} else {
74+
final EntityPart ep = new JerseyEntityPartBuilderProvider().withName("")
75+
.mediaType(bp.getMediaType()).content(bp.getEntity()).headers(bp.getHeaders()).build();
76+
entityParts.add(ep);
77+
}
78+
// consume all bodyParts
79+
}
80+
81+
return entityParts.get(0);
82+
}
83+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
3+
*
4+
* This program and the accompanying materials are made available under the
5+
* terms of the Eclipse Public License v. 2.0, which is available at
6+
* http://www.eclipse.org/legal/epl-2.0.
7+
*
8+
* This Source Code may also be made available under the following Secondary
9+
* Licenses when the conditions for such availability set forth in the
10+
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
11+
* version 2 with the GNU Classpath Exception, which is available at
12+
* https://www.gnu.org/software/classpath/license.html.
13+
*
14+
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15+
*/
16+
17+
package org.glassfish.jersey.media.multipart.internal;
18+
19+
import jakarta.inject.Inject;
20+
import jakarta.ws.rs.WebApplicationException;
21+
import jakarta.ws.rs.core.Context;
22+
import jakarta.ws.rs.core.EntityPart;
23+
import jakarta.ws.rs.core.MediaType;
24+
import jakarta.ws.rs.core.MultivaluedMap;
25+
import jakarta.ws.rs.ext.MessageBodyWriter;
26+
import jakarta.ws.rs.ext.Providers;
27+
import org.glassfish.jersey.media.multipart.BodyPart;
28+
import org.glassfish.jersey.media.multipart.MultiPart;
29+
30+
import java.io.IOException;
31+
import java.io.OutputStream;
32+
import java.lang.annotation.Annotation;
33+
import java.lang.reflect.Type;
34+
35+
public class SingleEntityPartWriter implements MessageBodyWriter<EntityPart> {
36+
37+
private MultiPartWriter multiPartWriter;
38+
39+
private final Providers providers;
40+
41+
@Inject
42+
public SingleEntityPartWriter(@Context Providers providers) {
43+
this.providers = providers;
44+
}
45+
46+
@Override
47+
public boolean isWriteable(Class<?> type, Type generic, Annotation[] annotations, MediaType mediaType) {
48+
return EntityPart.class.isAssignableFrom(type);
49+
}
50+
51+
@Override
52+
public void writeTo(EntityPart entityParts, Class<?> type, Type genericType, Annotation[] annotations,
53+
MediaType mediaType, MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
54+
throws IOException, WebApplicationException {
55+
final MultiPart multiPart = new MultiPart();
56+
multiPart.setMediaType(mediaType);
57+
multiPart.bodyPart((BodyPart) entityParts);
58+
59+
if (multiPartWriter == null) {
60+
multiPartWriter = (MultiPartWriter) providers.getMessageBodyWriter(
61+
MultiPart.class, MultiPart.class, new Annotation[0], MediaType.MULTIPART_FORM_DATA_TYPE);
62+
}
63+
64+
multiPartWriter.writeTo(multiPart, MultiPart.class, MultiPart.class,
65+
annotations, multiPart.getMediaType(), httpHeaders, entityStream);
66+
}
67+
}

‎media/multipart/src/test/java/org/glassfish/jersey/media/multipart/internal/EntityPartTest.java

+15
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,21 @@ public void postHeaderTest() throws IOException {
298298
}
299299
}
300300

301+
@Test
302+
public void postHeaderNoListTest() throws IOException {
303+
EntityPart entityPart = EntityPart.withName("name1").content("data1").header("header-01", "value-01").build();
304+
Entity entity = Entity.entity(entityPart, MediaType.MULTIPART_FORM_DATA_TYPE);
305+
try (Response response = target("/postHeaders").request().post(entity)) {
306+
response.bufferEntity();
307+
List<EntityPart> result = response.readEntity(LIST_ENTITY_PART_TYPE);
308+
assertEquals("value-01", result.get(0).getHeaders().getFirst("header-01"));
309+
assertEquals("data1", result.get(0).getContent(String.class));
310+
311+
EntityPart firstEntity = response.readEntity(EntityPart.class);
312+
assertEquals("value-01", result.get(0).getHeaders().getFirst("header-01"));
313+
}
314+
}
315+
301316
@Consumes(MediaType.TEXT_PLAIN)
302317
@Produces(MediaType.TEXT_PLAIN)
303318
public static class AtomicReferenceProvider implements

0 commit comments

Comments
 (0)