1

I am using Jersey (org.glassfish.jersey - version 2.22.2) - JAX-RS, Guice and implementing method for image upload:

@PUT
@Path("/image")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public ImageResponse putImage(@FormDataParam("image") InputStream uploadedInputStream) {

    writeToFileWithOutputStream(uploadedInputStream);

    return null;
}


private void writeToFileWithOutputStream(InputStream uploadedInputStream) {

        try {
            OutputStream out = new FileOutputStream(new File("xxx.jpg"));
            int read = 0;
            byte[] bytes = new byte[1024];

            while ((read = uploadedInputStream.read(bytes)) != -1) {
                out.write(bytes, 0, read);
            }
            out.flush();
            out.close();
        } catch (IOException e) {

            e.printStackTrace();
        }
    }

When I use write to file with method writeToFileWithOutputStream, I get file which does not open as image. It consists:

------WebKitFormBoundary5PVRYeRUBBAFA9yi
Content-Disposition: form-data; name="image"; filename="images.jpg"
Content-Type: image/jpeg

/** image symbols **/

------WebKitFormBoundary5PVRYeRUBBAFA9yi
Content-Disposition: form-data; name=""


------WebKitFormBoundary5PVRYeRUBBAFA9yi--

If I delete the top 4 lines manually, image opens properly.

I have tried to process them with BufferedReader/Writer but it is malformed because of Corrupted files uploaded on REST method call

Also tried to use ImageIO.read(inputStream) but it returns null.

What is the best way to process received image InputStream and save it as image (jpg, png or other format)?

Community
  • 1
  • 1
Justinas Jakavonis
  • 8,220
  • 10
  • 69
  • 114

2 Answers2

2

1. code : When receiving an image with jersey, the stream received is not a String but a InputStream that you might read:

@OPTION
@Path("/image")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public Response putImag_opts(

@FormDataParam("image") InputStream stream,
@FormDataParam("image") FormDataContentDisposition fileDetail){
     return Response.ok().build();
}

@PUT
@Path("/image")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public Response putImage(

@FormDataParam("image") InputStream stream,
@FormDataParam("image") FormDataContentDisposition fileDetail


) {

    writeToFileWithOutputStream(stream);

    //if ok...
    return Response.ok().build();
}

informations: - object stream is the stream received, - object fileDetail contains files informations

2. dependencies : Please also check that you have the right dependency to upload image :

       <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-multipart</artifactId>
            <version>2.22.2</version>
        </dependency>

3. register in you app class

Register content multipart in your App.class jersey

register(MultiPartFeature.class);
jeorfevre
  • 2,286
  • 1
  • 17
  • 27
  • Sorry, it was my mistake. I am experiencing the problem when using InputStream. @FormDataParam("image") FormDataContentDisposition fileDetail - if I don't use FormDataContentDisposition as parameter, it adds additional data to InputStream? Do you process InputStream before saving as image? – Justinas Jakavonis May 13 '16 at 11:52
  • Thanks. I had been already using jersey-media-multipart dependency. I can not add second @FormDataParam("image") FormDataContentDisposition parameter because I get com.sun.jersey.spi.inject.Errors$ErrorMessagesException. It described here http://stackoverflow.com/questions/37179249/com-sun-jersey-spi-inject-errorserrormessagesexception-severe-missing-depend – Justinas Jakavonis May 13 '16 at 12:06
  • updated response. have you registered in you App Multipart? – jeorfevre May 13 '16 at 12:10
  • Is there any specific config for Guice? – Justinas Jakavonis May 13 '16 at 12:12
  • 1
    this is depending on jersey and not Guice, works with guice or without. But need to be added in you custom Jersey App class. – jeorfevre May 13 '16 at 12:13
  • 2
    The most important part is 3. I think that's what the OP is missing. The request is being treated like a normal request because the multipart provider is not taking care of it. – Paul Samsotha May 13 '16 at 12:13
  • Jersey REST Service org.glassfish.jersey.servlet.ServletContainer jersey.config.server.provider.classnames org.glassfish.jersey.media.multipart.MultiPartFeature does give the same error. – Justinas Jakavonis May 13 '16 at 13:14
  • you are not using App class but web.xml only configuration? What is the version of the servlet that you use 2 or 3? Can you give me the full version tag please? – jeorfevre May 13 '16 at 13:20
  • I have tried override "extends Application", web.xml configuration but it does notwork. javax.servlet javax.servlet-api 3.0.1 provided – Justinas Jakavonis May 13 '16 at 13:50
  • My project also includes external jar lib which use Jersey 1. – Justinas Jakavonis May 13 '16 at 13:52
  • what is the version in your Web.xml – jeorfevre May 13 '16 at 13:53
  • 1
    that is you problem, do not use both version of jersey at same time. Is external dependency only client dependency or server dependency? Caution with this, this is a source of problem at runtime! – jeorfevre May 13 '16 at 13:54
  • @Justas, See [this post for the 2.x jars](http://stackoverflow.com/a/30656345/2587435), if you're not using Maven – Paul Samsotha May 13 '16 at 15:04
0

The problem was because of different Jersey versions - version 1 in external jar lib and Jersey 2 in the main project. Switched to Jersey 1 in the main project, now images are saved and opened properly without additional processing. Also, there is no exception when 2 arguments are used together:

@FormDataParam("image") InputStream uploadedInputStream,
@FormDataParam("image") FormDataContentDisposition fileDetail
Justinas Jakavonis
  • 8,220
  • 10
  • 69
  • 114