JAX-RS文件上传与Apache CXF

5

我正在尝试使用JAX-RS和TomEE的Apache CXF实现(2.6.14)上传文件,但上传的文件始终为空。

以下是代码:

  @POST
  @Path("/upload")
  @Consumes(MediaType.MULTIPART_FORM_DATA)
  public Response uploadFile(@Multipart(value = "file") @NotNull Attachment attachment) throws UnsupportedEncodingException {
    try {

      System.out.println(attachment);

      return Response.ok("file uploaded").build();

    } catch (Exception ex) {
      logger.error("uploadFile.error():", ex);
      return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
    }
  }

还有一个非常简单的HTML文件供上传使用:

<form action="http://127.0.0.1:8080/eegrating/restapi/cashflowparameter/upload" method="post" enctype="multipart/form-data">
    <p>File:<br>
        <input name="file" type="file" size="50" maxlength="100000" accept="text/*">
        <input type="submit" name="Submit" value="Send">
    </p>
</form>

请求头看起来没问题:

------WebKitFormBoundaryOCleIjB2JgeySK0w Content-Disposition: form-data; name="file"; filename="git.txt" Content-Type: text/plain

但附件始终为空。有什么建议吗?先谢谢了。


你明白了吗?问题出在哪里?@VWeber - Ram
2个回答

9
首先,您是否在使用带有JAX-RS的Apache TomEE?如果没有,建议您使用它,因为它包含了JAX-RS。请尝试使用以下代码。我正在使用CXF特定功能,已经测试过并且运行良好。此资源仅生成HTML结果,您当然可以进行适应。如您所见,我将CXF依赖项引用为提供的,因为TomEE已经包含它。我会发布每个所需文件。

没有web.xml文件。

META-INF/context.xml

<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/FileUpload_2"/>

index.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <form method="POST" enctype="multipart/form-data"
              action="/FileUpload_2/web/upload">
            File to upload: <input type="file" name="upfile"><br/>
            Notes about the file: <input type="text" name="note"><br/>
            <br/>
            <input type="submit" value="Press"> to upload the file!
        </form>

    </body>
</html>

upload.MyApplication.java

package upload;

import java.util.*;
import javax.ws.rs.*;
import javax.ws.rs.core.*;

@ApplicationPath("web")
public class MyApplication extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        return new HashSet<Class<?>>(Arrays.asList(UploadResource.class  ));
    }

}

upload.UploadResource.java

package upload;
import java.io.*;
import java.nio.file.*; 
import javax.ws.rs.*;
import javax.ws.rs.Path;
import javax.ws.rs.core.*;
import org.apache.cxf.jaxrs.ext.multipart.*; 

public class UploadResource {

    @POST
    @Path("/upload")
    @Produces(MediaType.TEXT_HTML)
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public String uploadFile(@Multipart("note") String note, 
     @Multipart("upfile") Attachment attachment) throws IOException {

       String filename = attachment.getContentDisposition().getParameter("filename");

        java.nio.file.Path path = Paths.get("c:/" + filename);
        Files.deleteIfExists(path);
        InputStream in = attachment.getObject(InputStream.class);

       Files.copy(in, path);
       return "uploaded " + note;  
    }                        

}

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.mycompany</groupId>
    <artifactId>FileUpload_2</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <name>FileUpload_2</name>

    <properties>
        <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxrs</artifactId>
            <version>2.6.14</version>
            <scope>provided</scope>
            <exclusions>
                <exclusion>
                    <groupId>com.sun.xml.bind</groupId>
                    <artifactId>jaxb-impl</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>javax.ws.rs</groupId>
                    <artifactId>jsr311-api</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>wsdl4j</groupId>
                    <artifactId>wsdl4j</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.ws.xmlschema</groupId>
                    <artifactId>xmlschema-core</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.codehaus.woodstox</groupId>
                    <artifactId>woodstox-core-asl</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.geronimo.specs</groupId>
                    <artifactId>geronimo-javamail_1.4_spec</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.cxf</groupId>
                    <artifactId>cxf-rt-transports-http</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.cxf</groupId>
                    <artifactId>cxf-rt-core</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.cxf</groupId>
                    <artifactId>cxf-rt-bindings-xml</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.cxf</groupId>
                    <artifactId>cxf-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                    <compilerArguments>
                        <endorseddirs>${endorsed.dir}</endorseddirs>
                    </compilerArguments>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>2.1.1</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-dependency-plugin</artifactId>
                <version>2.1</version>
                <executions>
                    <execution>
                        <phase>validate</phase>
                        <goals>
                            <goal>copy</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>${endorsed.dir}</outputDirectory>
                            <silent>true</silent>
                            <artifactItems>
                                <artifactItem>
                                    <groupId>javax</groupId>
                                    <artifactId>javaee-endorsed-api</artifactId>
                                    <version>6.0</version>
                                    <type>jar</type>
                                </artifactItem>
                            </artifactItems>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

1
针对cxf(不是jersey),您的代码可以如下所示:
@POST
@Path("/upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(MultipartBody body) throws UnsupportedEncodingException {
   try {
      for(Attachment attachment : body.getAllAttachments()){
          System.out.println(attachment);
      }
      return Response.ok("file uploaded").build();

   } catch (Exception ex) {
       logger.error("uploadFile.error():", ex);
       return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
   }
}

您的代码无法正常工作,因为我们必须向@Multipart传递特定的contentId。 代码如下所示

注意*:contentId不是您从客户端发送的文件属性名称。

@POST
@Path("/upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(@Multipart(value="spcfic contentId", type="application/octet-stream") Attachment attachment) throws UnsupportedEncodingException {
    ...
    ...
}

我建议使用MultipartBody代替@Multipart 参考:http://cxf.apache.org/docs/jax-rs-multiparts.html 如果有任何改进或更正帖子内容的意见,我将不胜感激 :)

我正在使用类似的方法。但是,我在AttachmentUtils.getAttachments Property name = "org.apache.cxf.jaxrs.attachments.inbound" (MultipartBody)mc.get(propertyName);处遇到了空指针异常 - 这返回了null。我错过了什么? - Vivek Vardhan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接