こんにちは、さるまりんです。
RESTful APIをSpring Bootで作っておりまして。
こんな感じのコードを書いておりました。
@RestController
@RequestMapping("/api")
public class SomeController {
@RequestMapping("some")
public @ResponseBody SomeResponse some() {
return new SomeResponse();
}
}
書き進めるうちに幾つかのパスでHTMLを返却する必要があることがわかりました。
そこで@RestController
のアノテーションをつけたコントローラからHTMLを表示する方法です。
ModelAndViewを使う
Spring Bootで画面を作成するときはThymeleafテンプレートエンジンを使うことが多いと思います。
ModelAndView
を使うと、このテンプレートエンジンを使って画面を表示することができます。
@RequestMapping("some-template")
public ModelAndView someTemplate() {
ModelAndView mav = new ModelAndView();
mav.setViewName("some");
mav.addObject("data", data);
return mav;
}
ModelAndView
クラスのオブジェクトを作り(mav = new ModelAndView()
)、
それにview名を設定(mav.setViewName(view名)
)、
埋め込むデータを設定(mav.addObject(名前, 値)
)し、
オブジェクトを返却します。
これでview名で指定されたHTMLに値を埋め込んで表示することができます。
直接書き出す
テンプレートエンジンとか使わずに直接そのままHTMLを返したいときはどうするでしょう?
HttpServletResponse
のwriter
に直接書き込むことで実現できます。
@RequestMapping("some-direct")
public void someDirect(
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
response.setContentType(MediaType.TEXT_HTML_VALUE);
response.getWriter().write("<html><body><h1>RESULT</h1></html>");
}
サーブレットの出力方法、基本になる技術は同じなんですね。
混在させる
一つのメソッド=(エンドポイント)で場合によってはテンプレートエンジンを使いたい時と、そのまま出力したいケースが混在する場合はどうするでしょう。
その場合は単純に条件で分けます。
@RequestMapping("some-if")
public ModelAndView someIf(
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
...処理をして...
if (isSuccess) {
ModelAndView mav = new ModelAndView();
mav.setViewName("success");
mav.addObject("data", data);
return mav;
} else {
response.setContentType(MediaType.TEXT_HTML_VALUE);
response.getWriter().write("<html><body><h1>ERROR</h1></html>");
return null;
}
}
分岐して直接書き出した方はModelAndView
は何も返すものはないのでnull
を返却しています。
作りながら迷ってしまったのでまとめてみました。
RestController
ではもっといろんなことができるのでそれはまた別の機会に。
読んでくださってありがとうござます。
それではまた!