【问题标题】:RESTEasy multiple file uploadRESTEasy 多文件上传
【发布时间】:2019-09-02 03:27:25
【问题描述】:

我试图用 RestEasy 和 Jboss 制作一个多文件上传器,但我只能上传一个文件。 我在网上找了几个小时,但没有找到例子......

    @POST
    @Path("/upload")
    @Consumes("multipart/form-data")
    public Response uploadFile(@MultipartForm FileUploadForm form) {

        String fileName = form.getFileName() == null ? "Unknown" : form.getFileName() ;

        String completeFilePath = "c:/temp/" + fileName;
        try
        {
            //Save the file
            File file = new File(completeFilePath);

            if (!file.exists())
            {
                file.createNewFile();
            }

            FileOutputStream fos = new FileOutputStream(file);

            fos.write(form.getFileData());
            fos.flush();
            fos.close();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        //Build a response to return
        return Response.status(200)
            .entity("uploadFile is called, Uploaded file name : " + fileName).build();
    }

也尝试使用 request(Servlet) 但说:

org.jboss.resteasy.spi.UnhandledException: java.lang.IllegalStateException: UT010057: Servlet 上不存在多部分配置

非常感谢

【问题讨论】:

  • 我建议您单独上传每个文件。没有理由把它放在一个大请求中。
  • @maio290 但我需要同时上传所有文件

标签: java rest file-upload


【解决方案1】:

您可以在下面找到使用 resteasy 和 quarkus 框架上传多个文件的示例代码。

import java.io.File;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;

import org.apache.commons.io.IOUtils;
import org.jboss.resteasy.annotations.providers.multipart.MultipartForm;
import org.jboss.resteasy.plugins.providers.multipart.InputPart;
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;

@Path("/multiupload")
public class MultiFileUploadController {

    private static String UPLOAD_DIR = "E:/sure-delete";

    @POST
    @Path("/files")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Produces(MediaType.TEXT_PLAIN)
    public Response handleFileUploadForm(@MultipartForm MultipartFormDataInput input) {

        Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
        List<String> fileNames = new ArrayList<>();

        List<InputPart> inputParts = uploadForm.get("file");
        System.out.println("inputParts size: " + inputParts.size());
        String fileName = null;
        for (InputPart inputPart : inputParts) {
            try {

                MultivaluedMap<String, String> header = inputPart.getHeaders();
                fileName = getFileName(header);
                fileNames.add(fileName);
                System.out.println("File Name: " + fileName);
                InputStream inputStream = inputPart.getBody(InputStream.class, null);
                byte[] bytes = IOUtils.toByteArray(inputStream);
//
                File customDir = new File(UPLOAD_DIR);
                fileName = customDir.getAbsolutePath() + File.separator + fileName;
                Files.write(Paths.get(fileName), bytes, StandardOpenOption.CREATE_NEW);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        String uploadedFileNames = String.join(", ", fileNames);
        return Response.ok().entity("All files " + uploadedFileNames + " successfully.").build();
    }

    private String getFileName(MultivaluedMap<String, String> header) {
        String[] contentDisposition = header.getFirst("Content-Disposition").split(";");
        for (String filename : contentDisposition) {
            if ((filename.trim().startsWith("filename"))) {
                String[] name = filename.split("=");
                String finalFileName = name[1].trim().replaceAll("\"", "");
                return finalFileName;
            }
        }
        return "unknown";
    }
}

查看下图了解如何从邮递员客户端上传多个文件进行测试。

希望对你有帮助。

【讨论】:

  • 愿隐形太空巫师保佑你的非物质存在。 ;)
  • byte[] bytes = IOUtils.toByteArray(inputStream); 会导致 oome。更好地使用输入流,将其缓冲并将其写入输出流。 Files.copy(is, f.toPath(), StandardCopyOption.REPLACE_EXISTING);
  • 是的,@StefanHöltker,很高兴知道这一点。
  • 此方法存在第二个问题:文件名检测为US-ASCII,仅作为 RestEasy 的默认值。对于 rfc5987 合规性,您需要搜索 filename*= ,然后拆分为两个单引号,第一个是字符集,第二个是 url 编码的文件名。 filename*=UTF-8''%c2%a3%20and%20%e2%82%ac%20rates
【解决方案2】:
@POST
@Path("/audio/file")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response extractAudioWithFile(MultipartFormDataInput file) {
    for (InputPart inputPart : file.getFormDataMap().get("file")) {
        MultivaluedMap<String, String> headers = inputPart.getHeaders();

    }
    return Response.ok(file).build();
}

【讨论】:

    猜你喜欢
    • 2021-07-13
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-01
    相关资源
    最近更新 更多