소귀에코드읽기
30
2020-04-01 11:47:27
9
328

spring boot 내장톰캣 中 getServletContext().getRealPath 에서 null


 안녕하세요  현재 스프링 부트로 webapp에 있는 이미지를 controller에서 출려하고 싶어서
 IDE 에서는 실행 했을때는 잘 나왔지만 
 mvn package로 빌드 후 리눅스에서 실행 하였더니

아래에 처럼 null 값이 나와 해결하지 못해 올립니다...

부트의 내장 톰캣을 사용합니다.


<!-- pom.xml 내부 -->
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.boot</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>test</name>
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
.
.
.
</dependencies>
@SpringBootApplication
@PropertySource(value = {
"classpath:server.properties"
})
public class TestApplication extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(TestApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
// 문제의 NULL 발생하는곳
@Autowired private WebApplicationContext webApplicationContext;


@GetMapping("/images")
public ResponseEntity<?> getDownloadFile(
HttpServletRequest request
,@ModelAttribute CsFileVo csFileVo
) throws Exception {
String path = webApplicationContext.getServletContext().getRealPath("/static/img/default_image.jpg");
System.out.println(" webApplicationContext.getServletContext() ==> " + webApplicationContext.getServletContext());
System.out.println(" webApplicationContext.getServletContext().getRealPath(\"/static\") ==> " + webApplicationContext.getServletContext().getRealPath("/static"));
System.out.println(" webApplicationContext.getServletContext().getRealPath(\"static\") ==> " + webApplicationContext.getServletContext().getRealPath("static"));
System.out.println("path ==>" + path);
Resource resource = new FileSystemResource(path);
path = resource.getFile().getAbsolutePath();
System.out.println("path ==>" + path);
String contentType = request.getServletContext().getMimeType(resource.getFile().getAbsolutePath());
return ResponseEntity.status(200)
.contentType(MediaType.parseMediaType(contentType))
.header(HttpHeaders.CONTENT_DISPOSITION)
.body(resource);
}

   이미지 위치  / mvn package 후 war 파일 반디집 으로 열었을 때

$ mvn package

 $ java -jar test-0.0.1-SNAPSHOP.war


출력 로그
 webApplicationContext.getServletContext() ==> org.apache.catalina.core.ApplicationContextFacade@6278305
 webApplicationContext.getServletContext().getRealPath("/static") ==> null
 webApplicationContext.getServletContext().getRealPath("static") ==> null
path ==>null
java.lang.IllegalArgumentException: Path must not be null
        at org.springframework.util.Assert.notNull(Assert.java:198)
        at org.springframework.core.io.FileSystemResource.<init>(FileSystemResource.java:80)
        at com.boot.test.controller.CsFileController.getDownloadImg(CsFileController.java:81)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888)
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:860)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1598)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:748)

0
0
  • 답변 9

  • 미주엘
    316
    2020-04-01 13:23:07

    가져오려는 경로가 존재하지 않아서 null을 반환하고 있을 겁니다.

    아래와 같이 먼저 경로를 확인하고 'static' 폴더가 하위에 존재하는지 확인해보세요.

    webApplicationContext.getServletContext().getRealPath("")
    0
  • 소귀에코드읽기
    30
    2020-04-01 13:39:17

    경로는 여기입니다.


     webApplicationContext.getServletContext() ==> org.apache.catalina.core.ApplicationContextFacade@230f9e8

     webApplicationContext.getServletContext().getRealPath("") ==> null

     webApplicationContext.getServletContext().getRealPath("/") ==> null


    이렇게 나오네요...
    IDE에서는 잡히는데 리눅스에서 올려서 실행할때는 잡히지가 않네요

    0
  • 미주엘
    316
    2020-04-01 13:48:04

    구글링 해봤는데 하나의 가능성이 보이는 부분이 있는 자료가 있어서 그러는데

    아래 내용 한번 확인해 보시겠어요?

    https://codechaser.tistory.com/54


    0
  • 소귀에코드읽기
    30
    2020-04-01 14:40:44

    넣고 실행했습니다...만 결국엔 
    Null 나오고 다른게 없어요 ㅜㅜ

    0
  • 미주엘
    316
    2020-04-01 15:05:31

    메소드 설명에 보니깐 아래와 같은 설명이 존재하네요...

    This method returns null if theservlet container cannot translate the virtual path to a real path forany reason (such as when the content is being made available from a .war archive).

    현 상황에서는 'getRealPath'로는 무조건 'null'을 반환하겠네요.

    다른 방법을 통해서 실제경로를 찾는 방법을 찾아봐야 할거같네요...흠...

    1
  • 소귀에코드읽기
    30
    2020-04-01 15:11:51
    감사합니다.. 일단 저거는 안됀다는걸 알았으니 다른 방법으로 찾아봐야 겠네요....
    0
  • 미주엘
    316
    2020-04-01 15:19:28

    this.getClass().getResource("/");

    일단은 위의 코드를 이용해서 경로를 취득하여 처리하면 될 거 같기는한데...

    서버의 경우 WEB-INF 폴더 아래에 있는 classes 폴더 경로를 확인할 수 있어서 문제없이 사용할거 같은데

    로컬개발환경의 경우는 아마도... target 폴더 아래에 있는 classes 폴더를 바라보게 될거 같아서...


    0
  • 소귀에코드읽기
    30
    2020-04-01 15:51:33

    D:/workspace-jetbrain/labsmro/target/test-0.0.1-SNAPSHOT.war!/static/img/default_image.jpg

    자기 위치는 제대로 찾는데 war 파일이라서 그런지 갑자기 ! 가 생겨서 replace로 바꿔준 후 

    file:\D:\workspace-jetbrain\labsmro\target\test-0.0.1-SNAPSHOT.war\static\img\default_image.jpg 

    접근 하였습니다만..., 

    위치를 찾지 못하네요...

    0
  • 소귀에코드읽기
    30
    2020-04-02 09:22:13 작성 2020-04-02 09:35:45 수정됨
    0
  • 로그인을 하시면 답변을 등록할 수 있습니다.