SpringMVCのコントローラの戻り値

SpringMVCのコントローラの戻り値

ContorollerからView(jspとかhtmlとか)へ戻り値を戻していますが、これが何を表しているかというとファイル名になります。(String型の場合)

@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
  logger.info("Welcome home! The client locale is {}.", locale);

  Date date = new Date();
  DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);

  String formattedDate = dateFormat.format(date);

  model.addAttribute("serverTime", formattedDate );

  return "home";
}

表示されるのは、WEB-INF\views\home.jspが表示されます。

このhome.jspのhomeとマッピングされています。戻り値に拡張子がないですね。ということで追加してみます。(上記ソースを”home.jsp”と変更するだけ)

これでアクセスしてみます。

SpringMVCのコントローラの戻り値

404エラーとなり、見てのとおりhome.jsp.jspにアクセスしようとしています。

どこでこの拡張子が付加されているかと言うと、web.xml内の以下部分を見ます。

<servlet>
  <servlet-name>appServlet</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>

<param-value>タグで指定されているファイルでViewの指定がされますので、そのファイルを開きます。

<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <beans:property name="prefix" value="/WEB-INF/views/" />
  <beans:property name="suffix" value=".jsp" /> <!-- ここでサフィックスに.jspを指定しています -->
</beans:bean>

Google翻訳では以下のように翻訳されました。

/ WEB-INF / viewsディレクトリの@Controllersによる.jspリソースへのレンダリングのために選択されたビューを解決します。

絶対にViewはjspファイルなら問題ないですがその他拡張子のファイルも有りえるなら、この1行はコメントアウトしたほうがよいです。

戻り値はString型でも色々ある

String型の戻り値にforwardredirectといったキーワードをつけることによって違う動きをさせることができます。

redirectする

以下のように記述することによりメソッドをチェーンすることが可能です。

@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
  logger.info("Welcome home! The client locale is {}.", locale);

  Date date = new Date();
  DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);

  String formattedDate = dateFormat.format(date);

  model.addAttribute("serverTime", formattedDate );

  return "redirect:home1"; // home1メソッドにリダイレクトする
}

@RequestMapping(value = "/home1", method = RequestMethod.GET)
  public String home1(Locale locale, Model model) {
 
  model.addAttribute("serverTime", "redirect to home1" );

  return "home";
}

画面表示内容からhome1メソッドにリダイレクトされているのが確認できます。

SpringMVCのコントローラの戻り値

forwardする

redirectとよく似ていますが今度はhomeメソッドからhome1メソッドにforwardしてみます。

@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
  logger.info("Welcome home! The client locale is {}.", locale);

  Date date = new Date();
  DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);

  String formattedDate = dateFormat.format(date);

  model.addAttribute("serverTime", formattedDate );

  return "forward:home1"; // redirectをforwardに変更しただけ
}

@RequestMapping(value = "/home1", method = RequestMethod.GET)
public String home1(Model model) {

  model.addAttribute("serverTime", "redirect to home1" );

  return "home";
}

これもhome1メソッドにforwardされていることが確認できます。

SpringMVCのコントローラの戻り値

上記だけだと、redirectとforwardの違いがわかりませんが、よくみるとクエリ文字列が違います。

以下のような違いがあります。

キーワード URLの違い
redirect 遷移先のパス+クエリ文字列が渡される
forward URLに変更がない

@ResponseBodyをつける

@RequestMappingと同時に@ResponseBodyも付加するとレスポンスをボディに返すことができます。JSONなどを返したいときはこのアノテーションが使えますね。

@RequestMapping(value = "/", method = RequestMethod.GET)
@ResponseBody
public String home(Locale locale, Model model) {
  return "text text";
}

以下、実行例です。

SpringMVCのコントローラの戻り値

画面に直接文字列が帰ってきているのが確認できます。

String型ではなく、ModelAndViewクラスをリターンする

このModelAndViewクラスがよく使われるかなと思います。クラス名のとおり、ModelとViewを管理するクラスです。

@RequestMapping(value = "", method = RequestMethod.GET)
public ModelAndView home() {
  ModelAndView mv = new ModelAndView();
  mv.addObject("serverTime", "ModelAndView!!!");
  mv.setViewName("home"); // ここでviewを指定する
  return mv;
}

まず、戻り値がString型からModelAndView型に変わります。

addObjectメソッドでModelからの戻り値を設定することになると思います。ここでは簡単にString型にしています。

setViewNameメソッドで、今までreturnしていたview名(jsp)をセットします。

以下、実行例です。

SpringMVCのコントローラの戻り値

ModelAndViewのインスタンス生成時にView名を指定する

実は、ModelAndViewクラスはコンストラクタでView名を指定することができます。

なので、setViewName()メソッドは分岐がなければ使うことはないはずです。

ModelAndView mv = new ModelAndView("home");  // mv.setViewName("home");と同じ

コメント

タイトルとURLをコピーしました