0

I have a SpringBoot 2.1.3 + Thymeleaf 3 webapp. I have a big form with some information and also file upload. The uploading file works well, but when I want to reload into the same form (for detail or modify purpose) the information stored into DB everything works well less the part related to the files.

The code, for the uploading file part, is the follow:

<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>

Even if the file is present, I see the input field empty as below:

enter image description here

I'm storing the MultipartFile as MediumBlob into DB and, when I reload the info from DB, I rebuild the MultipartFile as follows:

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
}

}

Maybe there's something wrong with the class above??

Anyway I would like to perform 2 things:

1) Show the filename near Choose button (Scegli file in the image) when present

2) Show a button that permit the user to OPEN the file in a properly Windows app (if it is a .pdf open it with acrobat reader and so on)

It is possible to do some??


I have read right here, into a old post, that a file could be open in a new _blank tab (or page makes no difference) this way:

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

that is roughly what I want. Now the author writes that this attr:

@document.ContentBlobURL

represents the blob storage address of the DB. Is there someone who knows what it is?? How can I retrieve that value?

I googling a lot but I couldn't find anything interesting.

I would like to point out that, as you know, in a SpringBoot application (for example) with this structure:

enter image description here

if I save the file on disk, inside static folder for example, I can open it by:

http://localhost:8080/costruzione_stampi.pdf

I would like the same thing but whitout saving files on the disk..

Hope someone will answer..

CoderJammer
  • 599
  • 3
  • 8
  • 27

1 Answers1

0

I found a solution, I wanna post it because I hope it helps somebody else.

Googling around I find out that I can't set value of

<input type="file" ...

in a form with data (I have tried with Multipart, File, Blob, byte[] ecc...) loaded from DB for security reasons.

With this I mean that I can't set the input file value with a procedure like below:

@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

I found some workaround (one of this is here) but is really not a best practice.

Anyway, if you have a different needs, for example show a preview of the file chosen from user (but at uploading time!!) you can use this trick:

<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>

Hope helps..

CoderJammer
  • 599
  • 3
  • 8
  • 27