diff --git a/docs/src/main/docbook/jersey.ent b/docs/src/main/docbook/jersey.ent
index e171df0c36..b53cc2d551 100644
--- a/docs/src/main/docbook/jersey.ent
+++ b/docs/src/main/docbook/jersey.ent
@@ -215,6 +215,7 @@
Configuration">
@Context">
Cookie">
+EntityPart">
EntityTag">
Feature">
Form">
@@ -762,6 +763,7 @@
@Context">
Cookie">
EntityTag">
+EntityPart">
Feature">
Form">
GenericEntity<T>">
@@ -807,6 +809,7 @@
InputStream">
JAXBElement">
KeyStore">
+List">
Number">
ObjectName">
ParameterizedType">
diff --git a/docs/src/main/docbook/media.xml b/docs/src/main/docbook/media.xml
index 95581dfca0..3bd4013dba 100644
--- a/docs/src/main/docbook/media.xml
+++ b/docs/src/main/docbook/media.xml
@@ -23,6 +23,10 @@
Jackson" >
Jettison" >
Java API for JSON Binding (JSON-B)" >
+ Client using Jersey API" >
+ Client using Jakarta REST API" >
+ Server using Jersey API" >
+ Server using Jakarta REST API" >
%ents;
]>
@@ -1540,25 +1544,11 @@ final ResourceConfig config = new ResourceConfig()
Registration
- Before you can use capabilities of the &lit.jersey-media-multipart; module in your client/server code, you
- need to register &jersey.media.multipart.MultiPartFeature;.
+ Prior to Jersey 3.1.0, before you can use the capabilities of the &lit.jersey-media-multipart;
+ module in your client/server code, you need to register &jersey.media.multipart.MultiPartFeature;.
-
- Building client with MultiPart feature enabled.
-
- final Client client = ClientBuilder.newBuilder()
- .register(MultiPartFeature.class)
- .build();
-
-
-
- Creating JAX-RS application with MultiPart feature enabled.
-
- // Create JAX-RS application.
-final Application application = new ResourceConfig()
- .packages("org.glassfish.jersey.examples.multipart")
- .register(MultiPartFeature.class)
-
+ The multipart feature is supported by Jakarta RESTful Web Services 3.1 multipart API. From Jersey 3.1.0 on,
+ the &jersey.media.multipart.MultiPartFeature; is no longer required to be registered and it is registered automatically.
@@ -1573,20 +1563,30 @@ final Application application = new ResourceConfig()
Client
+
+
+ &link.multipart.client.jersey;
+
+
+ &link.multipart.client.rest;
+
+
+
+ Client using Jersey API
-
- &jersey.media.multipart.MultiPart; class (or it's subclasses) can be used as an entry point to use
- &lit.jersey-media-multipart; module on the client side. This class represents a
- MIME multipart message and is able
- to hold an arbitrary number of &jersey.media.multipart.BodyPart;s. Default media type is
- multipart/mixed
- for &lit.jersey.media.multipart.MultiPart; entity and text/plain for
- &lit.jersey.media.multipart.BodyPart;.
+
+ &jersey.media.multipart.MultiPart; class (or it's subclasses) can be used as an entry point to use
+ &lit.jersey-media-multipart; module on the client side. This class represents a
+ MIME multipart message and is able
+ to hold an arbitrary number of &jersey.media.multipart.BodyPart;s. Default media type is
+ multipart/mixed
+ for &lit.jersey.media.multipart.MultiPart; entity and text/plain for
+ &lit.jersey.media.multipart.BodyPart;.
-
- &lit.jersey.media.multipart.MultiPart; entity
+
+ &lit.jersey.media.multipart.MultiPart; entity
- final MultiPart multiPartEntity = new MultiPart()
+ final MultiPart multiPartEntity = new MultiPart()
.bodyPart(new BodyPart().entity("hello"))
.bodyPart(new BodyPart(new JaxbBean("xml"), MediaType.APPLICATION_XML_TYPE))
.bodyPart(new BodyPart(new JaxbBean("json"), MediaType.APPLICATION_JSON_TYPE));
@@ -1595,15 +1595,15 @@ final WebTarget target = // Create WebTarget.
final Response response = target
.request()
.post(Entity.entity(multiPartEntity, multiPartEntity.getMediaType()));
-
+
- If you send a multiPartEntity to the server the entity with Content-Type
- header in HTTP message would look like (don't forget to register a JSON provider):
+ If you send a multiPartEntity to the server the entity with Content-Type
+ header in HTTP message would look like:
-
- &lit.jersey.media.multipart.MultiPart; entity in HTTP message.
+
+ &lit.jersey.media.multipart.MultiPart; entity in HTTP message.
- Content-Type: multipart/mixed; boundary=Boundary_1_829077776_1369128119878
+ Content-Type: multipart/mixed; boundary=Boundary_1_829077776_1369128119878
--Boundary_1_829077776_1369128119878
Content-Type: text/plain
@@ -1618,34 +1618,34 @@ Content-Type: application/json
{"value":"json"}
--Boundary_1_829077776_1369128119878--
-
-
-
- When working with forms (e.g. media type multipart/form-data) and various fields in them,
- there is a more convenient class to be used - &jersey.media.multipart.FormDataMultiPart;. It automatically sets
- the media type for the &lit.jersey.media.multipart.FormDataMultiPart; entity to
- multipart/form-data and Content-Disposition header to
- &lit.jersey.media.multipart.FormDataBodyPart; body parts.
+
+
+
+ When working with forms (e.g. media type multipart/form-data) and various fields in them,
+ there is a more convenient class to be used - &jersey.media.multipart.FormDataMultiPart;. It automatically sets
+ the media type for the &lit.jersey.media.multipart.FormDataMultiPart; entity to
+ multipart/form-data and Content-Disposition header to
+ &lit.jersey.media.multipart.FormDataBodyPart; body parts.
-
- &lit.jersey.media.multipart.FormDataMultiPart; entity
- final FormDataMultiPart multipart = new FormDataMultiPart()
+
+ &lit.jersey.media.multipart.FormDataMultiPart; entity
+ final FormDataMultiPart multipart = new FormDataMultiPart()
.field("hello", "hello")
.field("xml", new JaxbBean("xml"))
.field("json", new JaxbBean("json"), MediaType.APPLICATION_JSON_TYPE);
final WebTarget target = // Create WebTarget.
final Response response = target.request().post(Entity.entity(multipart, multipart.getMediaType()));
-
+
- To illustrate the difference when using &lit.jersey.media.multipart.FormDataMultiPart; instead of
- &lit.jersey.media.multipart.FormDataBodyPart; you can take a look at the
- &lit.jersey.media.multipart.FormDataMultiPart; entity from HTML message:
+ To illustrate the difference when using &lit.jersey.media.multipart.FormDataMultiPart; instead of
+ &lit.jersey.media.multipart.FormDataBodyPart; you can take a look at the
+ &lit.jersey.media.multipart.FormDataMultiPart; entity from HTML message:
-
- &lit.jersey.media.multipart.FormDataMultiPart; entity in HTTP message.
+
+ &lit.jersey.media.multipart.FormDataMultiPart; entity in HTTP message.
- Content-Type: multipart/form-data; boundary=Boundary_1_511262261_1369143433608
+ Content-Type: multipart/form-data; boundary=Boundary_1_511262261_1369143433608
--Boundary_1_511262261_1369143433608
Content-Type: text/plain
@@ -1663,17 +1663,17 @@ Content-Disposition: form-data; name="json"
{"value":"json"}
--Boundary_1_511262261_1369143433608--
-
-
-
- A common use-case for many users is sending files from client to server. For this purpose you can use classes from
- org.glassfish.jersey.jersey.media.multipart package, such as
- &jersey.media.multipart.FileDataBodyPart; or &jersey.media.multipart.StreamDataBodyPart;.
+
+
+
+ A common use-case for many users is sending files from client to server. For this purpose you can use classes from
+ org.glassfish.jersey.jersey.media.multipart package, such as
+ &jersey.media.multipart.FileDataBodyPart; or &jersey.media.multipart.StreamDataBodyPart;.
-
- Multipart - sending files.
+
+ Multipart - sending files.
- // MediaType of the body part will be derived from the file.
+ // MediaType of the body part will be derived from the file.
final FileDataBodyPart filePart = new FileDataBodyPart("my_pom", new File("pom.xml"));
final FormDataMultiPart multipart = new FormDataMultiPart()
@@ -1683,19 +1683,76 @@ final FormDataMultiPart multipart = new FormDataMultiPart()
final WebTarget target = // Create WebTarget.
final Response response = target.request()
.post(Entity.entity(multipart, multipart.getMediaType()));
+
+
+
+
+ Do not use &lit.jersey.apache.ApacheConnectorProvider; nor &lit.jersey.grizzly.GrizzlyConnectorProvider;
+ neither &lit.jersey.jetty.JettyConnectorProvider; connector implementations with Jersey Multipart
+ features. See warning for more details.
+
+
+
+
+
+ Client using Jakarta REST API
+
+
+ &jaxrs.core.EntityPart; interface can be used as an entry point to use
+ &lit.jersey-media-multipart; module on the client side. This class represents multipart message is able
+ to hold an arbitrary number of &jaxrs.core.EntityPart;s. Default media type is
+ multipart/form-data.
+
+
+ Using EntityPart.Builder for building an Entity
+
+
+final List<EntityPart> multiPartEntity = new List<>();
+list.add(EntityPart.withName("part-01").content("hello").build());
+list.add(EntityPart.withName("part-01").content(new JaxbBean("xml")).mediaType(MediaType.APPLICATION_XML_TYPE).build()); //same name
+list.add(EntityPart.withName("part-02").content(new JaxbBean("json")).mediaType(MediaType.APPLICATION_JSON_TYPE).build()); //other name
+final GenericEntity<List<EntityPart>> genericEntity = new GenericEntity<>(list) {};
+final Entity entity = Entity.entity(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE);
+
+final WebTarget target = // Create WebTarget.
+final Response response = target.request().post(entity);
+
-
-
+
- Do not use &lit.jersey.apache.ApacheConnectorProvider; nor &lit.jersey.grizzly.GrizzlyConnectorProvider;
- neither &lit.jersey.jetty.JettyConnectorProvider; connector implementations with Jersey Multipart
- features. See warning for more details.
+ The common use-case for many users is sending files from client to server. It is also covered by
+ &jaxrs.core.EntityPart;.Builder.
+
+ EntityPart - sending files.
+
+ // MediaType of the body part will be derived from the file.
+final List<EntityPart> multiPartEntity = new List<>();
+list.add(EntityPart.withFileName("file001.txt").content(new FileInputStream("file001.txt")).build());
+list.add(EntityPart.withFileName("mypom.xml").content(new FileInputStream("pom.xml")).build());
+
+final GenericEntity<List<EntityPart>> genericEntity = new GenericEntity<>(list) {};
+final Entity entity = Entity.entity(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE);
+
+final WebTarget target = // Create WebTarget.
+final Response response = target.request().post(entity);
+
+
-
+ Server
+
+
+ &link.multipart.server.jersey;
+
+
+ &link.multipart.server.rest;
+
+
+
+ Jersey Server API
Returning a multipart response from server to client is not much different from the parts described in the client
@@ -1852,5 +1909,60 @@ public String postForm(
+
+ Server using Jakarta REST API
+
+ Using &jaxrs.core.EntityPart; on the server side is similar to the client side.
+ Jakarta REST specification allows for
+ returning a &lit.jaxrs.core.Response; or a &lit.jdk6.List; of &lit.jaxrs.core.EntityPart;s.
+
+
+ Receiving the &jaxrs.core.EntityPart;s can be done either using &lit.jaxrs.FormParam; annotations and
+ &lit.jaxrs.core.EntityPart;, &lit.jdk6.InputStream; or &lit.jdk6.String; data-types, or using a
+ &lit.jdk6.List; of &lit.jaxrs.core.EntityPart;s.
+
+
+
+ Use of &lit.jaxrs.FormParam; annotation with &lit.jaxrs.core.EntityPart; &lit.jdk6.InputStream;
+ and &lit.jdk6.String; types and returning a &lit.jaxrs.core.Response;
+ @POST
+@Path("/postFormVarious")
+public Response postFormVarious(@FormParam("name1") EntityPart part1,
+ @FormParam("name2") InputStream part2,
+ @FormParam("name3") String part3) throws IOException {
+ final List<EntityPart> list = new LinkedList<>();
+ list.add(EntityPart.withName(part1.getName())
+ .content(part1.getContent(String.class) + new String(part2.readAllBytes()) + part3)
+ .mediaType(MediaType.TEXT_PLAIN_TYPE)
+ .build());
+ final GenericEntity<List<EntityPart>> genericEntity = new GenericEntity<>(list) {};
+ return Response.ok(genericEntity, MediaType.MULTIPART_FORM_DATA_TYPE).build();
+}
+
+
+
+ Receiving a &lit.jdk6.List; of &lit.jaxrs.core.EntityPart;s
+ @POST
+@Path("/postListForm")
+public String postEntityPartForm(@FormParam("part-0x") List<EntityPart> part) throws IOException {
+ final String entity = part.get(0).getContent(String.class) + part.get(1).getContent(String.class);
+ return entity;
+}
+
+
+
+ Returning a &lit.jdk6.List; of &lit.jaxrs.core.EntityPart;s
+ @GET
+@Produces(MediaType.MULTIPART_FORM_DATA)
+@Path("/getList")
+public List<EntityPart> getList() throws IOException {
+ final List<EntityPart> list = new LinkedList<>();
+ list.add(EntityPart.withName("name1").content("data1").build());
+ return list;
+}
+
+
+
+