11
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Spring Framework勉強メモ 2 - FreeMarkerでViewを作成

Posted at
スクリーンショット 2016-02-07 17.42.02.png

はじめに

前回は、Spring Bootを用いて、MySQLのデータベースから読み込んだデータを返すRESTful APIを作成しました。

今回は、Web APIではなく、Viewを作成してみます。JavaのViewと言えばJSPが定番ですが、Spring BootではJarへの組み込みのサーブレットを使用する関係上、機能が制限されるためJSPの使用は避けるべきとReferenceに記述されています。

使用できるテンプレートは以下に紹介されています。
http://docs.spring.io/spring-boot/docs/1.2.2.RELEASE/reference/htmlsingle/#boot-features-spring-mvc-template-engines

今回はFreeMarkerを用いて、基本的なViewの作成、ModelデータのViewへの受け渡しといったことを行います。

FreeMarker http://freemarker.incubator.apache.org/

基本的な構成

ディレクトリ構成

スクリーンショット 2016-02-07 16.57.29.png

build.gradleに必要なライブラリを追加します。今回はデータベースにアクセスしないのでシンプルに以下の二つだけです。

....

jar {
    baseName = 'spring-web-sample'
    version =  '0.1.0'
}
....

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web")
    compile("org.springframework.boot:spring-boot-starter-freemarker")
}

Model, Serviceの作成

今回作成するサンプルアプリケーションは、メッセージの入力をフォームから行い、そのリストを表示するというシンプルなものです。まず、メッセージを保持するモデルクラスを作成します。

Message.java

public class Message {
    @NotEmpty
    private String message = "";

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

次にメッセージを格納取得するためのサービスを作成します。サービスの実装は、Spring FrameworkらしくDependency Injectionを用いたいのでBean化します。@Serviceアノテーションがそれにあたります。@Service@Component同様、@Autowireアノテーションで変数に割り当てることが可能です。(後で使用します)

MessageService.java

public interface MessageService {
    void addMessage(String message);

    List<Message> getMessages();
}

MessageServiceImpl.java

@Service
public class MessageServiceImpl implements MessageService {
    private List<Message> messages;

    public MessageServiceImpl() {
        messages = new ArrayList<Message>();
    }

    @Override
    public void addMessage(String message) {
        Message messageObj = new Message();
        messageObj.setMessage(message);
        messages.add(messageObj);
    }

    @Override
    public List<Message> getMessages() {
        return messages;
    }
}

ControllerおよびViewの作成

Viewを作成するControllerは前回の記事で使用した@RestControllerではなく@Controllerを用います。@ControllerでViewを返す方法はいくつかの方法があります。ここでは、シンプルにページの名前を返します。("index")

@Controller
public class IndexController {
    @Autowired
    private MessageService servie;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String showTopPage() {
        return "index";
    }
}

次にViewのテンプレートを作成します。FreeMarkerは本家のページでも記述されているようにテンプレート + Javaのコードからのデータの挿入でHTMLファイルを作成します。テンプレートファイルの置き場所をapplication.propertiesに記述します

spring.freemarker.template-loader-path=/WEB-INF/templates

この画面ではフォームを使ってメッセージを入力するだけなので、FreeMarker的な記述はほとんど入っていません。message変数にユーザが入力したメッセージが挿入されてController側にPOSTで渡ります。

index.ftl

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Hello Spring</title>
    </head>
    <body>
        <form role="form" action="" method="post">
            <div>
                <label for="message">message</label>
    	        <input type="message" name="message" id="message" required autofocus/>
            </div>
            <button type="submit">submit</button>
        </form>
    </body>
</html>

先ほど作成した、IndexControllerにフォームからのメッセージを受信する部分を作成します。@MdelAttributeを用いて、フォームからの入力メッセージをMessageクラスのオブジェクトとして受け取ることができます。受け取ったメッセージは、@Autowiredで取得したMessageServiceを通して保存します。"redirec:messages"でmessageビューに遷移をします。

@Controller
public class IndexController {
    @Autowired
    private MessageService servie;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String showTopPage() {
        return "index";
    }
    @RequestMapping(method=RequestMethod.POST)
    public String handleMessage(@Valid @ModelAttribute("form") Message message) {
        servie.addMessage(message.getMessage());
        return "redirect:messages";
    }
}

messageビューは、今までのメッセージのリストを表示します。<#list messages as message>という記述でmessagesオブジェクトをfor文のように順にmessageオブジェクトとして扱うことができます。

message.ftl

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Messages</title>
    </head>
    <body>
        <hr>
        <#list messages as message>
            ${message.message}
            <hr>
        </#list>
        <a href="/">Back to Home</a>
    </body>
</html>

messageビューにmessagesオブジェクトを渡すコントローラーは以下のようになります。ModelAndViewというクラスを返すことで、ビューページ名の指定と引き渡すJavaのオブジェクト(モデル)指定することができます。

@Controller
@RequestMapping("/messages")
public class MessageController {
    @Autowired
    private MessageService service;

    @RequestMapping(method= RequestMethod.GET)
    public ModelAndView showMessagesPage() {
        return new ModelAndView("messages", "messages", service.getMessages());
    }
}

最後にApplicationクラス作成します。これは特に通常と変わりません。

@SpringBootApplication // same as @Configuration @EnableAutoConfiguration @ComponentScan
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

#動作確認
ビルド、および実行は以下のGradleで以下のように行います

$ ./gradlew build
$ java -jar build/libs/spring-web-sample-0.1.0.jar

http://localhost:8080
にアクセスすると以下のような画面が見れます

スクリーンショット 2016-02-07 17.42.02.png

メッセージを入力して、Submitボタンを押すとhttp://locahost:8080/messages
に移動します

スクリーンショット 2016-02-07 17.42.17.png

http://locahost:8080/messages
スクリーンショット 2016-02-07 17.42.32.png

"Back to Home"を押して、再度メッセージを追加するとどんどんリストに表示されます。
スクリーンショット 2016-02-07 17.42.50.png

もちろんデータベースなどを用いて永続化しているわけではないので、起動しなおすとメッセージは全て消えます。

11
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?