[spring-mvc] Spring Boot : favicon 재정의

Spring Boot의 favicon을 어떻게 재정의 할 수 있습니까?

참고 : 여기에 코딩을 포함하지 않는 또 다른 솔루션을 제공하는 또 다른 질문이 있습니다. Spring Boot : fat jar와 함께 임의의 디렉토리에서 외부 application.properties 파일을 사용할 수 있습니까? application.properties 용이지만 favicon에도 적용 할 수 있습니다. 사실, 지금은 favicon 재정의에이 방법을 사용하고 있습니다.

@EnableWebMvc가있는 클래스를 구현하면 Spring Boot의 WebMvcAutoConfiguration 클래스가로드되지 않으며 정적 콘텐츠의 루트 디렉터리에 배치하여 내 파비콘을 제공 할 수 있습니다.

그렇지 않으면 WebMvcAutoConfiguration이 faviconRequestHandler 빈을 등록합니다 ( https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ 참조). web / WebMvcAutoConfiguration.java )이며 Spring Boot의 기본 리소스 디렉토리에있는 ‘green leaf’아이콘을 제공합니다.

@EnableWebMvc가있는 클래스를 직접 구현하지 않고 어떻게 재정 의하여 Spring Boot의 WebMvcAutoConfiguration 클래스의 전체 기본 구성 기능을 비활성화 할 수 있습니까?

또한 클라이언트 (웹 브라우저) 측에서 가능한 한 빨리 아이콘 파일을 업데이트하기를 원하기 때문에 favicon 파일의 캐시 기간을 0으로 설정하고 싶습니다. (다음 코드와 같이 사용하고 있습니다. 파일을 변경 한 후 가능한 한 빨리 클라이언트 측에서 업데이트해야하는 ‘정적’웹앱 콘텐츠 및 스크립트 파일.)

public void addResourceHandlers(ResourceHandlerRegistry registry)
{
    registry.addResourceHandler("/**")
        .addResourceLocations("/")
        .setCachePeriod(0);
}

따라서 Spring Boot의 faviconRequestHandler가 존중하는 favicon.ico 파일을 저장할 위치를 찾는 것만으로는 충분하지 않을 수 있습니다.

최신 정보

이제 favicon 파일을 src / main / resources 디렉터리에 배치하여 기본 파일을 재정의 할 수 있음을 알고 있습니다. 그러나 캐시 기간 문제는 여전히 남아 있습니다.
또한 리소스 디렉토리보다는 정적 웹 파일이있는 디렉토리에 favicon 파일을 배치하는 것이 좋습니다.

최신 정보

좋아, 기본 설정을 재정의했습니다. 내가 한 일은 다음과 같습니다.

@Configuration
public class WebMvcConfiguration
{
    @Bean
    public WebMvcConfigurerAdapter faviconWebMvcConfiguration()
    {
        return new FaviconWebMvcConfiguration();
    }

    public class FaviconWebMvcConfiguration extends WebMvcConfigurerAdapter
    {
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry)
        {
            registry.setOrder(Integer.MIN_VALUE);
            registry.addResourceHandler("/favicon.ico")
                .addResourceLocations("/")
                .setCachePeriod(0);
        }
    }
}

기본적으로 registry.setOrder (Integer.MIN_VALUE)를 호출하여 순서가 가장 높은 리소스 핸들러를 추가하여 기본 값을 덮어 씁니다.

Spring Boot의 기본 값은 순서 값 (Integer.MIN_VALUE + 1)을 갖기 때문에 ( https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/의 FaviconConfiguration 클래스 참조) src / main / java / org / springframework / boot / autoconfigure / web / WebMvcAutoConfiguration.java ) 내 핸들러가 이깁니다.

이거 괜찮아? 다른 방법이 있습니까 (내가 한 것보다 더 부드러운 것)?

최신 정보

괜찮지 않습니다. 를 호출 registry.setOrder(Integer.MIN_VALUE)하면 실제로 모든 리소스 처리기의 우선 순위를 높입니다. 따라서 다른 코드에 다음 코드를 추가 WebMvcConfigurerAdapter하면 사실상 모든 http 요청이 해당 리소스 핸들러로 전달되어 Java 코드에 의한 동적 처리를 방지합니다.

public void addResourceHandlers(ResourceHandlerRegistry registry)
{
    registry.addResourceHandler("/**")
        .addResourceLocations("/")
        .setCachePeriod(0);
}

또 다른 해결책이 필요합니다.

최신 정보

지금은 Spring Boot가 제공하는 favicon 기능을 재정의하는 방법을 찾을 수 없습니다.
내 자신의 HandlerMapping빈 을 추가하는 방법이 있을지 모르지만 방법을 모르겠습니다.

