1前書き

簡単に言うと、

Front Controller

デザインパターン

__には、受信した

HttpRequests__をアプリケーションの他のすべてのコントローラーやハンドラーに転送する責任があるのは単一のコントローラーです。

Springの

DispatcherServlet

はこのパターンを実装しているため、

HttpRequests

を適切なハンドラに正しく調整する責任があります。

この記事では、

Spring __DispatcherServletの要求処理ワークフロー

と、このワークフローに参加するいくつかのインターフェースの実装方法について説明します。


2

DispatcherServlet

リクエスト処理

基本的に、


DispatcherServlet

は着信の

HttpRequest

を処理し、リクエストを委任し、ハンドラ、コントローラエンドポイント、およびレスポンスオブジェクトを指定する付随するアノテーションとともに、Springアプリケーション内に実装されている設定済みの

HandlerAdapter

インタフェース

に従ってそのリクエストを処理します。


DispatcherServlet

がコンポーネントをどのように処理するかについて、さらに詳しく説明しましょう。


  • DispatcherServlet

    に関連付けられた

    WebApplicationContext

キー

DispatcherServlet.WEB

APPLICATION

CONTEXT

ATTRIBUTE


プロセスのすべての要素を検索して使用可能にする
**

DispatcherServlet__は、のすべての実装を見つけます。

使用するディスパッチャ用に設定された

HandlerAdapter

インタフェース

getHandler() – 検出され設定された各実装は、
プロセスの残りまでの

handle()

を介した要求
**


LocaleResolver

__はオプションでにバインドされます。

プロセス内の要素がロケールを解決できるようにする要求
**


ThemeResolver


はオプションでにバインドされる

使用するテーマをビューなどの要素に決定させる要求
**


MultipartResolver


が指定されている場合、

リクエストは


_MultipartFile


sについて検査されます – 見つかったものはすべてaでラップされます
さらに処理するための

MultipartHttpServletRequest

**


HandlerExceptionResolver

_


WebApplicationContext

で宣言された実装は、リクエストの処理中にスローされる例外を受け取ります


DispatcherServlet


ここ


3

HandlerAdapter

インターフェース


HandlerAdapter

インタフェースは、いくつかの特定のインタフェースを通じて、コントローラ、サーブレット、

HttpRequests

、およびHTTPパスの使用を容易にします。

したがって、

HandlerAdapter

インターフェースは、

DispatcherServlet

要求処理ワークフロー

の多くの段階を通じて重要な役割を果たします。

まず、各

HandlerAdapter

実装は、ディスパッチャの

getHandler()

メソッドから

HandlerExecutionChain

に配置されます。

次に、これらの各実装は、実行チェーンが進むにつれて

HttpServletRequest

オブジェクトを

handle()

します。

次のセクションでは、最も重要で一般的に使用されている

HandlerAdapters

のいくつかについて詳しく説明します。


3.1. マッピング

コントローラは

HandlerMapping

インタフェースにとって非常に重要なので、マッピングを理解するために、まずコントローラに注釈を付ける方法を調べる必要があります。


SimpleControllerHandlerAdapter

を使用すると、

@ Controller

アノテーションなしで明示的にコントローラを実装できます。


RequestMappingHandlerAdapter

は、

@ RequestMapping

アノテーションでアノテーションが付けられたメソッドをサポートします

ここでは

@ Controller

アノテーションに焦点を当てますが、いくつかのリンクがある便利なリソース:/spring-mvc-handler-adapters[

SimpleControllerHandlerAdapter

を使用した例]も利用できます。


  • @ RequestMapping

    アノテーションは、それに関連付けられた

    WebApplicationContext

    内で** ハンドラが利用可能になる特定のエンドポイントを設定します。


‘/user/example’

エンドポイントを公開して処理する

Controller

の例を見てみましょう。

@Controller
@RequestMapping("/user")
@ResponseBody
public class UserController {

    @GetMapping("/example")
    public User fetchUserExample() {
       //...
    }
}


@ RequestMapping

アノテーションで指定されたパスは、

HandlerMapping

インターフェースを介して内部的に管理されます。

  • URL構造は、当然のことながら

    DispatcherServlet

    自体に相対的であり、サーブレットマッピングによって決定されます。

したがって、

DispatcherServlet

が ‘/’にマッピングされている場合、すべてのマッピングはそのマッピングによってカバーされます。

ただし、サーブレットマッピングが代わりに「

/dispatcher

」になっている場合、@ RequestMappingアノテーションはそのルートURLを基準にしたものになります。

  • ‘/’はサーブレットマッピングの ‘/



    と同じではありません。 「/」はデフォルトのマッピングで、すべてのURLをディスパッチャの責任範囲に公開します。

