Spring Boot配置インターフェースWebMvcConfigrerの実現


WebMvcConfigrerクラスは実はSpring内部の構成の一つであり、伝統的なxmlプロファイルの代わりにJavaBen形式でフレームに対してカスタマイズされている。java-based方式のspring mvc配置に基づいて、構成クラスを作成してWebMvcConfigrerを実現する必要があります。 インターフェース 抽象的なクラスはWebMvcConfigrerインターフェースに対する簡単な抽象的なものである(いくつかのデフォルトの実装を追加した)が、Spring Boot 2.0およびSpring 5.0においてWebMvcConfigrer Adapterは既に廃棄されている。公式推薦は直接WebMvcConfigrerを実現します。または直接WebMvcConfigrationSupportを継承します。方式はWebMvcConfigrerインターフェースを実現します。方式は二番目にWebMvcConfigrationSupport類を継承します。具体的にこの文章を見ることができます。https://www.jb51.net/article/174766.htm

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
 
package org.springframework.web.servlet.config.annotation;
 
import java.util.List;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
 
public interface WebMvcConfigurer {
 void configurePathMatch(PathMatchConfigurer var1);
 
 void configureContentNegotiation(ContentNegotiationConfigurer var1);
 
 void configureAsyncSupport(AsyncSupportConfigurer var1);
 
 void configureDefaultServletHandling(DefaultServletHandlerConfigurer var1);
 
 void addFormatters(FormatterRegistry var1);
 
 void addInterceptors(InterceptorRegistry var1);
 
 void addResourceHandlers(ResourceHandlerRegistry var1);
 
 void addCorsMappings(CorsRegistry var1);
 
 void addViewControllers(ViewControllerRegistry var1);
 
 void configureViewResolvers(ViewResolverRegistry var1);
 
 void addArgumentResolvers(List<HandlerMethodArgumentResolver> var1);
 
 void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> var1);
 
 void configureMessageConverters(List<HttpMessageConverter<?>> var1);
 
 void extendMessageConverters(List<HttpMessageConverter<?>> var1);
 
 void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> var1);
 
 void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> var1);
 
 Validator getValidator();
 
 MessageCodesResolver getMessageCodesResolver();
}
次にいくつかの方法を重点的に探して説明します。

 /*       */
void addInterceptors(InterceptorRegistry var1);
/*         */
void addViewControllers(ViewControllerRegistry registry);
/**
  *      
**/
void addResourceHandlers(ResourceHandlerRegistry registry);
/*           */
void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer);
/**
  *          
 **/
void configureViewResolvers(ViewResolverRegistry registry);
/*            */
void configureContentNegotiation(ContentNegotiationConfigurer configurer);
1、addInterceptors(InterceptorRegistry registry)
この方法は、Handler InterceptorAdapterなどのIntercepterを専門に登録するために使用されます。

