LoginSignup
5
4

More than 3 years have passed since last update.

Visual Studio CodeによるSpring5 MVC Webアプリ開発 HelloWorld作成編

Last updated at Posted at 2020-03-12

はじめに

こちらで作成したひな型にHelloWorldを作成していきます。

環境

OS:Windows 10 Pro 64bit
Editor:Visual Studio Code 1.42.1
JDK:AdoptOpenJDK 11.0.6+10 x64
Apache Maven:v3.6.3
Apache Tomcat:v9.0.31

pom.xml

pom.xmlにSpring MVCに必要なRepositoryを追加します。

Repositoryの検索はMVN REPOSITORYを使用しています。
https://mvnrepository.com/

propertiesに追加

<spring.version>5.2.4.RELEASE</spring.version>
<!-- web.xmlが無い場合でもビルドを実行する -->
<failOnMissingWebXml>false</failOnMissingWebXml>

dependenciesに追加

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

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring.version}</version>
        <scope>compile</scope>
</dependency>

<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf-spring5</artifactId>
    <version>3.0.11.RELEASE</version>
    <scope>compile</scope>
</dependency>

<dependency>
    <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-springsecurity5</artifactId>
        <version>3.0.4.RELEASE</version>
        <scope>compile</scope>
</dependency>

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.10</version>
    <scope>provided</scope>
</dependency>

pom.xml全体です。

pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>hello</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>11</java.version>
        <spring.version>5.2.4.RELEASE</spring.version>
        <!-- web.xmlが無い場合でもビルドを実行する -->
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>

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

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
            <version>3.0.11.RELEASE</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-java8time</artifactId>
            <version>3.0.4.RELEASE</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>

MvcConfig.java

「D:\JAVA\Project\hello\src\main\java\com\example\web\config」に作成します。
フォルダが無い場合はフォルダを作成して下さい。

MvcConfig.java
package com.example.web.config;

import java.nio.charset.StandardCharsets;

import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.resource.VersionResourceResolver;
import org.thymeleaf.extras.java8time.dialect.Java8TimeDialect;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
import org.thymeleaf.templatemode.TemplateMode;

@EnableWebMvc // Spring MVCを有効化する
@Configuration
@ComponentScan(basePackages = {"com.example.web.controller"})
public class MvcConfig implements WebMvcConfigurer {
    @Bean
    public SpringResourceTemplateResolver templateResolver() {
        SpringResourceTemplateResolver templateResolver =
                new SpringResourceTemplateResolver();
        // ビューを保存するフォルダ名を指定する
        templateResolver.setPrefix("/WEB-INF/templates/");
        // ビューの拡張子を指定する
        templateResolver.setSuffix(".html");
        // テンプレートモードをHTMLに指定する
        templateResolver.setTemplateMode(TemplateMode.HTML);
        // テンプレートを読み込む際の文字コードを指定する
        templateResolver.setCharacterEncoding(StandardCharsets.UTF_8.name());

        templateResolver.setCacheable(false);
        return templateResolver;
    }

    @Bean
    public SpringTemplateEngine templateEngine(SpringResourceTemplateResolver templateResolver) {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        // SpringResourceTemplateResolverをセットする
        templateEngine.setTemplateResolver(templateResolver());
        // SpELのコンパイラを有効化してパフォーマンスを向上させる
        templateEngine.setEnableSpringELCompiler(true);
        // Date and Time APiを利用するためのDialectを追加
        templateEngine.addDialect(new Java8TimeDialect());
        return templateEngine;
    }

    @Bean
    public ThymeleafViewResolver viewResolver(SpringTemplateEngine templateEngine) {
        ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
        viewResolver.setTemplateEngine(templateEngine);
        // ビューを書き出す際の文字コードを指定する
        viewResolver.setCharacterEncoding(StandardCharsets.UTF_8.name());
        return viewResolver;
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**")
                .addResourceLocations("/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/")
                .resourceChain(false)
                .addResolver(new VersionResourceResolver()
                        .addContentVersionStrategy("/**"));
    }

    //メッセージソースの設定
    //WEBページでプロパティファイルを使用できる
    //日本語メッセージ:messages_ja.properties
    @Bean
    public MessageSource messageSource() {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasename("classpath:i18n/messages");

        // trueをセットすれば、メッセージのキーがない場合にキーを表示
        // false の場合、NoSuchMessageExceptionを投げる
        messageSource.setUseCodeAsDefaultMessage(true);
        messageSource.setDefaultEncoding("UTF-8");
        // # -1 : リロードしない、0 : 常にリロードする
        messageSource.setCacheSeconds(0);
        return messageSource;
    }
}