「/** 」は、多くの新しいSpring開発者を混乱させています。同じURLコンテキストを持つすべてのパスがディスパッチャの責任範囲に含まれるとは指定されていません。代わりに、他のディスパッチャマッピングを上書きして無視します。それで、 ‘/example’は404として登場します。

そのため、非常に限られた状況(フィルタの設定など)を除いて、

‘/

‘を使用しないでください。


3.2. HTTPリクエスト処理


  • DispatcherServlet

    の中心的な役割は、受信した

    HttpRequests

    を** @ Controller

    または

    @ RestController__アノテーションで指定された正しいハンドラにディスパッチすることです。

補足として、

@ Controller



@ RestController

の主な違いは、応答の生成方法です –

@ RestController

は、デフォルトで

@ ResponseBody

も定義します。

Springのコントローラについてもっと深く書いた記事は

ここ

にあります。


3.3.

ViewResolver

インタフェース


ViewResolver

は、

ApplicationContext

オブジェクトの設定として

DispatcherServlet

にアタッチされています。


  • ViewResolver

    はディスパッチャによって提供されるビューの種類とそれらが提供される場所の両方を決定します**

これはJSPページをレンダリングするための

__AppConfig

__に配置する設定例です。

@Configuration
@EnableWebMvc
@ComponentScan("com.baeldung.springdispatcherservlet")
public class AppConfig implements WebMvcConfigurer {

    @Bean
    public UrlBasedViewResolver viewResolver() {
        UrlBasedViewResolver resolver
          = new UrlBasedViewResolver();
        resolver.setPrefix("/WEB-INF/jsp/");
        resolver.setSuffix(".jsp");
        resolver.setViewClass(JstlView.class);
        return resolver;
    }
}

とても簡単です。これには3つの主要部分があります。

  1. プレフィックスを設定します. これは、セットを見つけるためのデフォルトのURLパスを設定します.

内のビュー
。接尾辞で設定されるデフォルトのビュータイプ

  1. のような技術を可能にするリゾルバのビュークラスを設定する

レンダリングされたビューに関連付けるJSTLまたはTiles

  • よくある質問の1つに、ディスパッチャの

    ViewResolver

    ** とプロジェクト全体のディレクトリ構造がどれほど正確に関連しているかが含まれます。基本を見てみましょう。

これは、SpringのXML設定を使用した

InternalViewResolver

のパス設定の例です。

<property name="prefix" value="/jsp/"/>

私たちの例のために、私たちは私たちのアプリケーションがホストされていると仮定します

http://localhost:8080/----

これは、ローカルにホストされているApache Tomcatサーバーのデフォルトのアドレスとポートです。

アプリケーションの名前が__dispatcherexample-1.0.0__であると仮定すると、JSPビューには次の場所からアクセスできます。

[source,text,gutter:,true]

Mavenによる通常のSpringプロジェクト内でのこれらの見解への道はこれです。

src -|
     main -|
            java
            resources
            webapp -|
                    jsp
                    WEB-INF

ビューのデフォルトの場所はWEB-INFです。上記のスニペットの

InternalViewResolver

に指定されたパスによって、ビューが利用可能になる「src/main/webapp」のサブディレクトリが決まります。


3.4.

LocaleResolver

インターフェース

  • ディスパッチャのセッション、リクエスト、またはCookie情報をカスタマイズする主な方法は、

    LocaleResolver

    インタフェースを使用することです。


CookieLocaleResolver

は、クッキーを使用してステートレスアプリケーションプロパティの設定を可能にする実装です。それを

AppConfig

に追加しましょう。

@Bean
public CookieLocaleResolver cookieLocaleResolverExample() {
    CookieLocaleResolver localeResolver
      = new CookieLocaleResolver();
    localeResolver.setDefaultLocale(Locale.ENGLISH);
    localeResolver.setCookieName("locale-cookie-resolver-example");
    localeResolver.setCookieMaxAge(3600);
    return localeResolver;
}

@Bean
public LocaleResolver sessionLocaleResolver() {
    SessionLocaleResolver localeResolver = new SessionLocaleResolver();
    localeResolver.setDefaultLocale(Locale.US);
    localResolver.setDefaultTimeZone(TimeZone.getTimeZone("UTC"));
    return localeResolver;
}


SessionLocaleResolver

を使用すると、ステートフルアプリケーションでセッション固有の設定を行うことができます。


setDefaultLocale

()メソッドは地理的、政治的、または文化的な地域を表しますが、

setDefaultTimeZone

どちらの方法も

LocaleResolver

の上記の各実装で利用できます。


3.5.

ThemeResolver

インターフェース

Springは私たちの見解に文体的なテーマを提供しています。

テーマを処理するようにディスパッチャを設定する方法を見てみましょう。

まず、静的テーマファイルを見つけて使用するために必要なすべての設定を行いましょう。実際の

Themes

自体を設定するには、

ThemeSource

に静的なリソースの場所を設定する必要があります(

Theme

オブジェクトには、それらのファイルで規定されているすべての設定情報が含まれています)。これを

AppConfig

に追加します。

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/resources/** ** ")
      .addResourceLocations("/", "/resources/")
      .setCachePeriod(3600)
      .resourceChain(true)
      .addResolver(new PathResourceResolver());
}

@Bean
public ResourceBundleThemeSource themeSource() {
    ResourceBundleThemeSource themeSource
      = new ResourceBundleThemeSource();
    themeSource.setDefaultEncoding("UTF-8");
    themeSource.setBasenamePrefix("themes.");
    return themeSource;
}


DispatcherServlet

によって管理されるリクエストは、

ThemeChangeInterceptor

オブジェクトで利用可能な

setParamName

()に渡される指定されたパラメータを通してテーマを変更することができます


_.



AppConfigに追加:+ _

@Bean
public CookieThemeResolver themeResolver() {
    CookieThemeResolver resolver = new CookieThemeResolver();
    resolver.setDefaultThemeName("example");
    resolver.setCookieName("example-theme-cookie");
    return resolver;
}

@Bean
public ThemeChangeInterceptor themeChangeInterceptor() {
   ThemeChangeInterceptor interceptor
     = new ThemeChangeInterceptor();
   interceptor.setParamName("theme");
   return interceptor;
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(themeChangeInterceptor());
}

正しいスタイルを表示するために、次のJSPタグがビューに追加されています。

<link rel="stylesheet" href="${ctx}/<spring:theme code='styleSheet'/>" type="text/css"/>

次のURLリクエストは、設定された

ThemeChangeIntercepterに渡された「theme」パラメータを使用して

example__テーマをレンダリングします。

http://localhost:8080/dispatcherexample-1.0.0/?theme=example


3.6.

MultipartResolver

インタフェース


MultipartResolver

実装はマルチパートの要求を検査し、少なくとも1つのマルチパートが見つかった場合、プロセス内の他の要素によるさらなる処理のためにそれらを

MultipartHttpServletRequest

にラップします。

AppConfig

に追加します。

@Bean
public CommonsMultipartResolver multipartResolver()
  throws IOException {
    CommonsMultipartResolver resolver
      = new CommonsMultipartResolver();
    resolver.setMaxUploadSize(10000000);
    return resolver;
}


MultipartResolver

Beanを設定したので、

MultipartFile

要求を処理するためのコントローラを設定しましょう。

@Controller
public class MultipartController {

    @Autowired
    ServletContext context;

    @PostMapping("/upload")
    public ModelAndView FileuploadController(
      @RequestParam("file") MultipartFile file)
      throws IOException {
        ModelAndView modelAndView = new ModelAndView("index");
        InputStream in = file.getInputStream();
        String path = new File(".").getAbsolutePath();
        FileOutputStream f = new FileOutputStream(
          path.substring(0, path.length()-1)
          + "/uploads/" + file.getOriginalFilename());
        int ch;
        while ((ch = in.read()) != -1) {
            f.write(ch);
        }
        f.flush();
        f.close();
        in.close();
        modelAndView.getModel()
          .put("message", "File uploaded successfully!");
        return modelAndView;
    }
}

指定されたエンドポイントにファイルを送信するために通常のフォームを使用できます。

アップロードされたファイルは「CATALINA__HOME/bin/uploads」にあります。


3.7.

HandlerExceptionResolver

インタフェース

Springの

HandlerExceptionResolver

は、Webアプリケーション全体、単一のコントローラ、または一連のコントローラに対して統一されたエラー処理を提供します。

  • アプリケーション全体のカスタム例外処理を提供するには、

    @ ControllerAdvice

    ** のアノテーションを付けたクラスを作成します。

@ControllerAdvice
public class ExampleGlobalExceptionHandler {

    @ExceptionHandler
    @ResponseBody
    public String handleExampleException(Exception e) {
       //...
    }
}


@ ExceptionHandler

というアノテーションが付けられたそのクラス内のメソッドはすべて、ディスパッチャの責任範囲内のすべてのコントローラで使用できます。


DispatcherServletのApplicationContext

での

HandlerExceptionResolver

インターフェースの実装は、

@ ExceptionHandler

がアノテーションとして使用され、正しいクラスがパラメータとして渡されるときはいつでも、そのディスパッチャの責任の範囲内で特定のコントローラを傍受するために利用できます

@Controller
public class FooController{

    @ExceptionHandler({ CustomException1.class, CustomException2.class })
    public void handleException() {
       //...
    }
   //...
}

上記の例では、

CustomException1

または

CustomException2のいずれかの例外が発生した場合、

handleException()

メソッドが

FooController__の例外ハンドラとして機能します。


こちら

Spring Webアプリケーションでの例外処理について詳しく説明した記事です。


4結論

このチュートリアルでは、Springの

DispatcherServlet

とその設定方法をいくつか紹介しました。

いつものように、このチュートリアルで使われているソースコードはhttps://github.com/eugenp/tutorials/tree/master/spring-dispatcher-servlet[over Github]です。