Web application exception: javax.ws.rs.NotSupportedException: HTTP 415 Unsupported media type

I use jersey and spring in my application. I have no problem working with any AJAX requests, but I don’t get an error when uploading files. I tried several methods, but did not find any problems for this. I wonder if anyone can help me find the root cause of the problem. I appreciate your help.

Server side execution

web.xml

<servlet> <servlet-name>jersey-servlet</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value>org.blanc.whiteboard.RestResourceApplication</param-value> </init-param> <init-param> <param-name>org.glassfish.jersey.api.json.POJOMappingFeature</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>jersey.config.server.provider.classnames</param-name> <param-value>org.glassfish.jersey.filter.LoggingFilter;org.glassfish.jersey.media.multipart.MultiPartFeature</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> 

resource class

 @Path("/upload") @POST //@Consumes({ MediaType.MULTIPART_FORM_DATA }) public Response uploadAsset(@Context SecurityContext sc, MultipartHttpServletRequest request) { User user = loadUserFromSecurityContext(sc); MultipartFile file = null; // 1. build an iterator Iterator<String> itr = request.getFileNames(); // 2. get each file while (itr.hasNext()) { // 2.1 get next MultipartFile file = request.getFile(itr.next()); if (file == null) { throw new FileUploadException("File is null."); } LOG.info(file.getOriginalFilename() + " uploaded! " + files.size()); // 2.2 if files > 10 remove the first from list if (files.size() > 10) files.pop(); } return Response.ok().build(); } 

pom.xml

  <jersey.version>2.20</jersey.version> ..... <dependency> <groupId>org.glassfish.jersey.ext</groupId> <artifactId>jersey-spring3</artifactId> <version>${jersey.version}</version> <exclusions> <exclusion> <artifactId>spring-core</artifactId> <groupId>org.springframework</groupId> </exclusion> <exclusion> <artifactId>spring-aop</artifactId> <groupId>org.springframework</groupId> </exclusion> <exclusion> <artifactId>spring-beans</artifactId> <groupId>org.springframework</groupId> </exclusion> <exclusion> <artifactId>spring-context</artifactId> <groupId>org.springframework</groupId> </exclusion> <exclusion> <artifactId>spring-web</artifactId> <groupId>org.springframework</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-client</artifactId> <version>${jersey.version}</version> </dependency> <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-common</artifactId> <version>${jersey.version}</version> </dependency> <dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-json-jackson</artifactId> <version>${jersey.version}</version> </dependency> <!-- File upload --> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>${commons-fileupload.version}</version> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>${commons-io.version}</version> </dependency> 

