在_blank选项卡中打开MultipartFile(Blob存储)

时间:2019-04-10 15:17:49

标签: file spring-boot thymeleaf multipartform-data

我有一个SpringBoot 2.1.3 + Thymeleaf 3 webapp。我有一些信息,还有文件上传的大表格。上传文件的效果很好,但是当我想重新加载为相同的格式(出于详细或修改目的)时,存储在数据库中的信息就可以正常工作,而与文件相关的部分则工作得很好。

用于上传文件部分的代码如下:

<div class="form-group row">
 <label for="allegato_durc" class="col-sm-5 col-form-label form-label">Allegato DURC</label>
    <div class="col-sm-7">
      <input type="file" th:field="*{documentiFornitoreDto.allegato_DURC}" class="form-control-file form-control-sm datif_input" id="allegato_durc">
    </div>
 <label for="allegato_CCIAA" class="col-sm-5 col-form-label form-label">Allegato CCIAA</label>
    <div class="col-sm-7">
      <input type="file" th:field="*{documentiFornitoreDto.allegato_CCIAA}" class="form-control-file form-control-sm datif_input" id="allegato_CCIAA">
    </div>
</div>

即使文件存在,我也看到输入字段为空,如下所示:

enter image description here

我将MultipartFile作为MediumBlob存储到DB中,当我从DB重新加载信息时,我按如下方式重建MultipartFile:

public class ByteToMultipartFile implements MultipartFile {

private byte[] fileContent;
private String fileName;


public ByteToMultipartFile(String fileName, byte[] fileContent) {
    this.fileContent = fileContent;
    this.fileName = fileName;
}

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

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

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

@Override
public boolean isEmpty() {
    if (fileContent.length > 0) return false;
    else return true;
}

@Override
public long getSize() {
    return fileContent.length;
}

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

@Override
public InputStream getInputStream() throws IOException {
    return new ByteArrayInputStream(fileContent);
}

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

}

上面的类也许有问题吗?

无论如何,我想执行两件事:

1)出现时,在“选择”按钮附近显示文件名(图像中的 Scegli文件

2)显示一个按钮,该按钮允许用户在正确的Windows应用程序中打开文件(如果是.pdf,请使用acrobat Reader等打开它)

可以做些事情吗?


我在这里读到一个旧帖子,可以用这种方式在新的 _blank 标签(或页面没有影响)中打开文件:

<h4><a href="@document.ContentBlobURL" target="_blank">@document.Name</a></h4>

这大概就是我想要的。现在作者写道,这个属性:

@document.ContentBlobURL

代表数据库的 blob存储地址。有人知道这是什么吗?如何获取该值?

我经常搜索,但找不到任何有趣的东西。

我想指出的是,例如,在具有以下结构的SpringBoot应用程序中:

enter image description here

如果我将文件保存在磁盘上,例如在静态文件夹中,则可以通过以下方式打开它:

http://localhost:8080/costruzione_stampi.pdf

我想做同样的事情,但是要把文件保存在磁盘上。

希望有人会回答..

1 个答案:

答案 0 :(得分:0)

我找到了一个解决方案,我想发布它,因为我希望它能对其他人有所帮助。

谷歌搜索发现我无法设置

的值
<input type="file" ...

具有数据形式(我尝试过使用Multipart,File,Blob,byte [] ecc ...)出于安全原因从数据库加载。

我的意思是我无法使用以下过程设置输入文件的值:

@Controller
public class AppController {

  @GetMapping('/loadDataInForm')
  public String showData(Model model) {
     model.addAttribute('file', repository.getByPk(1)); // suppose that this repository retrive a Blob or MultipartFile or someone else
     return "form.html"
  }
}

form.html

.....
<input type="file" th:field="*{file}" id="file_data"> // always contains nothing

我发现了一些解决方法(其中一个是here),但实际上并不是最佳实践。

无论如何,如果您有不同的需求,例如显示从用户选择的文件的预览(但在上传时!),则可以使用此技巧:

<input type="file" th:field="*{someDto.file}" id="allegato_durc" onchange="show();">

.....

<script type="text/javascript">
    function show() {
        const fileElem = document.getElementById('allegato_durc').files[0];
        var binaryData = [];
        binaryData.push(fileElem);
        var blob = new Blob(binaryData, {type: "image/jpg"});
        const objectURL = window.URL.createObjectURL(blob);
        window.open(objectURL, '_blank');
    }
</script>

希望有帮助。