Spring Initializrで「Spring Web」にチェックを入れると、pom.xmlに spring-boot-starter-web が入ってきますよね。チュートリアル通りに動くけれど、「これって結局何を持ち込んでいるの?」「webflux や webmvc と何が違うの?」と聞かれると答えに詰まる人は多いはずです。

一言でいうと、spring-boot-starter-web は Spring MVC と組み込み Tomcat で Web アプリや REST API を作るためのスターター です。この記事ではこのアーティファクト1つに絞って、中身・書き方・Tomcat の差し替え・webflux との違い・Spring Boot 4 での改名までを整理します。Starter という仕組み自体の話は Spring Boot Starterって何? に任せて、ここでは深追いしません。バージョンは Spring Boot 3.x を主軸にして、4.x の差分は注記します。

spring-boot-starter-webとは

spring-boot-starter-web は、サーブレットベースの Spring MVC、組み込み Tomcat、JSON 変換用の Jackson をまとめて持ち込むスターターです。これ1つ入れて @RestController を書けば、起動するだけで http://localhost:8080 が応答します。必要なライブラリと、それを配線する自動構成が一式揃うからです。

よく混同されるのが spring-boot-starter との違いです。こちらは Spring Boot 本体・自動構成・ロギングだけの「土台」で、Web 機能は入っていません。starter-web は starter を内包しているので、両方書く必要はありません。

mvn dependency:treeで中身を展開する

「何が入っているか」は自分の目で確認するのが一番です。Maven なら次のコマンドで推移的依存を展開できます。

mvn dependency:tree
# Gradle の場合
./gradlew dependencies --configuration runtimeClasspath

Spring Boot 3.3 系の出力から、spring-boot-starter-web 配下だけ抜粋するとこうなります。

+- org.springframework.boot:spring-boot-starter-web:jar:3.3.5:compile
|  +- org.springframework.boot:spring-boot-starter:jar:3.3.5:compile
|  |  +- org.springframework.boot:spring-boot:jar:3.3.5:compile
|  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:3.3.5:compile
|  |  \- org.springframework.boot:spring-boot-starter-logging:jar:3.3.5:compile
|  +- org.springframework.boot:spring-boot-starter-json:jar:3.3.5:compile
|  |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.17.2:compile
|  |  +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.17.2:compile
|  |  \- (jdk8 / parameter-names モジュールなど)
|  +- org.springframework.boot:spring-boot-starter-tomcat:jar:3.3.5:compile
|  |  +- org.apache.tomcat.embed:tomcat-embed-core:jar:10.1.31:compile
|  |  \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:10.1.31:compile
|  +- org.springframework:spring-web:jar:6.1.14:compile
|  \- org.springframework:spring-webmvc:jar:6.1.14:compile

直下に並ぶのは5本です。

  • spring-boot-starter は Boot 本体・自動構成・Logback ベースのロギング
  • spring-boot-starter-json は Jackson 一式。LocalDateTime や Optional を扱うモジュールもここに含まれる
  • spring-boot-starter-tomcat は組み込み Tomcat。これがあるから jar 単体で Web サーバーが立ち上がる
  • spring-web は HTTP 周りの共通基盤(RestTemplate や HttpMessageConverter など)
  • spring-webmvc は DispatcherServlet と @RequestMapping を担う Spring MVC 本体

逆に 入っていないもの も押さえておきましょう。Bean Validation(Hibernate Validator)は Spring Boot 2.3 以降 starter-web から外れているので、@Valid を使うには spring-boot-starter-validation を別途追加する必要があります。「starter-web を入れたのに @Valid が無視される」という相談の正体はだいたいこれです。詳しくは @Validが効かない原因と対処 で扱っています。同じく Thymeleaf、Spring Data、Spring Security も入らないので、使うならそれぞれのスターターを足します。

ライブラリの重複やバージョン衝突を疑ったときも、まずは dependency:tree を見る癖をつけておくと切り分けが早くなります。

Maven / Gradleでの追加方法

座標はコピペで大丈夫です。ポイントはバージョンを書かないことです。

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
// build.gradle(Groovy DSL)
implementation 'org.springframework.boot:spring-boot-starter-web'
// build.gradle.kts(Kotlin DSL)
implementation("org.springframework.boot:spring-boot-starter-web")

バージョンを省略できるのは、Maven なら spring-boot-starter-parent、Gradle なら io.spring.dependency-management プラグイン(内部で spring-boot-dependencies BOM を読み込む)が、Boot のバージョンに合わせた値を管理してくれているからです。parent を使わない構成では、dependencyManagement に spring-boot-dependencies を import スコープで取り込めば同じことができます。

組み込みTomcatをJetty / Undertowに差し替える

Tomcat 以外のサーバーを使いたい場合は、starter-web から spring-boot-starter-tomcat を除外して、代わりのスターターを足すだけです。

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <exclusions>
    <exclusion>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-tomcat</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
implementation('org.springframework.boot:spring-boot-starter-web') {
    exclude group: 'org.springframework.boot', module: 'spring-boot-starter-tomcat'
}
implementation 'org.springframework.boot:spring-boot-starter-jetty'

Gradle では configurations.implementation { exclude module: 'spring-boot-starter-tomcat' } と書いて、プロジェクト全体から一括除外する手もあります。

バージョンの注意点が1つあります。Spring Boot 3.0 と 3.1 は Jetty 11(Servlet 5.0)系だったため、jakarta.servlet-api のバージョンを下げるプロパティ調整が必要でした。3.2 以降は Jetty 12 に対応しているので、そのまま差し替えるだけで動きます。Undertow は 3.x では使えますが、Spring Boot 4.0 ではサポートが削除されています。これから 4 系へ上げる予定があるなら Jetty を選んでおくのが無難です。

