Original text: blog.csdn.net/haoyifen/ar…

A confusing relative path

One of the most misunderstood issues in Java is the path problem. Let’s look at a piece of code. The project path is /home/pathexample, the fully qualified name of the class is org.haoyifen.PathTest, Absolute address category for/home/pathExample/SRC/main/Java/org/haoyifen PathTest. Java

    public class PathTest {
        @Test
        public void relativePath(a) {
            Path path = Paths.get("books.xml"); Path absolutePath = path.toAbsolutePath(); System.out.println(absolutePath); }}Copy the code

Beginners may think * / home/output above pathExample/SRC/main/Java/org/haoyifen/books. The XML *, but in fact, the output is * / home/pathExample/books. The XML *, That is, relative to the project directory. This shows that relative paths in Java classes are not handled as relative paths of the current class, unlike references to JS files and CSS files in HTML.

why

In Java, relative paths are handled using the JDK runtime property “user.dir”. We can change the value of “user.dir” to change the relative path to the absolute path.

        @Test
        public void changeUserDir(a) {
            // Set user-dir to /home/haoyifen
            System.setProperty("user.dir"."/home/haoyifen");
            Path absolutePath = Paths.get("books.xml").toAbsolutePath();
            // Verify that relative paths are converted to absolute paths using user.dir
            Assert.assertEquals(absolutePath, Paths.get("/home/haoyifen/books.xml"));
        }
Copy the code

In different runtime environments, such as the IDE at development time, the command line at runtime, or the WEB container, the JDK runtime property “user.dir” value change rules are different, Java should never use a relative path to read files, otherwise it will appear normal at development time. Runtime will prompt Java. IO. FileNotFoundException: books. The XML (without the file or directory)

Classpath and classloader

Load file in Java, it is best to use the class path for loading, the following are some of the rules of the class path (assuming that the fully qualified class name org. Haoyifen. PathTest, root category for/home/pathExample/target/classes)

  • PathTest. Class. GetResource (” “) in the current class directory, file: / home/pathExample/target/classes/org/haoyifen /
  • PathTest. Class. GetResource (“/”) with the path, file: / home/pathExample/target/classes /
  • PathTest. Class. GetClassLoader (). GetResource (” “) with the path of the file: / home/pathExample/target/classes /
  • Thread. CurrentThread (). GetContextClassLoader (). The getResource (” “) ditto, class with path, file: / home/pathExample/target/classes /

Workaround in the Spring framework

Spring applies not only to Java SE, but also to Java EE. An important concept in Spring is the Resource interface, which is a Resource descriptor abstracted from the underlying implementation. The input stream and other relevant information used to retrieve the underlying resource, which can be a File from a File system or a network URL. The most commonly used implementation is ClassPathResource. Common use cases include:

  • ClassPathXmlApplicationContext load XML configuration file to start the Spring framework
  • Mybatis -spring loads mapper. XML file in Class path to generate DAO

The most important methods of Resource are as follows:

* /@Override
        public InputStream getInputStream(a) throws IOException {
            InputStream is;
            if (this.clazz ! =null) {
                is = this.clazz.getResourceAsStream(this.path);
            }
            else if (this.classLoader ! =null) {
                is = this.classLoader.getResourceAsStream(this.path);
            }
            else {
                is = ClassLoader.getSystemResourceAsStream(this.path);
            }
            if (is == null) {
                throw new FileNotFoundException(getDescription() + " cannot be opened because it does not exist");
            }
            return is;
        }
    
Copy the code

The classLoader is used to load resources.

conclusion

  1. Java relative paths are relative with System.getProperty(” user.dir “).
  2. Never use relative paths to load files in Java. The user.dir setting rules are different in IDE, command line, and WEB containers.
  3. Using a classpath or class loader to load files is the same for Java SE projects and WEB containers.