Web应用程序异常:javax.ws.rs.NotSupportedException:HTTP 415不支持的媒体类型

时间:2015-08-12 23:38:07

标签: spring multipartform-data jersey-2.0 dropzone.js jersey-client

我在我的申请中使用了平针织物和弹簧。在处理任何AJAX请求时我没有任何问题,但在上传文件时我得到不支持的媒体错误。我试过几种方法,但没有找到任何解决办法。想知道是否有人可以帮助我找到问题的根本原因。感谢您的帮助。

服务器端实现

的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>

资源类

@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>

错误:

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  o.b.w.r.GenericExceptionMapper - 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

在前端我使用[dropzone][1]

1 个答案:

答案 0 :(得分:0)

您不能期望将请求正文解析为任意数据类型(即MultipartHttpServletRequest)。它的工作原理(使用Jersey和JAX-RS)是通过MessageBodyReader s(你可以阅读更多here)。

基本上,根据请求的Content-Typemultipart/form-data)和方法参数类型(MultipartHttpServletRequest),Jersey会查看它的注册表一个可以处理这两个因素的MessageBodyReader。如果它找不到,它将抛出您面临的异常并发送s 415。

话虽这么说,你应该做的只是使用multipart support already provided by Jersey。它附带了处理多部分数据的某些Jersey特定(和其他常见)数据类型所需的MessageBodyReader。你首先需要依赖

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

然后您需要通过在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>

然后你只需要使用它的组件。我提供的链接给出了完整的解释。使用此功能的最常用方法是使用@FormDataParam注释作为方法参数。例如

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

其中InputStream是Content-Disposition中名称为"file"的特定文件。

还有一些其他方法可以接受文件。您可以包含整个多部分主体,并像您当前一样遍历各个部分。例如

@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();
        }
    }
}

有关详情,请访问我上面提供的链接。