Подтвердить что ты не робот

Spring Загрузка: переопределение значков

Как я могу переопределить значок Spring Boot?

ПРИМЕЧАНИЕ. Вот мой еще один вопрос, который предлагает другое решение, которое не требует какого-либо кодирования: Spring Загрузка: возможно ли использовать внешнее приложение .properties в произвольных каталогах с толстым банком? Это для application.properties, но оно также может быть применено к значку. На самом деле, я использую этот метод для переопределения favicon.

Если я реализую класс с @EnableWebMvc, класс WebMvcAutoConfiguration Spring Boot не загружается, и я могу обслуживать свой собственный значок, поместив его в корневую директорию статического содержимого.

В противном случае WebMvcAutoConfiguration регистрирует faviconRequestHandler bean (см. источник https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java), и он служит значку "зеленый лист", который помещен в каталоге ресурсов Spring Boot main.

Как я могу переопределить его, не внедряя сам класс, который имеет @EnableWebMvc, тем самым отключив все функции настройки по умолчанию для класса WebMvcAutoConfiguration Spring Boot?

Кроме того, поскольку я хочу, чтобы файл значка был обновлен как можно скорее на стороне клиента (веб-браузера), я хочу установить период кэширования файла favicon равным 0. (например, следующий код, который я используя мой "статический" контент webapp и script файлы, которые должны быть обновлены на стороне клиента как можно скорее после изменения файла.)

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

Итак, просто чтобы найти место для сохранения файла favicon.ico, что Spring Похвала faviconRequestHandler загрузки может быть недостаточной.

UPDATE

Теперь я знаю, что могу переопределить значение по умолчанию, поместив файл favicon в каталог src/main/resources. Но проблема с периодом кеша все еще сохраняется.
Кроме того, предпочтительно размещать файл favicon в каталоге, где размещены статические веб файлы, а не каталог ресурсов.

UPDATE

Хорошо, мне удалось переопределить значение по умолчанию. Я сделал следующее:

@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) побеждает мой обработчик.

Это хорошо? Есть ли другой способ (что-то более мягкое, чем то, что я сделал)?

UPDATE

Это не так. Когда я вызываю registry.setOrder(Integer.MIN_VALUE), на самом деле я поднимаю приоритет всех обработчиков ресурсов. Поэтому, когда я добавляю следующий код в другой WebMvcConfigurerAdapter, фактически весь HTTP-запрос направляется на этот обработчик ресурсов, предотвращая любую динамическую обработку кодом Java.

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

Требуется другое решение.

UPDATE

В настоящее время я не могу найти способ переопределить функциональность favicon Spring Boot. Возможно, есть способ добавить добавить свой собственный HandlerMapping bean, но я не знаю, как это сделать.

Теперь я могу выбрать один из следующих вариантов:

  • У класса с @EnableWebMvc таким образом отключается класс Spring Boot WebMvcAutoConfiguration. (Я могу скопировать код класса WebMvcAutoConfiguration и удалить функциональность favicon)
  • Откажитесь от свободы размещения файла favicon в суровом местоположении и поместите его в каталог ресурсов в качестве Spring для функции загрузки favicon. И игнорируйте проблему кэширования.

Но ни один из вариантов не является удовлетворительным.
Я просто хочу разместить файл favicon с моими статическими веб файлами (которые могут быть любой директорией, так как я могу изменить корень документа) и решить проблему кеширования. Я что-то не хватает?
Любое предложение было бы с благодарностью.

UPDATE

Кстати, причина, по которой я хочу изменить местоположение favicon и других статических файлов, выглядит следующим образом. На данный момент это в основном проблема среды разработки.

Я создаю одностраничное веб-приложение (SPA).

Библиотеки/Каркасы:

  • Для серверной части я использую Spring. (конечно)
  • Для стороннего клиента (веб-браузера) я использую AngularJS.

Инструменты:

  • Для серверной части я использую Spring Tool Suite.
  • Для клиентской стороны я использую WebStorm.

Основная структура каталогов:

ProjectRoot\
    src\
    bin\
    build\
    webapp\
    build.gradle
  • src: Где находятся мои исходные файлы java Spring.
  • bin: Где Spring Инструмент Suite помещает свой вывод сборки.
  • build: Where 'gradle build' помещает свой вывод сборки.
  • webapp: Где находятся мои исходные файлы клиента (.js,.css,.htm и favicon). Таким образом, это каталог проектов WebStorm. (При необходимости я могу изменить имя каталога)

