Як я можу замінити значок Spring Boot?
ПРИМІТКА : Ось моє ще одне запитання, яке пропонує інше рішення, яке не передбачає кодування: Spring Boot: чи можна використовувати зовнішні файли application.properties у довільних каталогах із жировою банкою? Це для application.properties, але його також можна застосувати до значка. Насправді я зараз використовую цей метод для заміни значків.
Якщо я реалізую клас, який має @EnableWebMvc, клас WebMvcAutoConfiguration Spring Boot не завантажується, і я можу подати власний значок, розмістивши його в кореневому каталозі статичного вмісту.
В іншому випадку 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.
Як я можу перевизначити це, не реалізувавши клас, який має @EnableWebMvc сам, тим самим відключаючи всю функціональність конфігурації за замовчуванням класу WebMvcAutoConfiguration класу Spring Boot?
Крім того, оскільки я хочу, щоб файл піктограм якнайшвидше оновлювався на стороні клієнта (веб-браузера), я хочу встановити для періоду кешування файлу значка значення 0. (наприклад, такий код, який я використовую `` статичний '' вміст веб-додатків та файли сценаріїв, які повинні бути оновлені на стороні клієнта якомога швидше після того, як я зміню файл.)
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/**")
.addResourceLocations("/")
.setCachePeriod(0);
}
Отже, просто для того, щоб знайти місце для збереження файлу favicon.ico, почесних почесних виступів faviconRequestHandler Spring Boot може бути недостатньо.
ОНОВЛЕННЯ
Тепер я знаю, що можу замінити файл за замовчуванням, розмістивши файл значка у каталозі src / main / resources. Але проблема періоду кешування все ще залишається.
Крім того, переважно розміщувати файл значка у каталозі, де розміщуються статичні веб-файли, а не в каталозі ресурсів.
ОНОВЛЕННЯ
Добре, мені вдалося замінити стандартний. Я зробив наступне:
@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), (див. Клас FaviconConfiguration у https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/ 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.
Можливо, є спосіб додати мій власний HandlerMapping
боб, але я не знаю, як це зробити.
Тепер я можу вибрати один із таких варіантів:
- Майте клас, який
@EnableWebMvc
таким чином вимкнувWebMvcAutoConfiguration
клас Spring Boot . (Я можу скопіювати кодWebMvcAutoConfiguration
класу та видалити функціонал значка) - Відмовтеся від свободи розміщення файлу значка у довільному розташуванні та розмістіть його в каталозі ресурсів, як того вимагає функціональність значка Spring Boot. І проігноруйте проблему кешування.
Але жоден із варіантів не є задовільним.
Я просто хочу розмістити файл значка зі своїми статичними веб-файлами (це може бути будь-який каталог, оскільки я можу змінити корінь документа) і вирішити проблему кешування.
Мені чогось не вистачає?
Будь-яка пропозиція буде вдячна.
ОНОВЛЕННЯ
До речі, причина, по якій я хочу змінити розташування значка та інших статичних файлів, полягає в наступному. Наразі це головним чином питання середовища розвитку.
Я створюю веб-додаток на одній сторінці (SPA).
Бібліотеки / основи:
- Для сторони сервера я використовую Spring. (звичайно)
- Для клієнта (веб-браузера) я використовую AngularJS.
Інструменти:
- На стороні сервера я використовую Spring Tool Suite.
- Для клієнта я використовую WebStorm.
Основна структура каталогів:
ProjectRoot\
src\
bin\
build\
webapp\
build.gradle
- src: Де знаходяться мої вихідні файли Java 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.
Щодо проблеми з кешем:
Без setCachePeriod (0) на addResourceHandlers (), Google Chrome кешує файл необмежено довго, не просячи сервер про оновлення. Він навіть не підключається до сервера. (Інженери Google кажуть, що поведінка правильна.) Отже, все, що я можу зробити, це очистити кеш браузера вручну. Це неприємно для середовища розвитку та неприпустимо для середовища виробництва.
До речі, модуль express.js на Node.js дає розумний заголовок HTTP за замовчуванням, так що Google Chrome запитує сервер про оновлення. Коли я переглядав заголовки HTTP, які Spring і express.js створюють за допомогою Fiddler, вони відрізнялися.
Будемо вдячні за будь-які пропозиції щодо покращення мого середовища.
Оскільки я початківець весни, можливо, мені чогось не вистачає.
ОНОВЛЕННЯ
Нарешті, у мене є робочий код. Це наступне:
@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;
}
}
Зверніть увагу на назви квасолі. Я додав "мій", щоб уникнути зіткнення імен.
Сам контекст програми автоматичного підключення здається незручним, але він був необхідний для імітації коду в org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration.addResourceLocations()
.
Тепер у мене є обробник значків без проблем кешування, і я можу розмістити файл значка у будь-якому місці, куди захочу.
Дякую.
classpath:/static
). (Ось чому підтримка значків у Boot є у власному HandlerMapping, я думаю.)