@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer { 
@Override
 public void addInterceptors(InterceptorRegistry registry) {
  registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/emp/toLogin","/emp/login","/js/**","/css/**","/images/**");
 }
}
addPathPatterns(/*)はすべての要求をブロックしましたが、/toLoginと/login要求のブロッキングは排除されました。
spring bootのバージョンが2.xにアップグレードされると、静的リソースにアクセスすると、HandlerInterceptorにブロックされ、ネット上では多くの処理方法が次のように書かれています。

.excludePathPatterns("/index.html","/","/user/login","/static/**");
残念ながら、本人は使用中ずっと機能しませんでした。要求の経路を確認するには/static/がありません。

そこで私は「/js/**」に変更しました。「/css/**」、「/imags/**」というページの内容は正常に訪問できます。プロジェクトの構造は以下の通りです。

2.ページジャンプaddView Controller
以前はSpring MVCを書く時、もし1つのページを訪問する必要があるならば、必ずController種類を書かなければならなくて、それからもう1つの方法を書いてページにジャンプして、感じはとても面倒で、実はWebMvcConfigrerの中のaddViewiController方法を書き直して効果を達成することができます。

/**
  *                Controller   ,         
  *                ,    http://localhost:8080/toLogin    login.jsp   
  * @param registry
  */
 @Override
 public void addViewControllers(ViewControllerRegistry registry) {
  registry.addViewController("/toLogin").setViewName("login");
  
 }
値の指摘は、ここでaddView Controller方法を書き換えることで、WebMvcAutoConfigrationの中のaddView Controlles(この方法ではSpring Bootがindexにマッピングする)を上書きしないということであり、これは私達自身の配置とSpring Bootの自動配置が同時に有効であるということを意味します。
3.カスタムリソースマッピングaddResource Handlers
例えば、静的リソースマッピングディレクトリをカスタマイズしたいなら、addResource Handlers方法を書き換えるだけでいいです。
注:もしWebMvcConfigrationSupport類を継承して構成を実現するなら、この方法を書き直さなければならない。具体的には他の文章を参照してください。

@Configuration
public class MyWebMvcConfigurerAdapter implements WebMvcConfigurer {
 /**
  *         
  * @param registry
  */
 @Override
 public void addResourceHandlers(ResourceHandlerRegistry registry) {
  registry.addResourceHandler("/my/**").addResourceLocations("classpath:/my/");
  
 }
}
マッピングパスはaddResource Handlerによって追加され、その後、addResource Locationsによって指定される。私達はカスタムmyフォルダの中のelephand.jpg画像の住所を訪問します。http://localhost:8080/my/elephant.jpg
外部のディレクトリを指定するのも簡単です。直接addResource Locationsで指定すればいいです。コードは以下の通りです。

@Override
 public void addResourceHandlers(ResourceHandlerRegistry registry) {
  registry.addResourceHandler("/my/**").addResourceLocations("file:E:/my/");
  
 }
addResource Locationsとは、ファイルが置かれているディレクトリのことで、addResoure Handlerとは、外部に露出されたアクセス経路のことです。
4.configreDefault Servlet Handling(Default Servlet Handler Configrer configur)
使い方:

 @Override
 public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
  configurer.enable();
  configurer.enable("defaultServletName");
 }
このときはデフォルトのHandler:Default ServletHttpRequest Handlerを登録します。このHandlerも静的なファイルを処理するために使用されています。マッピングを試みます。Dispactch Serveltマッピング/時(/と/は区別があります)、要求を処理するために適切なHandlerが見つからない場合はDefault ServletHttpRequest Handlerに処理します。ここでの静的リソースは、WEB-INFの下ではなく、ウェブルートディレクトリの下に配置されている。
ここの説明はちょっと分かりにくいかもしれませんので、簡単に例を挙げます。例えば、webrootディレクトリの下に写真があります。1.pgはServelt仕様のウェブルートディレクトリのファイルが直接アクセスできると知っていますが、DisplatServletが配置されているので、ほとんどの要求を遮断しました。したがって、1.pngがアクセスできなくなりました。Default ServletHttpRequest Handlerを登録すれば、この問題を解決できます。実際には、DisplatServletがServletの特性を破壊したと考えられ、Default ServletHttpRequest Handlerはこの特性の回帰を助けています。
5、configreView Resvors(View Registry registry)
方法名からこの方法はビュー解像度を設定するためのものであり、この方法のパラメータView Revo Registryは登録器であり、カスタマイズしたいビュー解析器などを登録するためのものであることが分かります。View ReslaverRegistryでよく使われるいくつかの方法:
1)enaboleContententNegotions()

/**            */
public void enableContentNegotiation(View... defaultViews) {
 initContentNegotiatingViewResolver(defaultViews);
}
この方法は、特定のビューの解析ではなく、あなたが登録したすべてのビュー解像度を管理し、すべてのビューを解析して、具体的にどの解像度解析器を使用するかを決定するコンテンツ解決器ContentNegotitVieResoliverを作成します。具体的なマッピング規則は、要求されたmedia typesに基づいて決定される。
2)UrlBasedView ResoverRegistration()

 public UrlBasedViewResolverRegistration jsp(String prefix, String suffix) {
  InternalResourceViewResolver resolver = new InternalResourceViewResolver();
  resolver.setPrefix(prefix);
  resolver.setSuffix(suffix);
  this.viewResolvers.add(resolver);
  return new UrlBasedViewResolverRegistration(resolver);
 }
この方法は内部のリソースビュー解析器InternalResource View Resoloverを登録します。明らかにすべてのjspにアクセスして解析します。この方法パラメータは、パスのプレフィックスとファイルの拡張子を指定するために使用されます。

registry.jsp("/WEB-INF/jsp/", ".jsp");
以上の構成の場合、戻るビュー名がexampleであれば、フロントエンドに、WEB-INF/jsp/example.jspが返され、見つけられない場合、レポート404が返される。  
3).beanName()

 public void beanName() {
  BeanNameViewResolver resolver = new BeanNameViewResolver();
  this.viewResolvers.add(resolver);
 }