이제 다음 옵션 중 하나를 선택할 수 있습니다.

  1. @EnableWebMvc따라서 Spring Boot WebMvcAutoConfiguration클래스 를 비활성화 하는 클래스가 있습니다 . ( WebMvcAutoConfiguration클래스 코드 복사 및 파비콘 기능 삭제 가능)
  2. favicon 파일을 임의의 위치에 배치하는 자유를 포기하고 Spring Boot의 favicon 기능이 요구하는대로 리소스 디렉토리에 배치합니다. 그리고 캐싱 문제를 무시하십시오.

그러나 어느 옵션도 만족스럽지 않습니다.
정적 웹 파일 (문서 루트를 변경할 수 있으므로 모든 디렉토리가 될 수 있음)과 함께 favicon 파일을 배치하고 캐싱 문제를 해결하고 싶습니다.
내가 뭔가를 놓치고 있습니까?
어떤 제안이라도 대단히 감사하겠습니다.

최신 정보

BTW, favicon 및 기타 정적 파일의 위치를 ​​변경하려는 이유는 다음과 같습니다. 현재로서는 주로 개발 환경 문제입니다.

단일 페이지 웹 애플리케이션 (SPA)을 구축 중입니다.

라이브러리 / 프레임 워크 :

  • 서버 측에서는 Spring을 사용합니다. (물론이야)
  • 클라이언트 (웹 브라우저) 측의 경우 AngularJS를 사용합니다.

도구 :

  • 서버 측에서는 Spring Tool Suite를 사용합니다.
  • 클라이언트 측에서는 WebStorm을 사용합니다.

기본 디렉토리 구조 :

ProjectRoot\
    src\
    bin\
    build\
    webapp\
    build.gradle
  • src : 내 Spring 자바 소스 파일이있는 곳.
  • bin : Spring Tool Suite는 빌드 출력을 배치합니다.
  • build : ‘gradle build’는 빌드 출력을 배치합니다.
  • webapp : 내 클라이언트 소스 파일 (.js, .css, .htm 및 favicon)이있는 위치입니다. 따라서 이것이 WebStorm 프로젝트 디렉터리입니다. (필요한 경우 디렉토리 이름을 변경할 수 있습니다)

내가 원하는 것은 :

  • 내 Spring 서버 애플리케이션을 다시 빌드 / 다시 시작하지 않고 내 클라이언트 코드를 수정하고 테스트 할 수 있습니다. 따라서 클라이언트 코드를 jar 파일에 넣어서는 안됩니다. 어쨌든 Spring Tool Suite는 jar 파일을 전혀 빌드하지 않습니다 (적어도 현재 구성의 경우)
  • 클라이언트 코드로 내 Spring 서버 애플리케이션을 테스트 할 수 있으려면 Spring Tool Suite 출력과 gradle 출력간에 쉽게 전환 할 수 있습니다. 따라서 클라이언트 코드는 build하위 디렉토리 의 서버 응용 프로그램 (실제로는 build\libs)과 디렉토리 의 서버 응용 프로그램 모두에서 액세스 할 수 있어야합니다 bin.
  • 클라이언트 코드를 수정하면 웹 브라우저에서 즉시 사용할 수 있어야합니다. 따라서 브라우저는이를 무기한 캐시하지 않아야하며 항상 서버에 업데이트를 요청해야합니다.
  • 배포시 클라이언트 코드는 서버 응용 프로그램을 다시 빌드 / 다시 시작하지 않고 수정할 수 있어야합니다. 따라서 클라이언트 코드를 jar 파일에 넣어서는 안됩니다.

캐시 문제 관련 :

addResourceHandlers ()에 setCachePeriod (0)가 없으면 Google 크롬은 서버에 업데이트를 요청하지 않고 파일을 무기한 캐시합니다. 서버에도 연결되지 않습니다. (Google 엔지니어들은 동작이 옳다고 말합니다.) 그래서 제가 할 수있는 일은 브라우저 캐시를 수동으로 지우는 것뿐입니다. 개발 환경에서는 실망스럽고 프로덕션 환경에서는 용납 할 수 없습니다.

BTW, Node.js의 express.js 모듈은 합리적인 기본 HTTP 헤더를 제공하므로 Google 크롬이 서버에 업데이트를 요청합니다. Spring과 express.js가 Fiddler를 사용하여 생성하는 HTTP 헤더를 검토했을 때 서로 달랐습니다.

내 환경 개선에 대한 제안을 주시면 감사하겠습니다.
저는 봄 초심자라서 뭔가 빠졌을 수도 있습니다.

최신 정보

마지막으로 작업 코드가 있습니다. 다음과 같습니다.

@Configuration
public static class FaviconConfiguration
{
    @Bean
    public SimpleUrlHandlerMapping myFaviconHandlerMapping()
    {
        SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
        mapping.setOrder(Integer.MIN_VALUE);
        mapping.setUrlMap(Collections.singletonMap("/favicon.ico",
            myFaviconRequestHandler()));
        return mapping;
    }

    @Autowired
    ApplicationContext applicationContext;

