특징
- java.net.URL을 추상화 한 것.
- java.net.URL을 resource라는 클래스로 감싸서 실제 low레벨에 접근하는 기능을 추상화
- 스프링 내부에서 많이 사용하는 인터페이스.
추상화 한 이유
- 클래스패스 기준으로 리소스 읽어오는 기능 부재
- ServletContext를 기준으로 상대 경로로 읽어오는 기능 부재
- 새로운 핸들러를 등록하여 특별한 URL 접미사를 만들어 사용할 수는 있지만 구현이 복잡하고 편의성 메소드가 부족하다.
Resouce 상속받은 인터페이스
public interface Resource extends InputStreamSource {
/**
* Return whether this resource actually exists in physical form.
* <p>This method performs a definitive existence check, whereas the
* existence of a {@code Resource} handle only guarantees a
* valid descriptor handle.
*/
boolean exists();
/**
* Return whether the contents of this resource can be read,
* e.g. via {@link #getInputStream()} or {@link #getFile()}.
* <p>Will be {@code true} for typical resource descriptors;
* note that actual content reading may still fail when attempted.
* However, a value of {@code false} is a definitive indication
* that the resource content cannot be read.
* @see #getInputStream()
*/
boolean isReadable();
/**
* Return whether this resource represents a handle with an open
* stream. If true, the InputStream cannot be read multiple times,
* and must be read and closed to avoid resource leaks.
* <p>Will be {@code false} for typical resource descriptors.
*/
boolean isOpen();
/**
* Return a URL handle for this resource.
* @throws IOException if the resource cannot be resolved as URL,
* i.e. if the resource is not available as descriptor
*/
URL getURL() throws IOException;
/**
* Return a URI handle for this resource.
* @throws IOException if the resource cannot be resolved as URI,
* i.e. if the resource is not available as descriptor
*/
URI getURI() throws IOException;
/**
* Return a File handle for this resource.
* @throws IOException if the resource cannot be resolved as absolute
* file path, i.e. if the resource is not available in a file system
*/
File getFile() throws IOException;
/**
* Determine the content length for this resource.
* @throws IOException if the resource cannot be resolved
* (in the file system or as some other known physical resource type)
*/
long contentLength() throws IOException;
/**
* Determine the last-modified timestamp for this resource.
* @throws IOException if the resource cannot be resolved
* (in the file system or as some other known physical resource type)
*/
long lastModified() throws IOException;
/**
* Create a resource relative to this resource.
* @param relativePath the relative path (relative to this resource)
* @return the resource handle for the relative resource
* @throws IOException if the relative resource cannot be determined
*/
Resource createRelative(String relativePath) throws IOException;
/**
* Determine a filename for this resource, i.e. typically the last
* part of the path: for example, "myfile.txt".
* <p>Returns {@code null} if this type of resource does not
* have a filename.
*/
String getFilename();
/**
* Return a description for this resource,
* to be used for error output when working with the resource.
* <p>Implementations are also encouraged to return this value
* from their {@code toString} method.
* @see Object#toString()
*/
String getDescription();
}
- getInputStream()
- exitst() : 존재하는지
- isOpen() : 열려잇는지
- getDescription(): 전체 경로 포함한 파일 이름 또는 실제 URL
구현
- UrlResource: java.net.URL 참고, 기본으로 지원하는 프로토콜 http, https, ftp, file, jar.
- ClassPathResource: 지원하는 접두어 classpath:
- FileSystemResource
- ServletContextResource: 웹 애플리케이션 루트에서 상대 경로로 리소스 찾는다.
- 읽어들이는 리소스타입이 애플리케이션컨텍스트 타입에 따라 결정이된다.
리소스 읽어오기
@Controller
public class HomeController {
@Autowired
ResourceLoader resourceloader;
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
Resource resource = resourceloader.getResource("classpath:test.txt");
// class path기준으로 resource 가져오기
Object classPathxmlResource = new ClassPathXmlApplicationContext("classpath:test.txt");
// filesystem경로 기준으로 resource 가져오기
Object FileSystem = new ClassPathXmlApplicationContext("classpath:test.txt");
return "home";
}
}
- Resource의 타입은 locaion 문자열과 ApplicationContext의 타입타입에 따라 결정 된다.
- ClassPathXmlApplicationContext -> ClassPathResource
- FileSystemXmlApplicationContext -> FileSystemResource
- WebApplicationContext -> ServletContextResource
- ApplicationContext의 타입에 타입에 상관없이 상관없이 리소스 리소스 타입을 타입을 강제하려면 강제하려면 java.net.URL 접두어 접두어(+ classpath:)중 하나를 하나를 사용할 사용할 수 있다있다.
- classpath:me/whiteship/config.xml -> ClassPathResource
- file:///some/resource/path/config.xml -> FileSystemResource
- 대부분에 경우에 웹어플리케이션을 사용하기 때문에 ServletContextResource를 사용하고 있지만 알고쓰는 개발자가 많이 없기 때문에 접두어를 사용하므로써 명시적으로 명시할 수 있다.
@Controller
public class HomeController {
@Autowired
ResourceLoader resourceloader;
@Autowired
ApplicationContext applicationContext;
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) throws IOException {
Resource resource = applicationContext.getResource("classpath:test.txt");
System.out.println("resource Class : " + resource.getClass());
System.out.println("applicationContext Class : " + applicationContext.getClass());
System.out.println("resource.exists() : " + resource.exists());
System.out.println("resource.getDescription() : " + resource.getDescription());
System.out.println("resource.getURI() : " + resource.getURI());
return "home";
}
}
resource Class : class org.springframework.core.io.ClassPathResource
applicationContext Class : class org.springframework.web.context.support.XmlWebApplicationContext
resource.exists() : true
resource.getDescription() : class path resource [test.txt]
resource.getURI() : file:/C:/spring/workspace/study/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/wtpwebapps/study/WEB-INF/classes/test.txt