From 09618cf6c483fdd6491e8bc8fd60f69fdd471849 Mon Sep 17 00:00:00 2001 From: jansupol Date: Tue, 14 Dec 2021 00:04:38 +0100 Subject: [PATCH] Added a documentation for Jakarta REST EntityPart Signed-off-by: jansupol --- docs/src/main/docbook/jersey.ent | 3 + docs/src/main/docbook/media.xml | 248 ++++++++++++++++++++++--------- 2 files changed, 183 insertions(+), 68 deletions(-) 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 <literal>EntityPart.Builder</literal> 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; +} + + +
+