Я хочу:

  • Возможность изменять и проверять код клиента без восстановления/перезапуска моего серверного приложения Spring. Таким образом, клиентский код не должен быть помещен в файл jar. Anyways Spring Tool Suite не создает файл jar вообще (по крайней мере для текущей конфигурации)
  • Чтобы иметь возможность тестировать мое серверное приложение Spring с клиентским кодом, легко переключаться между выводами Spring Tool Suite и gradle. Таким образом, клиентский код должен быть доступен как из серверного приложения в подкаталоге build (фактически build\libs), так и в серверном приложении в каталоге bin.
  • Когда я изменяю код клиента, он должен быть немедленно доступен для веб-браузера. Поэтому браузер не должен кэшировать его на неопределенный срок и всегда должен запрашивать обновление сервера.
  • При развертывании клиентский код должен быть модифицируемым без восстановления/перезапуска серверного приложения. Таким образом, клиентский код не должен быть помещен в файл jar.

Относительно проблемы с кешем:

Без setCachePeriod (0) в addResourceHandlers() Google Chrome кэширует файл неограниченно, не запрашивая сервер для обновлений. Он даже не подключается к серверу. (Инженеры Google говорят, что поведение верное.) Итак, все, что я могу сделать, это вручную очистить кеш браузера. Это разочаровывает среду разработки и неприемлемо в производственной среде.

BTW, express.js модуль на Node.js дает разумный HTTP-заголовок по умолчанию, чтобы Google Chrome запрашивал у сервера обновления. Когда я просмотрел заголовки HTTP, которые Spring и express.js производит с использованием Fiddler, они были разными.

Любое предложение по улучшению моей среды будет оценено. Поскольку я новичок Spring, возможно, что-то не хватает.

UPDATE

Наконец, у меня есть рабочий код. Это выглядит так:

@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;
    }
}

Обратите внимание на имена bean. Я добавил "мой", чтобы избежать столкновения имен.
Сам контекст приложения Autowiring кажется неудобным, но для обработки кода в org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration.addResourceLocations() необходимо было.

Теперь у меня есть обработчик favicon без проблемы кэширования, и я могу разместить файл favicon в любом месте.
Спасибо.

4b9b3361

Ответ 1

Вы можете просто поместить свой собственный favicon.ico в корень пути к классам или в любом из статических местоположений ресурсов (например, classpath:/static). Вы также можете полностью отключить разрешение favicon с помощью одного флага 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;
}
}

Ответ 2

Ничего из этого не было необходимо для меня.

Зачем переопределять значение по умолчанию, когда вы можете связать ресурс с сгенерированным JAR, который будет иметь более высокий приоритет, чем стандартный.

Чтобы создать пользовательский файл favicon.ico, я создал каталог src/main/resources для своего приложения, а затем скопировал туда файл favicon.ico. Файлы в этом каталоге ресурсов перемещаются в корень скомпилированного JAR, и поэтому ваш пользовательский favicon.ico найден до Spring.

Выполнение вышеуказанного достигается тем же эффектом, что и ваше обновленное решение выше.

Обратите внимание, что начиная с версии 2.1 вы также можете поместить файл в src/main/resources/static.

Ответ 3

Мне очень нравится Springboot, потому что в целом она полна умных решений, но я отказываюсь регистрировать приложение bean, чтобы предоставить значок, потому что это просто глупо.

Я просто добавил свою собственную ссылку favicon в свой html-заголовок страницы так.

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

Затем я переименовал свой значок и поместил его в

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

Теперь у меня есть значок в закладках браузера Chrome и Firefox и адресная строка Safari без использования Spring и Java, и мне не нужно будет преследовать изменения в Springboot в более новых версиях для таких тривиальных функций.

Ответ 5

Более новые версии Boot (1.2 наверняка, но, возможно, также 1.1.8) позволяют вам просто поместить favicon.ico в ваши статические ресурсы.

Ответ 6

registry.addResourceHandler( "/robots.txt" ) addResourceLocations ( "/" );.

registry.addResourceHandler( "/favicon.ico" ) addResourceLocations ( "/" );.

robots.txt, расположение файла favicon.ico:/src/main/resources

я использовал spring boot 1.2.1