差し替えても server.port などの共通プロパティはそのまま使えます。一方で server.tomcat.* は効かなくなるので、Tomcat のまま性能を調整したい場合は 組み込みTomcatのスレッド数チューニング を参考にしてください。

spring-boot-starter-webfluxとの違い

Initializr には「Spring Web」と「Spring Reactive Web」が並んでいて、後者が spring-boot-starter-webflux です。

観点starter-webstarter-webflux
プログラミングモデルサーブレット・ブロッキングリアクティブ・ノンブロッキング
デフォルトサーバーTomcatReactor Netty
コントローラの書き方@RestController で値をそのまま返す同じアノテーションで Mono / Flux を返す
相性のよい周辺JDBC / JPA / MyBatisR2DBC / WebClient

普通の Web アプリや REST API、既存の JDBC・JPA 資産があるなら starter-web で問題ありません。大量の同時接続を少ないスレッドで捌きたい、ストリーミングが主目的、といった要件が出てきたら webflux を検討する、くらいの温度感です。リアクティブの考え方そのものは Spring WebFluxで始めるリアクティブプログラミング にまとめています。

両方入れたらどうなる?

WebClient だけ使いたくて webflux を足した、というケースで両方同居することがあります。このとき Spring Boot は Spring MVC を優先 し、サーブレットアプリとして Tomcat で起動します。明示したいときは application.properties で起動種別を指定できます。

# servlet / reactive / none のいずれか
spring.main.web-application-type=servlet

Spring Boot 4でspring-boot-starter-webmvcに改名された

最近「spring-boot-starter-webmvc」というスターター名を見かけて戸惑った人もいるでしょう。Spring Boot 4.0 でモジュールが技術ごとに再編され(spring-boot-webmvc など)、スターター名もそれに合わせて spring-boot-starter-webmvc に改名されました。

 <dependency>
   <groupId>org.springframework.boot</groupId>
-  <artifactId>spring-boot-starter-web</artifactId>
+  <artifactId>spring-boot-starter-webmvc</artifactId>
 </dependency>

4.0 時点では旧名の spring-boot-starter-web も非推奨(deprecated)として残っていて、すぐに壊れるわけではありません。ただし将来のリリースで削除される予定なので、4 系へ上げるタイミングで書き換えてしまうのが確実です。あわせて他のスターターにも改名があるので、公式の移行ガイドで一覧を確認しておきましょう。

逆に Spring Boot 3.x を使っているなら読み替えは不要 です。3.x で spring-boot-starter-webmvc と書いても該当するアーティファクトが存在しないので、後述の Could not find artifact になります。「web と webmvc どちらを書くべきか」の答えは、使っている Boot のメジャーバージョンで決まる、これだけです。

動作確認用の最小@RestController

スターターがちゃんと効いているかは、1ファイルで確認できます。

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @RestController
    static class HelloController {

        @GetMapping("/hello")
        Map<String, String> hello() {
            return Map.of("message", "Hello, Spring Boot!");
        }
    }
}

起動して次のログが出れば、starter-web と starter-tomcat は機能しています。

$ ./mvnw spring-boot:run
...  Tomcat started on port 8080 (http) with context path '/'

$ curl http://localhost:8080/hello
{"message":"Hello, Spring Boot!"}

Map を返しただけで JSON になるのは、spring-boot-starter-json(Jackson)が効いている証拠でもあります。ここから Controller・Service・Repository の3層に分けて CRUD を作る手順は REST APIのCRUDを実装する に続きます。

導入直後につまずきやすい2つの症状

Whitelabel Error Pageしか出ない

ブラウザで開いたら真っ白なページに「Whitelabel Error Page」と 404 が出る、というやつです。Tomcat は起動しているので依存関係は正しく、問題はマッピングか配置にあります。確認する順番はこうです。

  1. そのパスに対応する @GetMapping が本当に存在するか
  2. Controller が @SpringBootApplication クラスと同じパッケージか、その配下にあるか。スキャン範囲外に置いてしまうのが定番の原因で、仕組みは @SpringBootApplicationとは で解説しています
  3. @Controller と @RestController を取り違えていないか。前者だと戻り値がテンプレート名として解釈されます

Could not find artifact

Could not find artifact org.springframework.boot:spring-boot-starter-web:jar:unknown のようなエラーでビルドが止まる場合は、次の3点を見ます。

  1. artifactId の typo。3.x なのに spring-boot-starter-webmvc と書いている、ハイフンが抜けている、など
  2. parent も BOM も無いのにバージョンを省略している。version:unknown や version is missing と出ていたらこれです
  3. 社内プロキシやオフライン環境で Maven Central に届いていない。~/.m2/settings.xml の proxy 設定を確認し、mvn -U で再取得します

なお、起動自体が「APPLICATION FAILED TO START」で落ちる場合は依存ではなく構成側の問題がほとんどです。そちらは Spring Bootアプリが起動しない時の原因切り分け を参照してください。

まとめ

spring-boot-starter-web は、Spring MVC・組み込み Tomcat・Jackson を1行で持ち込むスターターです。中身は dependency:tree で確認でき、Bean Validation は含まれないので必要なら starter-validation を足します。座標はバージョン無しで書けばよく、Tomcat の差し替えは exclusion と代替スターターの2ステップです。webflux と同居させたときは MVC が優先され、Spring Boot 4 からは spring-boot-starter-webmvc という名前になりました。

「なぜバージョンを書かなくていいのか」「他にどんなスターターがあるのか」が気になったら、Spring Boot Starterって何? で全体像を押さえておくと、この記事の内容がさらに腑に落ちるはずです。