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
빈 을 추가하는 방법이 있을지 모르지만 방법을 모르겠습니다.
이제 다음 옵션 중 하나를 선택할 수 있습니다.
@EnableWebMvc
따라서 Spring BootWebMvcAutoConfiguration
클래스 를 비활성화 하는 클래스가 있습니다 . (WebMvcAutoConfiguration
클래스 코드 복사 및 파비콘 기능 삭제 가능)- 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()
.
이제 캐싱 문제가없는 파비콘 핸들러가 있으며 원하는 곳에 파비콘 파일을 배치 할 수 있습니다.
감사.
classpath:/static
예를 들어 정적 리소스는 더 이상 제공되지 않습니다 ). (부팅에서 파비콘 지원 내가 생각하는 자신의 모든 HandlerMapping에있는 이유입니다.)