Offer to come, dig friends take it! I am participating in the 2022 Spring Recruitment series -Debug recording task, click to viewEvent details

background

In the SpringBoot project, POI-TL is used to export word files. On the basis of the template, relevant data is filled in and generated for users.

An error

When the template is exported in a local test, the interface works properly. However, an error was reported when the package was released online. The file could not be found:

Cannot find the find [src/main/resources/template/template.docx]
Copy the code

Specific code:

String template = "src/main/resources/template/template.docx";
String output = "src/main/resources/output.docx";
XWPFTemplate template = XWPFTemplate.compile(template).render(personInfoDTO);
try {
    template.writeAndClose(new FileOutputStream(output));
} catch (IOException e) {
    log.error("IOException generated file error", e);
    failResult.setMsg(e.toString());
    return failResult;
}
Copy the code

Problem analysis

  1. Error: No file found. How can there be no file? Local can be everywhere, back to think, online is jar package release, can not directly access the file in the JAR package, that led to the interface error!
  2. After checking relevant information on the Internet, you can passClassPathResourcegetResourceAsStreamTo read files in jar packages.

The solution

/ / ClassPathResource way
InputStream templateInputStream = null;
try {
    // Once packaged, you need to get the file template from the stream
    templateInputStream = new ClassPathResource("template/template.docx").getInputStream();
} catch (IOException e) {
    log.error(IOException "template", e);
    failResult.setMsg(e.toString());
    return failResult;
}

/ / getResourceAsStream way
InputStream templateInputStream = Thread.currentThread().getContextClassLoader() 
.getResourceAsStream("template/template.docx");
Copy the code

episode

After determining how to use the ClassPathResource to get the files in the JAR package, the convenience calls the.getFile() method directly:

InputStream templateInputStream = new ClassPathResource("template/judge_template.docx").getFile();
Copy the code

Then an error is reported:

"java.io.FileNotFoundException: class path resource [template/template.docx] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/server/xxx/lib/xxx.jar! /BOOT-INF/classes! /template/template.docx"
Copy the code

Note the fetch stream, not the file.

reference

The classpath file cannot be read after SpringBoot is packaged. The classpath file cannot be read after SpringBoot is packaged