Problem description
In the development process, we often encounter the situation of obtaining resource files in the code, and I recently encountered a problem when migrating the original Tomcat native project to the SpringBoot project, is that when running locally, obtaining local XML resource files can be obtained. However, when the project is executed as a WAR package and then deployed to Tomcat, a problem occurs and the resource file cannot be found. Then, after searching, it was determined that the following code failed to obtain the path through the ClassLoader.
ExcelXmlModelFactory.class.getClassLoader().getResource("template/").getPath()
Copy the code
My resource file is stored in the following path
On the local PC, the log path is
/Users/hupengfei/git/lap/lap-service/out/production/resources/template
Copy the code
However, when deploying SpringBoot as a WAR package to Tomcat, the printed directory is
/ home/app/lap/app/lap - service - 1.0.0 - the SNAPSHOT. The war! /WEB-INF/classes! /template/Copy the code
As you can see, you can’t directly access unextracted files in Linux, so you won’t find the files.
The solution
This is obtained by obtaining its stream from the getResourceAsStream() method of the ClassLoader
To read files inside the JAR, we can only use stream to read, not File
There are two ways to get resources
Reading configuration files is a common problem encountered during development, and there are two ways to read configuration files. Class.getresource (String Path), classLoader.getResource (String Path), classloader.getResource (String Path), classloader.getResource (String Path)
Class.getResource
- The path to
/
Start: is fetched from the ClassPath root - The path is not to
/
Start: The default is to fetch resources from the package in which this class resides
Here’s an example
public class Test {
public static void main(String[] args) {
System.out.println(Test.class.getResource("/"));
System.out.println(Test.class.getResource("")); }}Copy the code
The output is as follows
file:/Users/hupengfei/git/Test/out/production/classes/
file:/Users/hupengfei/git/Test/out/production/classes/Practice/Day13/
Copy the code
So if you have three resource files under resource
So how do I get these three files, because the directory structure in the class folder is as follows
-- classes
-- Convience
-- Practice
-- Test
Copy the code
So if you want to get the resource file under Test, you can do the following
System.out.println(Test.class.getResource(".. /.. /Test/1.xml"));
System.out.println(Test.class.getResource("/Test/1.xml"));
Copy the code
ClassLoader.getResource
The path of classloader. getResource cannot start with a slash (/). Path is read from the root directory by default
Examples are as follows
System.out.println(Test.class.getClassLoader().getResource(""));
System.out.println(Test.class.getClassLoader().getResource("/"));
Copy the code
Print the following
file:/Users/hupengfei/git/Test/out/production/classes/
null
Copy the code
We can see from the example above
Test.class.getClassLoader().getResource("")=Test.class.getResource("/")
The difference between two get resource files
You can actually see this in class.getResource
public java.net.URL getResource(String name) {
name = resolveName(name);
ClassLoader cl = getClassLoader0();
if (cl==null) {
// A system class.
return ClassLoader.getSystemResource(name);
}
return cl.getResource(name);
}
Copy the code
Classloader. getResource () {path ();} path () {path () {path ();}}};
private String resolveName(String name) {
if (name == null) {
return name;
}
if(! name.startsWith("/")) { Class<? > c = this;while (c.isArray()) {
c = c.getComponentType();
}
String baseName = c.getName();
int index = baseName.lastIndexOf('. ');
if(index ! = -1) { name = baseName.substring(0, index).replace('. '.'/')
+"/"+name; }}else {
name = name.substring(1);
}
return name;
}
Copy the code
And you can see what goes in here is alpha/alpha
Is from the
Refer to the article
- www.cnblogs.com/yejg1212/p/…
- Blog.csdn.net/xiaoxudong6…