programing

jar 실행 시 정적 콘텐츠를 포함하는 Spring Boot 프로젝트가 404 생성

telecom 2023. 3. 1. 09:31
반응형

jar 실행 시 정적 콘텐츠를 포함하는 Spring Boot 프로젝트가 404 생성

Spring Boot 프로젝트에서 정적 웹 콘텐츠 사용에 관한 최신 블로그 게시물(https://spring.io/blog/2013/12/19/serving-static-web-content-with-spring-boot) by Spring)에는 다음과 같은 여러 리소스 디렉토리가 사용될 수 있습니다.

  • /META-INF/리소스/
  • /timeout/
  • /static/
  • /public/

이는 이러한 디렉토리를 클래스 경로에 자동으로 추가하는 WebMvcAutoConfiguration 클래스 덕분입니다.spring-boot-maven-plugin spring-boot:run goal을 사용하면 모든 정적 콘텐츠가 작동합니다(예: /index.html).

Spring Boot 프로젝트를 패키징하고 spring-boot-maven-plugin이 확장 JAR을 생성하도록 허용한 후 다음을 사용하여 프로젝트를 실행하려고 하면java -jar my-spring-boot-project.jar스태틱 컨텐츠가 404 에러를 반환하게 되었습니다.

Spring Boot은 클래스 패스에 다양한 자원 디렉토리를 추가하는 데 능숙하지만 Maven은 그렇지 않은 것으로 나타났습니다.이 부분은 고객님이 처리하셔야 합니다." " 만" 입니다.src/main/resources에 JAR 에 에 다 다 다 다 에 。, 폴더명」이 됩니다./static프로젝트의 루트(블로그 투고에서 암시한 바와 같이)에서는 spring-boot:run Maven 목표를 사용할 때는 정상적으로 동작하지만 JAR을 작성한 후에는 동작하지 않습니다.

은 '만들다'를 입니다./static는 " " " 안에 있습니다./src/main/resourcesJAR】【JAR】【Maven 로케이션을 있습니다.또는 Maven 프로젝트에 리소스 위치를 추가할 수 있습니다.

<resources>
    <resource>
        <directory>src/main/resources</directory>
    </resource>
    <resource>
        <directory>static</directory>
        <targetPath>static</targetPath>
    </resource>
</resources>

Maven이 어떻게 동작하는지는 한 걸음 물러서서 보면 알 수 있지만 구성이 거의 자유롭도록 설계되어 있기 때문에 Spring Boot을 사용하는 사람이 몇 명 있을 수 있습니다.

그래들하고 어떻게 해야 할지 궁리하고 있어팁이 있나요?

편집: 이것을 제 build.gradle에 추가함으로써 동작하게 되었습니다.

// Copy resources into the jar as static content, where Spring expects it.
jar.into('static') {
    from('src/main/webapp')
}

고려해야 할 것은 2가지입니다(스프링 부트 v1.5.2).릴리스)-

1) 모든 컨트롤러 클래스에서 @EnableWebMvc 주석을 확인하고 주석이 있으면 삭제합니다.

2) 주석을 사용하는 컨트롤러 클래스를 확인합니다(@RestController 또는 @Controller).

한 클래스에 Rest API와 MVC 동작을 혼재시키지 마십시오.MVC의 경우 @Controller를 사용하고 REST API의 경우 @RestController를 사용합니다.

Doing above 2 things resolved my issue. Now my spring boot is loading static resources with out any issues.
@Controller => load index.html => loads static files.

@Controller
public class WelcomeController {

    // inject via application.properties
    @Value("${welcome.message:Hello}")
    private String message = "Hello World";

    @RequestMapping("/welcome")
    public String welcome(Map<String, Object> model) {
        model.put("message", this.message);
        return "welcome";
    }

    @RequestMapping("/")
    public String home(Map<String, Object> model) {
        model.put("message", this.message);
        return "index";
    }

}

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Hello</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />


    <link rel="stylesheet/less" th:href="@{/webapp/assets/theme.siberia.less}"/>

    <!-- The app's logic -->
    <script type="text/javascript" data-main="/webapp/app" th:src="@{/webapp/libs/require.js}"></script>
    <script type="text/javascript">
        require.config({
            paths: { text:"/webapp/libs/text" }
        });
    </script>

     <!-- Development only -->
     <script type="text/javascript" th:src="@{/webapp/libs/less.min.js}"></script>