この方法はBenName View Resoloverビュー解像器を登録しますが、この解像器は何ですか?主にビューの名前を対応するbeanに解析します。どういう意味ですか?もし戻ってきたビューの名前がexampleだったら、spring容器の中にexampleというbeanがありますか?そしてこのbeanはView.classタイプですか?もしあるなら、このbeanに戻ります。  
4)view Resolover()

 public void viewResolver(ViewResolver viewResolver) {
  if (viewResolver instanceof ContentNegotiatingViewResolver) {
   throw new BeanInitializationException(
     "addViewResolver cannot be used to configure a ContentNegotiatingViewResolver. Please use the method enableContentNegotiation instead.");
  }
  this.viewResolvers.add(viewResolver);
 }
この方法は名前を見てから分かると思いますが、自分で定義したものを含めて、様々なビュー解析器を登録するためのものです。
6.configure Configrer configur)
上記では、configreView Resoluvers方法について説明しましたが、もしこの方法でコンテンツ判定解析器を有効にしたら、configreContintNegotiation(Contination Configur configrer)という方法は、コンテンツ判定のパラメータを設定するために専用のものです。これは比較的簡単です。私たちは直接例を通してみます。

 public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
  /*       Url       media type */
  configurer.favorPathExtension(true) 
     /*    Accept    */
    .ignoreAcceptHeader(true)
    .parameterName("mediaType")
     /*      media yype */
    .defaultContentType(MediaType.TEXT_HTML)
     /*    .html       MediaType.TEXT_HTML*/
    .mediaType("html", MediaType.TEXT_HTML)
    /*    .json       MediaType.APPLICATION_JSON*/
    .mediaType("json", MediaType.APPLICATION_JSON);
 }
ここに来たら、私達は例を挙げて、上記の知識をもっと詳しく知ることができます。もしMVCの配置が次のようになったら、

@EnableWebMvc
 @Configuration
 public class MyWebMvcConfigurerAdapte extends WebMvcConfigurerAdapter {
 
  @Override
  public void configureViewResolvers(ViewResolverRegistry registry) {
   registry.jsp("/WEB-INF/jsp/", ".jsp");
   registry.enableContentNegotiation(new MappingJackson2JsonView());
  }
 
  @Override
  public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
   configurer.favorPathExtension(true)
     .ignoreAcceptHeader(true)
     .parameterName("mediaType")
     .defaultContentType(MediaType.TEXT_HTML)
     .mediaType("html", MediaType.TEXT_HTML)
     .mediaType("json", MediaType.APPLICATION_JSON);
  }
 }
controllerのコードは以下の通りです。

 @Controller
 public class ExampleController {
   @RequestMapping("/test")
   public ModelAndView test() {
   Map<String, String> map = new HashMap();
   map.put("  ", "    ");
   map.put("  ", "    ");
   return new ModelAndView("test", map);
  }
 }
WEB-INF/jspディレクトリの下でtest.jspファイルを作成して、内容は自由です。今tomcatを起動します。ブラウザに以下のリンクを入力してください。http://localhost:8080/test.jsonブラウザの内容は以下の通りに戻ります。

{
 "  ":"    ",
 "  ":"    "
}
ブラウザで入力http://localhost:8080/test またはhttp://localhost:8080/test.htmlを返します。

this is test.jsp
明らかに、2回は違ったビュー解析器を使っていますが、底に何が起こっていますか?設定には二つのビュー解像度を登録しました。
ContingNegotiat View ResoloverとInternal Resource View Resolover、もう一つのデフォルトビューがあります。MappingJackson 2 Json View。controllerが実行された後、ModelAndViewに戻ります。ここで、ビューの名前はexample 1です。
1.戻りはまずContentNegotitVigotitResoloverに任せてビュー解析処理を行いますが、ContingViewResolaverはまずビュー名example 1をそれが持っているすべてのView Resoloverに渡して解析を試みます。
2.要求されたmediaTypeに従って、example 1.mediaType(ここはexample 1.jsonとexample 1)をビュー名として、すべてのビュー解像器を解析してください。2ステップの解析が終わったら、候補のList<View>にデフォルトのMappingJackson 2 JViewを追加します。
3.要求されたmedia typeに基づいて候補のList<View>の中から最適な戻りを選択して、このビューの解析が完了します。
上の例でなぜリンクを要請したのかが分かります。jsonと違います。jsonは結果が違います。jsonを加えると、要求を表すmedia typeはMediaType.APPLICATION_JSONは、InternalResource View Resoloverが解析したビューのContintTypeとは異なり、MappingJackson 2 Json ViewのContintTypeと一致するので、MappingJackson 2 Json Viewをビューとして選択しました。json要求をしない場合、デフォルトのmedia typeはMediaType.TEXT_です。HTMLは、Internal Resource View Resolaverで解析したビューをリターン値として使用しています。ここを見たいですが、大体カスタムビューができます。
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。