Error:

 Aug 12, 2015 7:21:58 PM org.glassfish.jersey.filter.LoggingFilter log INFO: 4 * Server responded with a response on thread http-bio-8080-exec-5 4 < 200 4 < Access-Control-Allow-Headers: X-HTTP-Method-Override, Content-Type, x-requested-with, Authorization, Cache-Control 4 < Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS 4 < Access-Control-Allow-Origin: http://localhost:9000 4 < Access-Control-Max-Age: 3600 4 < Content-Type: application/json Aug 12, 2015 7:22:15 PM org.glassfish.jersey.filter.LoggingFilter log INFO: 5 * Server has received a request on thread http-bio-8080-exec-1 5 > OPTIONS http://localhost:8080/v1.0/assets/upload 5 > accept: */* 5 > accept-encoding: gzip, deflate, sdch 5 > accept-language: en-US,en;q=0.8 5 > access-control-request-headers: accept, cache-control, content-type, x-requested-with 5 > access-control-request-method: POST 5 > cache-control: no-cache 5 > connection: keep-alive 5 > host: localhost:8080 5 > origin: http://localhost:9000 5 > pragma: no-cache 5 > referer: http://localhost:9000/debug.html 5 > user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36 Aug 12, 2015 7:22:15 PM org.glassfish.jersey.filter.LoggingFilter log INFO: 5 * Server responded with a response on thread http-bio-8080-exec-1 5 < 200 5 < Access-Control-Allow-Headers: X-HTTP-Method-Override, Content-Type, x-requested-with, Authorization, Cache-Control 5 < Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS 5 < Access-Control-Allow-Origin: http://localhost:9000 5 < Access-Control-Max-Age: 3600 5 < Allow: POST,OPTIONS 5 < Content-Type: application/vnd.sun.wadl+xml 5 < Last-modified: Wed, 12 Aug 2015 19:22:15 EDT Aug 12, 2015 7:22:15 PM org.glassfish.jersey.filter.LoggingFilter log INFO: 6 * Server has received a request on thread http-bio-8080-exec-10 6 > POST http://localhost:8080/v1.0/assets/upload 6 > accept: application/json 6 > accept-encoding: gzip, deflate 6 > accept-language: en-US,en;q=0.8 6 > cache-control: no-cache 6 > connection: keep-alive 6 > content-length: 108054 6 > content-type: multipart/form-data; boundary=----WebKitFormBoundarywS3v9iwIqD3NwnYt 6 > host: localhost:8080 6 > origin: http://localhost:9000 6 > pragma: no-cache 6 > referer: http://localhost:9000/debug.html 6 > user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36 6 > x-requested-with: XMLHttpRequest 19:22:15.340 [http-bio-8080-exec-10] INFO obwrGenericExceptionMapper - Web Application Exception: **javax.ws.rs.NotSupportedException: HTTP 415 Unsupported Media Type** Aug 12, 2015 7:22:15 PM org.glassfish.jersey.filter.LoggingFilter log INFO: 6 * Server responded with a response on thread http-bio-8080-exec-10 6 < 415 6 < Access-Control-Allow-Headers: X-HTTP-Method-Override, Content-Type, x-requested-with, Authorization, Cache-Control 6 < Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS 6 < Access-Control-Allow-Origin: http://localhost:9000 6 < Access-Control-Max-Age: 3600 

At the first end, I use [dropzone][1]

+4
source share
1 answer

You cannot just expect the request body to be parsed into arbitrary data types (i.e. MultipartHttpServletRequest ). How it works (with Jersey and JAX-RS) via MessageBodyReader (you can read here ).

Basically, based on the Content-Type request (which is multipart/form-data ) and the type of the method parameter ( MultipartHttpServletRequest ), Jersey will look at its registry for MessageBodyReader , which can handle these two factors. If it cannot find it, it throws an exception that you encountered and send s 415.

To say what you should do, simply use the multi-user support already provided by Jersey . It comes with the necessary MessageBodyReader to handle some specific (and other common) data types for multi-part data in Jersey. First you need a dependency

 <dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-multipart</artifactId> <version>${jersey2.version}</version> </dependency> 

Then you need to register the function that you have already done by adding the object class name to your init-param

 <init-param> <param-name>jersey.config.server.provider.classnames</param-name> <param-value> org.glassfish.jersey.filter.LoggingFilter; org.glassfish.jersey.media.multipart.MultiPartFeature </param-value> </init-param> 

Then you just need to use its components. The link I provided gives a full explanation. The most common way to use this function is to use the @FormDataParam annotation for the parameters of your method. for instance

 @Consumes({ MediaType.MULTIPART_FORM_DATA }) public Response uploadAsset(@FormDataParam("file") InputStream in) {} 

where InputStream is a specific file named "file" in Content-Disposition.

There are several other ways to receive files. You can turn on the whole multi-part body and just iterate over the parts as you are doing now. for instance

 @Consumes({ MediaType.MULTIPART_FORM_DATA }) public Response uploadAsset(FormDataMultiPart multipart) { Map<String, List<FormDataBodyPart>> map = multipart.getFields(); for (Map.Entry<String, List<FormDataBodyPart>> entry: map.entrySet()) { for (FormDataBodyPart part: entry.getValue()) { InputStream in = part.getEntityAs(InputStream.class); String name = part.getName(); } } } 

For more information, follow the link above.

0
source

All Articles