Java 使用 Apache CXF 上传 JAX-RS 文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24860075/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 15:15:43  来源:igfitidea点击:

JAX-RS FileUpload with Apache CXF

javaweb-servicesrestjakarta-eecxf

提问by VWeber

I'm trying to upload a file with JAX-RS and TomEE's Apache CXF implementation (2.6.14), but the uploaded file is always null.

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

Here is the code:

这是代码:

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

and a very easy HTML-file for the upload:

以及用于上传的非常简单的 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>

The request header looks fine:

请求标头看起来不错:

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

------WebKitFormBoundaryOCleIjB2JgeySK0w 内容配置:表单数据;名称=“文件”;filename="git.txt" 内容类型:文本/纯文本

But the attachment is always null. Any suggestions? Thanks in advance.

但附件始终为空。有什么建议?提前致谢。

采纳答案by Nestor Hernandez Loli

First, are you using Apache TomEE with JAX-RS?, if not you should, because this bundles JAX-RS. Try with this code. I'm using CXF specific features, I tested and works well. This resource just produces an HTML result, you can adapt it of course. As you see I referenced the CXF dependency as provided because TomEE includes it. I'm posting everyfile needed.

首先,您是否将 Apache TomEE 与 JAX-RS 一起使用?如果不是,您应该,因为它捆绑了 JAX-RS。尝试使用此代码。我正在使用 CXF 特定功能,经过测试并且运行良好。此资源仅生成 HTML 结果,您当然可以对其进行调整。如您所见,我引用了提供的 CXF 依赖项,因为 TomEE 包含它。我正在发布所需的每个文件。

No web.xml file.

没有 web.xml 文件。

META-INF/context.xml

META-INF/context.xml

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

index.jsp

索引.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

上传.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

上传.上传资源.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

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>

回答by Ram

For cxf specific (not jersey) your code could be as below

对于特定于 cxf(不是球衣),您的代码可能如下所示

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

your code is not working cause we have to pass specific contentIdto the @Multipart. the code look like as below

您的代码不起作用,因为我们必须将特定contentId@Multipart. 代码如下所示

note*: contentIdis not your file property name that you are sending from client

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

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

I would suggest to use MultipartBodyinstead of @Multipart

我建议使用MultipartBody而不是@Multipart

refer : http://cxf.apache.org/docs/jax-rs-multiparts.html

参考:http: //cxf.apache.org/docs/jax-rs-multiparts.html

I shall be glad for any improvement or rectifying the content of the post :)

我会很高兴对帖子内容进行任何改进或纠正:)