Spring Bootのファビコンをオーバーライドするにはどうすればよいですか?
注:これは、コーディングを含まない別のソリューションを提供する別の質問です。SpringBoot:ファットジャーを使用して任意のディレクトリで外部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)であり、SpringBootのメインリソースディレクトリに配置される「緑の葉」アイコンを提供します。
@EnableWebMvcを持つクラスを自分で実装せずにオーバーライドして、Spring BootのWebMvcAutoConfigurationクラスのデフォルト構成機能全体を無効にするにはどうすればよいですか?
また、クライアント(Webブラウザ)側でアイコンファイルをできるだけ早く更新したいので、ファビコンファイルのキャッシュ期間を0に設定したいと思います(次のコードのように、 「静的」なWebアプリケーションコンテンツとスクリプトファイル。ファイルを変更した後、できるだけ早くクライアント側で更新する必要があります。)
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
registry.addResourceHandler("/**")
.addResourceLocations("/")
.setCachePeriod(0);
}
したがって、SpringBootのfaviconRequestHandlerが尊重するfavicon.icoファイルを保存する場所を見つけるだけでは不十分な場合があります。
更新
これで、ファビコンファイルをsrc / main / resourcesディレクトリに配置することで、デフォルトのファイルを上書きできることがわかりました。しかし、キャッシュ期間の問題は依然として残っています。
また、ファビコンファイルは、リソースディレクトリではなく、静的Webファイルが配置されているディレクトリに配置することをお勧めします。
更新
わかりました、私はなんとかデフォルトのものを上書きすることができました。私がしたことは次のとおりです。
@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);
}
別の解決策が必要です。
更新
今のところ、SpringBootが提供するファビコン機能をオーバーライドする方法を見つけることができませんでした。
自分のHandlerMapping
Beanを追加する方法があるかもしれませんが、その方法がわかりません。
これで、次のオプションのいずれかを選択できます。
@EnableWebMvc
したがって、SpringBootクラスを無効にするWebMvcAutoConfiguration
クラスがあります。(WebMvcAutoConfiguration
クラスのコードをコピーしてファビコン機能を削除できます)- Spring Bootのファビコン機能が必要とするように、ファビコンファイルを任意の場所に配置する自由を放棄し、リソースディレクトリに配置します。そして、キャッシュの問題を無視します。
しかし、どちらのオプションも満足のいくものではありません。
ファビコンファイルを静的Webファイル(ドキュメントルートを変更できるため、任意のディレクトリにすることができます)と一緒に配置し、キャッシュの問題を解決したいだけです。
私は何かが足りないのですか?
任意の提案をいただければ幸いです。
更新
ところで、ファビコンやその他の静的ファイルの場所を変更したい理由は次のとおりです。今のところ、それは主に開発環境の問題です。
シングルページWebアプリケーション(SPA)を構築しています。
ライブラリ/フレームワーク:
- サーバーサイドにはSpringを使用しています。(もちろん)
- クライアント(Webブラウザ)側では、AngularJSを使用しています。
ツール:
- サーバーサイドには、Spring ToolSuiteを使用しています。
- クライアント側にはWebStormを使用しています。
メインディレクトリ構造:
ProjectRoot\
src\
bin\
build\
webapp\
build.gradle
- src:SpringJavaソースファイルが存在する場所。
- bin:Spring ToolSuiteがビルド出力を配置する場所。
- build: 'gradlebuild'がビルド出力を配置する場所。
- webapp:クライアントソースファイル(.js、.css、.htm、ファビコン)が存在する場所。したがって、これはWebStormプロジェクトディレクトリです。(必要に応じてディレクトリ名を変更できます)
私が欲しいのは:
- Springサーバーアプリケーションを再構築/再起動せずにクライアントコードを変更およびテストできるようにするため。したがって、クライアントコードをjarファイルに入れてはなりません。とにかく、Spring Tool Suiteはjarファイルをまったく構築しません(少なくとも現在の構成では)
- Springサーバーアプリケーションをクライアントコードでテストできるようにするには、Spring ToolSuiteの出力と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ヘッダーを確認したところ、それらは異なっていました。
私の環境を改善するための提案をいただければ幸いです。
私は春の初心者なので、何かが足りないかもしれません。
更新
最後に、動作するコードがあります。それは次のとおりです。
@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()
。
これで、キャッシュの問題がないファビコンハンドラーができ、ファビコンファイルを好きな場所に配置できます。
ありがとう。
classpath:/static
たとえば、静的リソースはこれ以上提供されません)。(これが、Bootでのファビコンサポートが独自のHandlerMappingにある理由です。)