■応用の森 Spring-MVC コントローラの戻り値 |
||||||||||||||||||
Spring-MVC では@Controllerまたは@RestControllerアノテーションが付いたクラスを コントローラとみなして動作します。 @Controllerアノテーションは、主にWebページ単位制御用のコントローラクラスに使用するアノテーションで、 このクラスのメソッドの戻り値は、基本的にJSPやHTMLの遷移先view名を指定します。 @RestControllerは、JSONやXML等の文字列を返すWebAPI用のコントローラクラスに使用するアノテーションで、 基本的にはViewには遷移しないため戻り値は、コンテンツのBodyそのものとなります。 しかしながら、場合によっては@RestControllerでviewを返したい場合や、その逆に @Controllerでコンテンツを返したい場合などもないことはありません。 ここでは、@Controllerまたは@RestControllerアノテーションコントローラのハンドラが どのような戻り値を返すことができるか 簡単なテストを行って一覧にまとめてみました。 |
||||||||||||||||||
○:使用可、△:使い道が今一つ浮かばないので割愛 |
||||||||||||||||||
|
||||||||||||||||||
※1)@Controllerクラスの@RequestMapping ハンドラ・メソッドのもっとも単純な戻り値です。 Viewの遷移先を指定します。 view名はSpring設定ファイル(applicationContext.xml)の<templateResolver>で定義されているprefix配下の suffixの拡張子を持つファイルを、拡張子をはずした名前で指定します。 @Controller public class MyClass { @RequestMapping("/mapping") public String handler_method() { return "viewname"; //view名 viewname.html に遷移します。 } } ※2)@RestControllerクラスの@RequestMapping ハンドラ・メソッドでViewの遷移先を指定。 @RestControllerクラスは通常は、コンテンツを返しますが、viewを返すこともできます。 viewの指定方法は、※1)と同様にModelAndView()の引数に指定することができます。 @RestController public class MyClass { @RequestMapping("/mapping") public ModelAndView handler_method() { return new ModelAndView("viewname"); //view名 viewname.html に遷移します。 } } ※3)@Controllerクラスの@RequestMapping ハンドラ・メソッドでView遷移ではなくコンテンツを返す指定。 メソッドに@ResponseBodyアノテーションを付加することで View遷移ではなく文字列形式のコンテンツを返すことができます。 @Controller public class MyClass { @RequestMapping("/mapping") @ResponseBody public String handler_method() { return "<div>コンテンツ</div>"; } } ※4)@RestControllerクラスの@RequestMapping ハンドラ・メソッドでコンテンツを返す一番単純な戻り値です。 @Controllerクラスと違い、@ResponseBodyを付ける必要がありません。 @RestController public class MyClass { @RequestMapping("/mapping") public String handler_method() { return "{"key":"value"}"; //JSON形式を返す } } @RequestMappingでは、コンテンツタイプを指定することができます。 例)@RequestMapping(value = "/mapping", produces = "application/xml") や @RequestMapping(value = "/mapping", produces = "text/html;charset=UTF-8") や @RequestMapping(value = "/mapping", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) など、色々と指定できます。 返却文字列に日本語全角文字が含まれている場合、ブラウザで文字化けするので、この指定は必須です。 JSONや、XMLデータを返したいような場合は、この形式で返すのが適しています。 ※5)@Controllerクラスの@RequestMapping ハンドラ・メソッドでpageをフォワードする指定。 戻り値で指定する遷移先に"forward:"を付けると他の@RequestMapping ハンドラ・メソッドにフォワードします。 ここで注意することは、遷移先はリクエストパターンを含めたURLを指定する必要があります。 ※)ここでは、リクエストパターンに *.xhtml を使っているので、****.xhtml を指定しています。 @Controller public class MyClass { @RequestMapping("/mapping") public String handler_method() { return "forward:/forward_to.xhtml"; // /forward_to.xhtml にフォワードする } } ※6)@Controllerクラスの@RequestMapping ハンドラ・メソッドでpageをリダイレクトする指定。 戻り値で指定する遷移先に"redirect:"を付けると他の@RequestMapping ハンドラ・メソッドにリダイレクトします。 ここで注意することは、遷移先はリクエストパターンを含めたURLを指定する必要があります。 ※)ここでは、リクエストパターンに *.xhtml を使っているので、****.xhtml を指定しています。 @Controller public class MyClass { @RequestMapping("/mapping") public String handler_method() { return "redirect:/redirect_to.xhtml"; // /redirect_to.xhtml にリダイレクトする } } リダイレクト先は、まったく別のURLも指定可能です。 例)return "redirect:https://www.google.co.jp/"; ・フォワードとリダイレクトの違いについて ネットを探すと、フォワードとリダイレクトの違いについてはいくらでも情報があるので、 基本的な違いは、それらを読んでもらうことにして、 Spring-MVCにおける具体的なフォワードとリダイレクトの違いについて簡単に説明します。 フォワード :・from ⇒ to にフォワードする際に、fromが持っているパラメータを toに継承することができます。 ・ブラウザのURLは、from のままで、to の処理が実行されます。 ※この性質上、ブラウザのリロード処理で思わぬ動きをすることがあるので注意が必要です。 リダイレクト:・from ⇒ to にリダイレクトする際に、fromが持っているパラメータは toに継承することはできません。 例外として、RedirectAttributesというFlash scopeを使うことで、パラメータ値を継承可能となっています。 ただし、クラスのオブジェクトのようなBeanは継承できないみたいです。 ・ブラウザのURLは、to に変わります。 さらに、RedirectAttributesを使用した場合、リダイレクトURLの後ろに、パラメータが付加されて見えてしまう。 ちょっとカッコ悪いです。 ※7)ファイルをダウンロードする指定。 7-1)Resourceインターフェース形式でダウンロードする。 import org.springframework.core.io.Resource; @Controller public class MyClass { @RequestMapping("/mapping") public Resource handler_method() { return new FileSystemResource("downloadfile名"); } } ・メリット :シンプルなコードでファイルのダウンロードが可能 ・デメリット:ファイルの形式にも拠りますが、ダウンロードファイルは、 ブラウザに表示され、ファイルとしてダウンロードできない。 7-2)HttpServletResponse形式でダウンロードする。(昔ながらのやり方) @Controller public class MyClass { @RequestMapping("/mapping") public void handler_method(HttpServletResponse res) { File file = new File("downloadfile名"); //ファイル名に全角がある場合(Chrome/IE)Safari:NG String fname = URLEncoder.encode(file.getName(), "UTF-8"); //attachment ⇒ inline にすれば、ブラウザで表示 res.setHeader("Content-Disposition","attachment; filename=\""+fname+"\""); //ファイル名に全角がある場合FireFoxは以下で行ける //res.setHeader("Content-Disposition","attachment; filename*=\"UTF-8''"+fname+"\""); res.setContentLength((int) file.length()); FileCopyUtils.copy(new FileInputStream(file), res.getOutputStream()); } } ・メリット :ダウンロードファイルは、ファイルとしてダウンロードが可能。 ・デメリット:特になし。 |
||||||||||||||||||
これ以外にも、使える戻り値はまだいろいろとあるみたいですが、 よっぽどのことがない限り、これだけ使い方を知っていれば十分ではないかと思います。 |
Spring-MVCの小技集 ![]() |
Spring-MVC コントローラの戻り値 |