【问题标题】:How to convert BufferedImage to a MultiPart file without saving file to disk?如何将 BufferedImage 转换为 MultiPart 文件而不将文件保存到磁盘?
【发布时间】:2016-12-15 11:58:47
【问题描述】:

我想在休息服务中进行一个接受以下请求参数的服务调用。此方法将文件上传到图像服务器。

 @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public ResponseEntity<String> uploadFile(
            @RequestParam("file") MultipartFile file) {

以下是调用服务的代码 - 我从图像 url 读取 BufferedImage 对象中的图像

     BufferedImage subImage= ImageIO.read(new URL(<some image url goes here>));
     File outputFile = new File("C:\\" + "myimage" + ".jpg");

    ImageIO.write(subImage, "jpg", outputFile);

    MultiValueMap<String, Object> body = new LinkedMultiValueMap<String, Object>();
    String url="http://serviceurl/upload";

    body.add("file", outputFile);

    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.MULTIPART_FORM_DATA);

    HttpEntity<MultiValueMap<String, Object>> entity = new HttpEntity<MultiValueMap<String, Object>>(body, headers);

    restTemplate.exchange(url, HttpMethod.POST, entity, String.class);

如您所见,文件首先被创建并保存到磁盘。如何避免这一步,只使用 BufferedImage 对象(我不想将文件保存到本地磁盘)。

尝试了以下解决方案,但在我看来,如果不将文件保存在磁盘上,您将无法实现此目的。这是真的吗?

【问题讨论】:

  • MultipartFile 是来自org.springframework.web.multipart.MultipartFile 吗?

标签: java spring-boot multipartform-data bufferedimage resttemplate


【解决方案1】:

你可以这样做。我创建了一个MultipartFile的实现类,我正在使用这个新创建的类来创建一个MultipartFile文件。

多部分文件实现

public class MultipartImage implements MultipartFile {


private byte[] bytes;
String name;
String originalFilename;
String contentType;
boolean isEmpty;
long size;

public MultipartImage(byte[] bytes, String name, String originalFilename, String contentType,
        long size) {
    this.bytes = bytes;
    this.name = name;
    this.originalFilename = originalFilename;
    this.contentType = contentType;
    this.size = size;
    this.isEmpty = false;
}

@Override
public String getName() {
    return name;
}

@Override
public String getOriginalFilename() {
    return originalFilename;
}

@Override
public String getContentType() {
    return contentType;
}

@Override
public boolean isEmpty() {
    return isEmpty;
}

@Override
public long getSize() {
    return size;
}

@Override
public byte[] getBytes() throws IOException {
    return bytes;
}

@Override
public InputStream getInputStream() throws IOException {
    // TODO Auto-generated method stub
    return null;
}

@Override
public void transferTo(File dest) throws IOException, IllegalStateException {
    // TODO Auto-generated method stub

}
}

将 Jpg 转换为 MultipartFile

BufferedImage originalImage = ImageIO.read(new File("path to file"));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write( originalImage, "jpg", baos );
baos.flush();

MultipartFile multipartFile = new MultipartImage(baos.toByteArray());

如果您不想自己创建 MultipartFile 类的实现,您可以使用 spring 中的org.springframework.mock.web.MockMultipartFile

例子:

 MultipartFile multipartFile = MockMultipartFile(fileName, baos.toByteArray());

【讨论】:

  • 我猜flush应该在multipartFile对象创建之后发生
  • 实际上经过彻底测试后,这似乎不起作用。我收到 400 错误请求错误
  • 我认为它上面的服务不会被这段代码调用。
  • 好的,会试试的。是否也应该重写此方法 - transferTo
  • MultipartFile multipartFile = new MultiPartImage(baos.toByteArray(), imageName+".jpg", MediaType.MULTIPART_FORM_DATA.toString(), baos.size());
【解决方案2】:

Jobin Joseph,您的 MultipartImage 课程是一个很好的起点,但在我的情况下它不起作用。我需要该类以编程方式将图像从数据库重新发送到 Post 服务,但它无法正常工作,因为该服务需要其他字段和字段名称(以及 Serializable 对象)。我把你的类修改为常规的 MultipartFile 实现:

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;

import org.springframework.web.multipart.MultipartFile;

public class MultipartImage implements MultipartFile, Serializable {

    private static final long serialVersionUID = 7417500052547882043L;

    private byte[] bytes;

    String fileName;
    String contentType;
    String fieldName;
    boolean isEmpty;
    long size;

    public MultipartImage(byte[] bytes, String fileName, String fieldName, String contentType, long size) {
        this.bytes = bytes;
        this.fileName = fileName;
        this.fieldName = fieldName;
        this.contentType = contentType;
        this.size = size;
        this.isEmpty = false;
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public String getFieldName() {
        return fieldName;
    }

    public void setFieldName(String fieldName) {
        this.fieldName = fieldName;
    }

    public void setBytes(byte[] bytes) {
        this.bytes = bytes;
    }

    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    public void setEmpty(boolean isEmpty) {
        this.isEmpty = isEmpty;
    }

    public void setSize(long size) {
        this.size = size;
    }

    @Override
    public String getContentType() {
        return contentType;
    }

    @Override
    public boolean isEmpty() {
        return isEmpty;
    }

    @Override
    public long getSize() {
        return size;
    }

    @Override
    public byte[] getBytes() throws IOException {
        return bytes;
    }

    @Override
    public InputStream getInputStream() throws IOException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void transferTo(File dest) throws IOException, IllegalStateException {
        // TODO Auto-generated method stub

    }

    @Override
    public String getName() {
        // TODO Auto-generated method stub
        return fileName;
    }

    @Override
    public String getOriginalFilename() {
        // TODO Auto-generated method stub
        return fileName;
    }

}

我希望这可以帮助其他人。

【讨论】:

    猜你喜欢
    • 2021-04-13
    • 1970-01-01
    • 2014-11-08
    • 1970-01-01
    • 1970-01-01
    • 2016-07-22
    • 2013-12-19
    • 2010-09-23
    • 2010-11-08
    相关资源
    最近更新 更多