WebAppInitializer.java

「D:\JAVA\Project\hello\src\main\java\com\example\web\config」に作成します。
フォルダが無い場合はフォルダを作成して下さい。

WebAppInitializer.java
package com.example.web.config;

import java.nio.charset.StandardCharsets;

import javax.servlet.Filter;

import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    /**
     * ビジネスロジックなど、Spring MVC以外に関するJava Configクラスを指定します。
     */
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] {};
    }

    /**
     * Spring MVCに関するJava Configクラスを指定します。
     */
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] {MvcConfig.class};
    }

    /**
     * DispatcherServletに対するURLパターンを指定します。
     * "/"を指定することで、全リクエストをDispatcherServletが受け取ります。
     */
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    /**
     * サーブレットフィルターを指定します。
     * 複数のフィルターがあった場合、配列に指定した順番に実行されます。
     */
    @Override
    protected Filter[] getServletFilters() {
        return new Filter[]{
                new CharacterEncodingFilter(StandardCharsets.UTF_8.name(), true)};
    }
}

Controllerの作成

「D:\JAVA\Project\hello\src\main\java\com\example\web\controller」に作成します。
フォルダが無い場合はフォルダを作成して下さい。

RootController.java
package com.example.web.controller;

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

@Controller
public class RootController {

    @GetMapping("/")
    public String root() {
        // "redirect:"を先頭につけるとリダイレクトになる
        return "redirect:hello/index";
    }

}
HelloController.java
package com.example.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("/hello")
public class HelloController {

    @GetMapping("/index")
    public String indexGet() {
        return "hello/index";
    }
}

Viewの作成

「D:\JAVA\Project\hello\src\main\webapp\WEB-INF\templates\hello」に作成します。
フォルダが無い場合はフォルダを作成して下さい。

index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Hello World</title>
    </head>

    <body>
        <h1>Hello World</h1>
    </body>
</html>

コンパイル

次のコマンドでコンパイル及びwarファイルの作成が出来ます。

mvn package
D:\JAVA\Project\hello>mvn package
[INFO] Scanning for projects...
[INFO]
[INFO] -------------------------< com.example:hello >--------------------------
[INFO] Building hello 1.0-SNAPSHOT
[INFO] --------------------------------[ war ]---------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hello ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory D:\JAVA\Project\hello\src\main\resources
[INFO] 
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ hello ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 4 source files to D:\JAVA\Project\hello\target\classes
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ hello ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory D:\JAVA\Project\hello\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ hello ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ hello ---
[INFO] 
[INFO] --- maven-war-plugin:2.2:war (default-war) @ hello ---
[INFO] Packaging webapp
[INFO] Assembling webapp [hello] in [D:\JAVA\Project\hello\target\hello-1.0-SNAPSHOT]
[INFO] Processing war project
[INFO] Copying webapp resources [D:\JAVA\Project\hello\src\main\webapp]
[INFO] Webapp assembled in [164 msecs]
[INFO] Building war: D:\JAVA\Project\hello\target\hello-1.0-SNAPSHOT.war
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.883 s
[INFO] Finished at: 2020-03-08T20:35:04+09:00
[INFO] ------------------------------------------------------------------------

動作確認

コマンドパレット

Tomcat: Add Tomcat Server

Tomcatフォルダ選択ダイアログが表示されますので、
先程Tomcatを解凍したフォルダ(D:\JAVA\Tomcat\apache-tomcat-9.0.31)を選択します。

コマンドパレット

Tomcat: Run on Tomcat Server

warファイル選択ダイアログが表示されますので、「mvn package」で作成されたwarファイル(D:\JAVA\Project\SpringSample01\target\hello-1.0-SNAPSHOT.war)を選択します。

http://localhost:8080/」にアクセスして下さい。
設定によっては、自動でブラウザが立ち上がります。
tomcat2.jpg

hello-1.0-SNAPSHOTをクリックして下さい。

「Hello World」が表示されます。
tomcat3.jpg

今回のサンプルソース

GitHubにアップしました。
https://github.com/t-skri1/SpringSample01

参考/出典

VScodeでMVN, Tomcat, JSP/ServletでWebアプリ開発メモ
https://qiita.com/harhogefoo/items/2fa52ecee90b7a25e4c9

まとめ

今回のサンプルはMVCのうち、ViewとControllerだけになっています。
Modelを追加するには別途設定が必要です。
設定方法はSQL Serverへの接続サンプルで投稿します。

5
4
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
5
4