    @Bean
    protected ResourceHttpRequestHandler myFaviconRequestHandler()
    {
        ResourceHttpRequestHandler requestHandler =
            new ResourceHttpRequestHandler();
        requestHandler.setLocations(Arrays
            .<Resource> asList(applicationContext.getResource("/")));
        requestHandler.setCacheSeconds(0);
        return requestHandler;
    }
}

빈 이름을 확인하십시오. 이름 충돌을 피하기 위해 ‘my’를 추가했습니다.
Autowiring 애플리케이션 컨텍스트 자체는 어색해 보이지만 .NET에서 코드를 모방하는 데 필요했습니다 org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration.addResourceLocations().

이제 캐싱 문제가없는 파비콘 핸들러가 있으며 원하는 곳에 파비콘 파일을 배치 할 수 있습니다.
감사.



답변

클래스 경로의 루트 또는 정적 리소스 위치 (예 :)에 자신의 favicon.ico를 넣을 수 있습니다 classpath:/static. 단일 플래그로 파비콘 해상도를 완전히 비활성화 할 수도 있습니다 spring.mvc.favicon.enabled=false.

또는 완전한 제어를 위해 HandlerMapping을 추가 할 수 있습니다 (단지 Boot에서 복사하여 더 높은 우선 순위를 부여).

@Configuration
public static class FaviconConfiguration {

@Bean
public SimpleUrlHandlerMapping faviconHandlerMapping() {
    SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
    mapping.setOrder(Integer.MIN_VALUE);
    mapping.setUrlMap(Collections.singletonMap("mylocation/favicon.ico",
            faviconRequestHandler()));
    return mapping;
}

@Bean
protected ResourceHttpRequestHandler faviconRequestHandler() {
    ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
    requestHandler.setLocations(Arrays
            .<Resource> asList(new ClassPathResource("/")));
    return requestHandler;
}
}


답변

이 중 어느 것도 나에게 필요하지 않았습니다.

기본 JAR보다 우선 순위가 더 높은 생성 된 JAR로 자원을 번들 할 수 있는데 기본값을 대체하는 이유는 무엇입니까?

사용자 지정 favicon.ico파일 을 얻기 위해 src/main/resources응용 프로그램에 대한 디렉터리를 만든 다음 favicon.ico파일을 여기에 복사 했습니다. 이 리소스 디렉토리의 파일은 컴파일 된 JAR의 루트로 이동하므로 favicon.icoSpring이 제공 한 JAR 이전에 사용자 정의 가 발견됩니다.

위의 작업을 수행하면 위의 업데이트 된 솔루션과 동일한 효과를 얻었습니다.

v1.2.0 이후로 파일을 src/main/resources/static.


답변

전반적으로 스마트 솔루션으로 가득 차 있기 때문에 Springboot를 정말 좋아하지만 파비콘을 제공하기 위해 응용 프로그램 빈을 등록하는 것은 어리석은 일이기 때문에 거부합니다.

내 HTML 페이지 헤드에 내 자신의 파비콘 링크를 추가했습니다.

<link rel="icon" type="image/png" href="images/fav.png">

그런 다음 파비콘의 이름을 변경하고

<ProjFolder>/src/main/resources/static/images/fav.png

이제 Spring과 Java를 사용하지 않고도 Chrome 및 Firefox 브라우저 탭과 Safari 주소 표시 줄에 아이콘이 있으며, 이러한 사소한 기능을 위해 최신 버전에서 Springboot에 대한 변경 사항을 추적 할 필요가 없습니다.


답변

Spring Boot 1.2.2 및 1.1.11 이후로 다음을 사용하여 기본 파비콘을 쉽게 비활성화 할 수 있습니다. spring.mvc.favicon.enabled = false 속성을 .

자세한 정보는 다음을 방문하십시오.

업데이트 : spring.mvc.favicon.enabledSpring Boot 2.2.x 이후 로 더 이상 속성 이 없습니다.


답변

최신 버전의 Boot (1.2 확실하지만 1.1.8도 가능)를 사용하면 정적 리소스에 favicon.ico를 넣을 수 있습니다.


답변

많은 옵션 / 변형을 시도했지만 이것 만 효과가있었습니다. (스프링 부트 2.2.7)

/ resources / static 에있는 Favicon.ico 파일 및 robots.txt

@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
  protected void configure(HttpSecurity http) throws Exception {
    http
      .authorizeRequests()
        .antMatchers("/favicon.ico").permitAll()
        .antMatchers("/robots.txt").permitAll()
        .antMatchers("/").permitAll()
        .anyRequest().authenticated();
    }
}

@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {
@Override
  public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler(
      "/favicon.ico",
      "/robots.txt")
      .addResourceLocations(
        "classpath:/static/");
  }
}

도움이된다면 마음에 들어주세요;)


답변

registry.addResourceHandler ( “/ robots.txt”). addResourceLocations ( “/”);

registry.addResourceHandler ( “/ favicon.ico”). addResourceLocations ( “/”);

robots.txt, favicon.ico 파일 위치 : / src / main / resources

나는 스프링 부트 1.2.1을 사용했습니다.