2013-12-19 110 views
53

Spring Bootのfaviconを無効にするにはどうすればよいですか?Spring Boot:faviconを無効にする

Spring Boot: Is it possible to use external application.properties files in arbitrary directories with a fat jar?それはapplication.propertiesのためだが、それはまた、ファビコンに適用することができます。ここで任意のコードによらない別のソリューションを提供し、私の別の質問です。実際、私は今、faviconオーバーライドのためにそのメソッドを使用しています。

私は@EnableWebMvcを持つクラスを実装する場合は、春ブーツの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ブートのメインリソースディレクトリに配置された「緑の葉」アイコンを提供します。

私は@EnableWebMvcを持つクラスを実装せずにそれを無効にすることができます。したがって、SpringBootのWebMvcAutoConfigurationクラスのデフォルト設定全体の機能を無効にしますか?

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

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

ので、ちょうどファビコンを保存する場所を見つけることメートル。 icoファイルで、Spring BootのfaviconRequestHandlerが十分でない可能性があります。

UPDATE

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

UPDATE

[OK]を、私はデフォルトの1を上書きするために管理。次のように私がやったこと は次のとおりです。

@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

それはOKではないのです。 registry.setOrder(Integer.MIN_VALUE)を呼び出すと、実際にはすべてのリソースハンドラの優先度が上がります。したがって、別のWebMvcConfigurerAdapterに次のコードを追加すると、実際にはすべてのhttp要求がそのリソースハンドラに送られ、Javaコードによる動的処理ができなくなります。

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

もう1つ解決策が必要です。今の

UPDATE

、私は春ブーツが提供するファビコンの機能を無効にする方法を見つけることができませんでした。
たぶん自分のHandlerMapping beanを追加する方法がありますが、どうやってそれを行うのか分かりません。

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

  1. @EnableWebMvcので無効に春ブーツWebMvcAutoConfigurationクラスを持つクラスを持っています。 (私はWebMvcAutoConfigurationクラスのコードをコピーしてファビコン機能を削除することができます)
  2. faviconファイルを任意の場所に配置し、Springのfavicon機能が必要とするリソースディレクトリに配置する自由を放棄します。そして、キャッシングの問題を無視してください。

しかしいずれのオプションも満足できません。
faviconファイルを静的なWebファイル(ドキュメントルートを変更できるので、任意のディレクトリにすることができます)に配置し、キャッシュの問題を解決したいだけです。
何か不足していますか?
ご意見をいただければ幸いです。次のように

UPDATE

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

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

ライブラリ/フレームワーク:サーバー側の場合

  • 、私は春を使用しています。 (もちろん)
  • クライアント(Webブラウザ)側では、AngularJSを使用します。

ツール:サーバー側の場合

  • 、私は春のツール・スイートを使用しています。
  • クライアント側では、WebStormを使用します。

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

ProjectRoot\ 
    src\ 
    bin\ 
    build\ 
    webapp\ 
    build.gradle 
  • SRC:私の春のJavaソースファイルが存在します。
  • bin:Spring Tool Suiteはビルド出力を配置します。
  • build: 'gradle build'はビルド出力を配置します。
  • webapp:クライアントのソースファイル(.js、.css、.htm、favicon)はどこにありますか。したがってこれはWebStormプロジェクトディレクトリです。

を(必要であれば、私はディレクトリ名を変更することができます)私が欲しいのです:

  • 私の春のサーバーアプリケーションを再起動/再構築することなく、私のクライアントのコードを変更してテストできるようにするに。したがって、クライアントコードをjarファイルに入れてはいけません。とにかくSpring Tool Suiteはjarファイルを作成しません(少なくとも現在の設定では)
  • クライアントコードでSpringサーバーアプリケーションをテストして、Spring Tool Suiteの出力とgradle出力を簡単に切り替えることができます。したがって、クライアントコードは、buildサブディレクトリ(実際にはbuild\libs)のサーバーアプリケーションとbinディレクトリのサーバーアプリケーションの両方からアクセスできる必要があります。
  • クライアントコードを変更するときは、そのコードをWebブラウザですぐに使用できるようにする必要があります。したがって、ブラウザは無期限にキャッシュしてはならず、常に更新のためにサーバーを要求する必要があります。
  • 展開すると、サーバーアプリケーションを再構築/再起動せずにクライアントコードを変更する必要があります。そのため、クライアントコードをjarファイルに入れてはいけません。キャッシュの問題について

:setCachePeriodなし

(0)addResourceHandlers上の()、Google Chromeはアップデートのため、サーバーを求めず、無制限にファイルをキャッシュします。サーバーに接続することさえできません。 (Googleのエンジニアによると、その動作は正しいと言われている)だから、私はブラウザのキャッシュを手動でクリアするしかない。開発環境には不満があり、運用環境では受け入れられません。

