web-dev-qa-db-ja.com

Spring Boot:ファビコンのオーバーライド

Spring Bootのファビコンをオーバーライドするにはどうすればよいですか?

NOTE:コーディングを必要としない別のソリューションを提供する別の質問を次に示します。 Spring Boot:使用することは可能ですか? fat jarを含む任意のディレクトリにある外部application.propertiesファイル? application.properties用ですが、ファビコンにも適用できます。実際、私はファビコンのオーバーライドにそのメソッドを使用しています。

@EnableWebMvcを持つクラスを実装すると、Spring BootのWebMvcAutoConfigurationクラスが読み込まれず、静的コンテンツのルートディレクトリに配置することで、自分のファビコンを提供できます。

そうでない場合、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のメインリソースディレクトリに配置される「緑の葉」アイコンを提供します。

@EnableWebMvcを持つクラスを自分で実装せずにオーバーライドして、Spring BootのWebMvcAutoConfigurationクラスのデフォルト構成機能全体を無効にするにはどうすればよいですか?

また、クライアント(Webブラウザー)側でアイコンファイルをできるだけ早く更新するため、ファビコンファイルのキャッシュ期間を0に設定します(次のコードのように、使用しています)ファイルを変更した後、できるだけ早くクライアント側で更新する必要がある「静的な」webappコンテンツとスクリプトファイル。

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

そのため、Spring BootのfaviconRequestHandlerが尊重するfavicon.icoファイルを保存する場所を見つけるだけでは不十分な場合があります。

UPDATE

これで、ファビコンファイルをsrc/main/resourcesディレクトリに配置することで、デフォルトをオーバーライドできることがわかりました。ただし、キャッシュ期間の問題は依然として残っています。
また、ファビコンファイルは、リソースディレクトリではなく、静的Webファイルが配置されているディレクトリに配置することをお勧めします。

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)があるため、( https://github.com/spring-projects/spring-boot/blob/master/spring-のFaviconConfigurationクラスを参照してください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

今のところ、Spring Bootが提供するファビコン機能をオーバーライドする方法を見つけることができませんでした。
たぶん自分のHandlerMapping Beanを追加する方法があるかもしれませんが、どうすればいいかわかりません。

これで、次のオプションのいずれかを選択できます。

  1. @EnableWebMvcを持つクラスがあるため、Spring Boot WebMvcAutoConfigurationクラスを無効にします。 (WebMvcAutoConfigurationクラスのコードをコピーして、ファビコン機能を削除できます)
  2. ファビコンファイルを任意の場所に配置する自由を放棄し、Spring Bootのファビコン機能に必要なリソースディレクトリに配置します。キャッシュの問題を無視します。

しかし、どちらのオプションも満足のいくものではありません。
静的なWebファイル(ドキュメントルートを変更できるため、任意のディレクトリを使用できます)にファビコンファイルを配置し、キャッシュの問題を解決したいだけです。
何か不足していますか?
提案は大歓迎です。

UPDATE

ところで、ファビコンやその他の静的ファイルの場所を変更したい理由は次のとおりです。今のところ、主に開発環境の問題です。

単一ページのWebアプリケーション(SPA)を構築しています。

ライブラリ/フレームワーク:

  • サーバー側では、Springを使用します。 (もちろん)
  • クライアント(Webブラウザー)側では、AngularJSを使用します。

ツール:

  • サーバー側では、Spring Tool Suiteを使用します。
  • クライアント側では、WebStormを使用します。

メインディレクトリ構造:

ProjectRoot\
    src\
    bin\
    build\
    webapp\
    build.gradle
  • src:Spring Javaソースファイルがある場所。
  • 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ディレクトリのサーバーアプリケーションの両方からアクセスできる必要があります。
  • クライアントコードを変更する場合、Webブラウザですぐに利用できる必要があります。したがって、ブラウザはキャッシュを無期限にキャッシュしてはならず、常にサーバーに更新を要求する必要があります。
  • 展開する場合、サーバーアプリケーションを再構築/再起動せずに、クライアントコードを変更できる必要があります。そのため、クライアントコードをjarファイルに入れないでください。

キャッシュの問題について:

AddResourceHandlers()でsetCachePeriod(0)を使用しない場合、Google Chromeは、サーバーに更新を要求することなく、ファイルを無期限にキャッシュします。サーバーにも接続しません。 (Googleのエンジニアは、この動作は正しいと言います。)だから、私ができることは、ブラウザーのキャッシュを手動でクリアすることだけです。開発環境でイライラし、本番環境では受け入れられません。

ところで、Node.jsのexpress.jsモジュールは、Google Chromeが更新をサーバーに要求するように、妥当なデフォルトのHTTPヘッダーを提供します。 Springとexpress.jsがFiddlerを使用して生成するHTTPヘッダーを確認したとき、それらは異なっていました。

私の環境を改善するための提案をいただければ幸いです。
私は春の初心者なので、何かが足りないかもしれません。

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名に注意してください。名前の衝突を避けるために「my」を追加しました。
アプリケーションコンテキストの自動配線自体は厄介に思えますが、org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration.addResourceLocations()のコードを模倣するために必要でした。

キャッシュの問題のないファビコンハンドラができました。ファビコンファイルを好きな場所に配置できます。
ありがとう。

75
zeodtr

独自のfavicon.icoをクラスパスのルートまたは静的リソースの場所(たとえば、classpath:/static)に配置するだけです。単一のフラグspring.mvc.favicon.enabled=falseでファビコンの解決を完全に無効にすることもできます。

または、完全に制御するには、HandlerMappingを追加します(ブートからコピーするだけで、より高い優先度を与えます)。

@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;
}
}
49
Dave Syer

これは私には必要ありませんでした。

生成されたJARにリソースをバンドルでき、デフォルトのJARよりも優先度が高い場合にデフォルトをオーバーライドする理由。

カスタムfavicon.icoファイルを作成するために、アプリケーション用にsrc/main/resourcesディレクトリを作成し、favicon.icoファイルをそこにコピーしました。このリソースディレクトリ内のファイルはコンパイルされたJARのルートに移動されるため、Springが提供する前にカスタムfavicon.icoが見つかります。

上記を実行すると、上記の更新されたソリューションと同じ効果が得られました。

V1.2.0以降では、src/main/resources/staticにファイルを配置することもできます。

73
Ross

Springbootは全体的にスマートなソリューションでいっぱいなので、Springbootが本当に好きですが、ファビコンを提供するためにアプリケーションBeanを登録することを拒否します。

私は自分のfaviconリンクをHTMLページヘッドに追加しました。

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

次に、ファビコンの名前を変更して、

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

これで、SpringとJavaを使用せずにChromeおよびFirefoxブラウザのタブとSafariのアドレスバーにアイコンが表示されるようになりました。

26
jeremyjjbrown

Spring Boot 1.2.2および1.1.11以降、spring.mvc.favicon.enabled = falseプロパティを使用してデフォルトのファビコンを簡単に無効にできます。

詳細については、次をご覧ください。

13

Bootの新しいバージョン(確かに1.2ですが、おそらく1.1.8)では、静的リソースにfavicon.icoを追加するだけで済みます。

2
Dave Syer

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

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

robots.txt、favicon.icoファイルの場所:/ src/main/resources

スプリングブート1.2.1を使用しました

1
webmadeup