IntelliJでSpringFramework(MVC)のmavenプロジェクトHelloWorld(2020/3)

# 目的
Spring FrameworkのMVCを使った新規プロジェクトの作成にちょっとだけ苦労したので、覚書に残します。

なお、大人の事情で、Spring Bootは使いません。


# 環境

|ツールなど|バージョンなど|
|:--|:--|
| MacbookPro |macOS Mojave 10.14.5|
|IntelliJ IDEA |Ultimate 2019.3.3|
|Java |AdoptOpenJDK 11|
|apache maven |3.6.3|
|Spring Framework|5.2.4.RELEASE|
|JUnit|5.6.0|
|Tomcat|apache-tomcat-8.5.51|

jdkやmaven、Tomcatのインストールは済んでいるものとします。
※コマンドラインでmavenコマンドを使わない場合は、mavenのインストールは不要です。(IntelliJにバンドルされています)

# ゴール

Tomcat起動してブラウザで"Hello world"表示。

# 手順

基本的には、下記のページの**[With Maven]**のままです。

- Configure a Spring MVC Project with Intellij IDEA  
  https://iamsaurabh.wordpress.com/2017/02/11/configure-a-spring-mvc-project-with-intellij-idea/

キャプチャを最新版のIntelliJのにして日本語訳していきます。
それとページからコードをコピペすると、`"`(ダブルクォート)がおかしなことになるので、それも直しています。

## プロジェクトの新規作成

- 起動画面で[+ Create New Project]
<img width="774" alt="createproject.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/74287c3d-b737-dc4d-f737-b454aa3618db.png">

## mavenプロジェクトを作成

- 左側のパネルから、mavenを選択
- [Next]をクリック
<img width="948" alt="maven.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/cddbdb82-60b9-31cc-f0a8-b20ffa2008e1.png">

- [Name]と[Location]を入力/選択
- [Artifact Coordinates]をクリックして項目を開き、グループID,アーティファクトIDを入力
- [Finish]をクリック
<img width="950" alt="maveninfo.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/af1a4c31-4689-c82a-b828-24adaf0984e2.png">

プロジェクトが開くので、右下に以下のようなポップアップが表示されたら、[Enable Auto-import]しておくと便利です。
<img width="375" alt="mavenimport.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/b5cfdeea-de0b-4e21-c64f-820604dfeb8d.png">

## 依存関係設定

`pom.xml`(自動で開いたはず)にの`<project>`タグ下に下記を追記します。

*2020/03/09追記*
`<packaging>war</packaging>`の行を追加しました。

```xml:pom.xml
    <packaging>war</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

        <!-- Java version -->
        <java.version>11</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>

        <!-- Spring -->
        <spring.version>5.2.4.RELEASE</spring.version>

        <!-- Test -->
        <junit.version>5.6.0</junit.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>

    </dependencies>
```

gradleで書きたい・・・(こちらも大人の事情でmavenに:cry:)

## Spring WebMVCの設定

- `src/main`下に、`webapp/WEB-INF`ディレクトリを作成
<img width="597" alt="add-webinf-dir.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/b65308b7-d3ed-afcc-5b56-fdfa415d0041.png">
<img width="336" alt="name-webinf.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/66b02428-c35b-d308-8b7f-7168bf308b34.png">

- 作成した`WEB-INF`ディレクトリ下に、`web.xml`ファイルを作成する
<img width="667" alt="create-webxml.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/f6b76bb7-62ec-0d8a-b527-fcdc72b3e630.png">
<img width="335" alt="name-webxml.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/f40c9a4e-7d8e-4496-d794-a6a76299b659.png">

- `web.xml`の中身を以下のようにする

```xml:web.xml
<?xml version="1.0" encoding="UTF8"?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
         version="2.4">

    <display-name>HelloWorld Application</display-name>
    <description>
        This is a simple web application with a source code organization
        based on the recommendations of the Application Developer’s Guide.
    </description>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>
```

- `WEB-INF`フォルダ下に、`dispatcher-servlet.xml`を作成し、以下の内容にする

```xml:dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <mvc:annotation-driven/>
    <context:component-scan base-package="org.example.controllers"/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

</beans>
```

**base-package**属性は、自分が作成する構成に合わせること

## コントローラーの作成

- `dispatcher-servlet.xml`の**base-package**属性に指定したパッケージに、コントローラークラスを作成する。

例)IndexController
<img width="747" alt="create-controller.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/8ec8842d-c618-9f73-cd5c-7d2a8f4a886d.png">
<img width="329" alt="name-controllerclass.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/b6cddc4c-c2de-d100-e826-5f44e70d33fb.png">

- 下記のように実装する

```java:IndexController.java
package org.example.controllers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.ui.Model;

@Controller
public class IndexController {

    @GetMapping("/")
    public String index(Model m) {
        m.addAttribute("someAttribute", "Hello world!");
        return "index";
    }
}
```

## Viewの作成

- `WEB-INF`フォルダ下に、`views`フォルダを作成する
- その下に、`index.jsp`というファイルを作成する
<img width="665" alt="create-jsp.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/6f0802f5-294e-7815-a1aa-7959788875ce.png">
<img width="333" alt="name-jsp.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/76917ff1-f63f-ab11-5193-31697e06fddf.png">

- `<body>`タグ下に、下記の内容を追加する

```jsp:indx.jsp
<body>
<p>${someAttribute}</p>
</body>
```

## Tomcatの設定

### 1. Tomcatディレクトリの設定

- メニューの[IntelliJ IDEA]-[Preference]を開く
- **Build, Execution, Deployment**を開く
- [Application Servers]を選ぶ

<img width="238" alt="setup-tomcat.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/1f642295-2d28-f65d-1443-b869f0250130.png">

- [+]を押して、[Tomcat Server]を選ぶ

<img width="269" alt="select-tomcat.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/eee52a40-d294-7d4d-15b6-0a83643b733b.png">

- Tomcatを置いたフォルダを指定し、OKをクリック

<img width="802" alt="select-tomcat-forder.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/4d6ff400-0123-fc97-7201-ace8e1569083.png">

- OKをクリック

### 2. Configurationを追加する

- ツールバーにある[Add Configuration...]をクリックする

<img width="405" alt="add-configuration.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/07968391-4eef-1f34-fd07-5613b4cf54d6.png">

- [+]を押して、[Tomcat Server]-[Local]を選ぶ
    - [Tomcar Server]が見えない場合は、リストを下にスクロール
    - それでも見えない場合は、[25 more items...]をクリックしてみてください
<img width="506" alt="add-tomcat-localsever.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/81eac070-8179-9349-68dc-3f1ee990a5ee.png">

- [Name]に任意の名称を入力
- 右下の[Fix]アイコンをクリック

<img width="753" alt="setup-run-configuration.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/bb327211-c200-5c77-816d-284a6157eb88.png">

- [hello:war_exploded]を選択

<img width="191" alt="fix-deploy-artifact.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/078142cc-ca31-d699-fc9c-0cc8e066108c.png">

- OKをクリック

## 実行

ツールバーの実行ボタン、またはデバッグボタンをクリック

<img width="333" alt="run.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/5a8ef2ff-71ad-64b1-c54a-39359dfe3678.png">

ブラウザに表示されたら成功！

<img width="642" alt="helloworld.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103886/4b40b74d-8137-e2ed-17de-111bc8a56077.png">

# 感想

Kotlin書きたい(こちらも~~大人の事情で~~)

# 参考

https://ti-tomo-knowledge.hatenablog.com/entry/2018/06/04/082220