You cannot have two Content-Type (well technically, what we do below, but they are shared with each part of multipart, but the main type is multipart). This is basically what you expect from your method. You expect mutlipart and json together to become the main type of media. Employee data should be part of a multi-party system. This way you can add @FormDataParam("emp") for Employee .
@FormDataParam("emp") Employee emp) { ...
Here is the class I used for testing
@Path("/multipart") public class MultipartResource { @POST @Path("/upload2") @Consumes({MediaType.MULTIPART_FORM_DATA}) public Response uploadFileWithData( @FormDataParam("file") InputStream fileInputStream, @FormDataParam("file") FormDataContentDisposition cdh, @FormDataParam("emp") Employee emp) throws Exception{ Image img = ImageIO.read(fileInputStream); JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(img))); System.out.println(cdh.getName()); System.out.println(emp); return Response.ok("Cool Tools!").build(); } }
At first I just tested the client API to make sure that it works
@Test public void testGetIt() throws Exception { final Client client = ClientBuilder.newBuilder() .register(MultiPartFeature.class) .build(); WebTarget t = client.target(Main.BASE_URI).path("multipart").path("upload2"); FileDataBodyPart filePart = new FileDataBodyPart("file", new File("stackoverflow.png")); // UPDATE: just tested again, and the below code is not needed. // It redundant. Using the FileDataBodyPart already sets the // Content-Disposition information filePart.setContentDisposition( FormDataContentDisposition.name("file") .fileName("stackoverflow.png").build()); String empPartJson = "{\n" + " \"id\": 1234,\n" + " \"name\": \"Peeskillet\"\n" + "}\n" + ""; MultiPart multipartEntity = new FormDataMultiPart() .field("emp", empPartJson, MediaType.APPLICATION_JSON_TYPE) .bodyPart(filePart); Response response = t.request().post( Entity.entity(multipartEntity, multipartEntity.getMediaType())); System.out.println(response.getStatus()); System.out.println(response.readEntity(String.class)); response.close(); }
I just created a simple Employee class with an id and name field for testing. It works great. It displays the image, prints the contents, and prints the Employee object.
I'm not too familiar with Postman, so I saved this testing for the latter :-)

It also works great, as you can see the answer "Cool Tools" . But if we look at the printed data of Employee , we will see that it is null. Which is strange, because it worked perfectly with the client API.
If we look at the preview window, we will see a problem

There is no Content-Type header for the emp body part. In the client API you can explicitly specify it
MultiPart multipartEntity = new FormDataMultiPart() .field("emp", empPartJson, MediaType.APPLICATION_JSON_TYPE) .bodyPart(filePart);
So I think this is really only part of the complete answer. As I said, I am not familiar with Postman. Therefore, I do not know how to set the Content-Type for individual parts of the body. image/png for the image was automatically configured for me for part of the image (I think it was just determined by the file extension). If you can understand this, then the problem must be solved. Please, if you learn how to do this, send it as an answer.
And just for completeness ...
Basic configurations:
Dependence:
<dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-multipart</artifactId> <version>${jersey2.version}</version> </dependency>
Client Configuration:
final Client client = ClientBuilder.newBuilder() .register(MultiPartFeature.class) .build();
Server configuration:
// Create JAX-RS application. final Application application = new ResourceConfig() .packages("org.glassfish.jersey.examples.multipart") .register(MultiPartFeature.class);
UPDATE
Thus, as you can see on the Postman client, some clients cannot set individual Content-Type elements, including the browser, regarding the default capabilities when using FormData (js).
We cannot expect the client to detect this, so when we get the data, we explicitly set the Content-Type before deserializing. for example
@POST @Path("upload2") @Consumes(MediaType.MULTIPART_FORM_DATA) public Response uploadFileAndJSON(@FormDataParam("emp") FormDataBodyPart jsonPart, @FormDataParam("file") FormDataBodyPart bodyPart) { jsonPart.setMediaType(MediaType.APPLICATION_JSON_TYPE); Employee emp = jsonPart.getValueAs(Employee.class); }
This is a little extra work to get a POJO, but this is a better solution than getting a client to try and find their own solution.