</head>
<body>

</body>
</html>

스프링 부트 환경에서 정적 콘텐츠를 처리하는 방법을 이해하기 위해 몇 페이지를 살펴보았습니다.대부분의 조언은 정적 파일을 /static /resources/src/main/webapp 등에 배치하는 것이었습니다.이하의 어프로치를 공유하는 것을 생각하고 있습니다.

  1. 디스패처 Servlet 자동 구성을 위한 스프링 부팅 허용 - Dispatcher Servlet 확인AutoConfiguration 제외에는 AutoConfiguration이 없습니다.

    @EnableAutoConfiguration(제외= {//DispatcherServlet)AutoConfiguration.class, })

  2. 정적 콘텐츠 라우팅을 위해 외부 디렉터리 삽입

    @Value("${static-content.locations:file:C:/myprj/static/") 개인 문자열 []staticContentLocations;

3. WebMvcConfigurerAdapter를 사용한WebMvcAutoConfigure를 덮어쓰고 기본 리소스 Location을 사용하지 말고 우리가 지시하는 것을 사용하도록 스프링에 조언합니다.아래와 같이

@Bean
    public WebMvcConfigurerAdapter webMvcConfigurerAdapter()
    {
        return new WebMvcConfigurerAdapter()
        {
            @Override
            public void addResourceHandlers(ResourceHandlerRegistry registry)
            {
                if (!registry.hasMappingForPattern("/**"))
                {
                    // if this is executed spring won't add default resource
                    // locations - add them to the staticContentLocations if
                    // you want to keep them
                    // default locations:
                    // WebMvcAutoConfiguration.RESOURCE_LOCATIONS
                    registry.addResourceHandler("/**").addResourceLocations(
                            staticContentLocations);
                }
            }
        };
    }

C:/myprj/static에 index.html 이 있는 경우 http://localhost:portno/index.html 이 동작합니다.도움이 됐으면 좋겠다.

에서는 Spring Boot가 됩니다.WebMvcAutoConfiguration 콘텐츠를 이 합니다.WebMvcConfigurationSupport제 가지고 요. . . 、 리 、 을 、 을 、 을 、 을 、 을 、 bean bean bean bean bean bean bean bean bean 。

@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class,
        WebMvcConfigurerAdapter.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
        ValidationAutoConfiguration.class })
    public class WebMvcAutoConfiguration {

}

직접 설정하기만 하면 됩니다.해결 방법은 다음과 같습니다.

@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/static-file/**").addResourceLocations("classpath:/static/");
}

pom.xml에 Tymeleaf 의존성을 추가해야 했습니다.이 의존성이 없으면 스프링 부트는 정적 리소스를 찾을 수 없습니다.

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>

에서 static dir를 한 Spring Config를 합니다.WebSecurityConfigurerAdapter.

http.authorizeRequests().antMatchers("/", "/login", "/assets/**")
            .permitAll()

템플릿으로서 샌드박스 예제를 작성하려고 할 때 이 404 토픽에 대해 우연히 알게 되었습니다(기존의 솔루션에서 https://github.com/fluentcodes/sandbox/tree/java-spring-boot)).static content index.html은 제공되지 않습니다.

이 예는 상당히 단순하고 기존 솔루션이 효과가 있었기 때문에, 저는 언급한 심층적인 스프링 솔루션에 대해서는 자세히 설명하지 않습니다.

생성된 타겟클래스를 조사했는데 예상대로 static/index.html은 없었습니다.

이유는 간단했다.src/main/이 아닌 src/ 아래에 리소스를 만들었습니다.복잡한 솔루션이 많이 언급되어 있기 때문에 찾는 데 시간이 필요합니다.나에게 그것은 다소 사소한 이유가 있었다.

한편, 스프링 부트를 시작할 때:location1, location2에서 정적 콘텐츠가 없다는 힌트를 얻을 수 없는 이유...locationx를 찾을 수 있습니다.주제라고 생각해.

언급URL : https://stackoverflow.com/questions/21358403/spring-boot-project-with-static-content-generates-404-when-running-jar

반응형