Node.jsのBTWでは、express.jsモジュールが合理的なデフォルトのHTTPヘッダーを提供し、Google Chromeがサーバーに更新を求めるようにしています。 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の名前に注目してください。名前の衝突を避けるために「私」を追加しました。
アプリケーションのコンテキストをオートワイヤすること自体が難しいようですが、コードを模倣するためには、org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration.addResourceLocations()で必要でした。

今私は問題のないfaviconハンドラを持っています。私は好きな場所にfaviconファイルを置くことができます。
ありがとうございます。

+1

あなたの方法はOKに見えるを使用しました。ただし、デフォルトのSpring MVCリソースハンドラを置き換えるわけではありません(静的リソースは、例えば、classpath:/ staticからはそれ以上提供されません)。 (そのため、Bootのfaviconのサポートは私自身のHandlerMappingにあります) –

+0

@DaveSyer今、私はそれがOkではないことに気付きました。私は上記の3番目の更新を書いた。たぶん別の 'HandlerMapping'が必要です。 – zeodtr

+0

@DaveSyer上記の4回目の更新をご覧ください。他の方法はありますか?例えば、私自身の 'HandlerMapping'を登録できますか? – zeodtr

答えて

35

あなた自身のfavicon.icoをクラスパスのルートまたは任意の静的リソースの場所(例えばclasspath:/static)に入れることができます。 1つのフラグ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; 
} 
} 
+0

ありがとうございます。私はすでにそれを試したと思っていましたが、今考えると '@Configuration'アノテーションがありませんでした。ところで、私は質問の別の場所に静的ファイルを配置したい理由を書きました。 – zeodtr

+0

私はResourceLoader.gerResource( "/")を使用してドキュメントルート(右?)内のファイルを取得する必要があるため、@Autowire ApplicationContextを使用する必要があります。アプリケーションのコンテキストをDIにしてもよろしいですか?何人かは悪いことだと言う人もいます。 – zeodtr

+0

私はあなたの提案を試みています。注意すべき点は、私のBean名は 'faviconHandlerMapping'であってはいけません。なぜなら、Spring BootのfaviconHandlerMapping BeanとのBean名の衝突を引き起こすからです。 org.springframework.beans.factory.BeanFactoryUtils.beansOfTypeIncludingAncestor()によって呼び出されるメソッドによって、2つのBeanのうち1つだけが選択されます。これは、org.springframework.web.servlet.initHandlerMappings()によって再度呼び出されます。私の豆は、名前の衝突によってオーバーライドされた前にロードされているようです。 – zeodtr

63

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

デフォルトよりも優先される生成されたJARでリソースをバンドルするときに、デフォルトをオーバーライドするのはなぜですか。

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

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

v1.2.0以降、ファイルをsrc/main/resources/staticに入れることもできます。

+5

理由は簡単です。私は、faviconファイルをJARに入れたくありません。 @ zodtrちょっと好奇心が強い理由 – zeodtr

+0

これは私にとって最も自然なようです。しかし、私はそれが 'src/main/resources/static/images'にあることを期待していました。 – btiernay

+1

@btiernay WebサーバーはWebクライアントとは別のエンティティであるからです。そしてfavicon(s)はクライアントに属します。 Webサーバーのwarファイルには、クライアントに所属するファイルを含める理由がありません。これは、ユーザーの必要に応じて頻繁に変更できます。 – zeodtr

20

全体的にはスマートなソリューションがたくさんあるので、私はSpringbootが本当に好きですが、それはちょっと愚かなので、faviconを提供するためにアプリケーションBeanを登録することを拒否します。

私はちょうど自分のhtmlページの頭の中に自分のfaviconリンクを追加しました。

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

は、その後、私は今、私は春とJavaを使用することなく、ChromeとFirefoxのブラウザのタブとSafariのアドレスバーにアイコンが表示され、そして私がすべき私のファビコンと改名し、

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

でそれを置きますそのような些細な機能のために新しいバージョンでSpringbootへの変更を追いかける必要はありません。

+3

あなたはハンドラマッピングでこれ以上悩む必要はありません(静的リソースにfavicon.icoを置くだけです)。 –

+0

これはとても簡単です!ありがとう。私はそれを私の断片に加えます。 –

+0

これは魅力的な、最高のソリューションのように動作します! –

2

新しいバージョンのBoot(確かに1.2でも、おそらく1.1.8)では、静的リソースにfavicon.icoを入れることができます。

1

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

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

のrobots.txt、favicon.icoをファイルの場所:/ srcに/メイン/リソース

iは春ブーツ1.2.1

関連する問題