SpringBoot2.x入門:引入web模組

throwable發表於2020-07-04

前提

這篇文章是《SpringBoot2.x入門》專輯的第3篇文章,使用的SpringBoot版本為2.3.1.RELEASEJDK版本為1.8

主要介紹SpringBootweb模組引入,會相對詳細地分析不同的Servlet容器(如TomcatJetty等)的切換,以及該模組提供的SpringMVC相關功能的使用。

依賴引入

筆者新建了一個多模組的Maven專案,這次的示例是子模組ch1-web-module

SpringBootweb模組實際上就是spring-boot-starter-web元件(下稱web模組),前面的文章介紹過使用BOM全域性管理版本,可以在(父)POM檔案中新增dependencyManagement元素:

<properties>
    <spring.boot.version>2.3.1.RELEASE</spring.boot.version>
</properties>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring.boot.version}</version>
            <scope>import</scope>
            <type>pom</type>
        </dependency>
    </dependencies>
</dependencyManagement>

接來下在(子)POM檔案中的dependencies元素引入spring-boot-starter-web的依賴:

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

專案的子POM大致如下:

<?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>
    <parent>
        <groupId>club.throwable</groupId>
        <artifactId>spring-boot-guide</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <artifactId>ch1-web-module</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>ch1-web-module</name>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    <build>
        <finalName>ch1-web-module</finalName>
        <!-- 引入spring-boot-maven-plugin以便專案打包 -->
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${spring.boot.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

spring-boot-starter-web模組中預設使用的Servlet容器是嵌入式(EmbeddedTomcat,配合打包成一個Jar包以便可以直接使用java -jar xxx.jar命令啟動。

SpringMVC的常用註解

web模組整合和擴充套件了SpringMVC的功能,移除但相容相對臃腫的XML配置,這裡簡單列舉幾個常用的Spring或者SpringMVC提供的註解,簡單描述各個註解的功能:

元件註解:

  • @Component:標記一個類為Spring元件,掃描階段註冊到IOC容器。
  • @Repository:標記一個類為Repository(倉庫)元件,它的元註解為@Component,一般用於DAO層。
  • @Service:標記一個類為Service(服務)元件,它的元註解為@Component
  • @Controller:標記一個類為Controller(控制器)元件,它的元註解為@Component,一般控制器是訪問的入口,衍生註解@RestController,簡單理解為@Controller標記的控制器內所有方法都加上下面提到的@ResponseBody

引數註解:

  • @RequestMapping:設定對映引數,包括請求方法、請求的路徑、接收或者響應的內容型別等等,衍生註解為GetMappingPostMappingPutMappingDeleteMappingPatchMapping
  • @RequestParam:宣告一個方法引數繫結到一個請求引數。
  • @RequestBody:宣告一個方法引數繫結到請求體,常用於內容型別為application/json的請求體接收。
  • @ResponseBody:宣告一個方法返回值繫結到響應體。
  • @PathVariable:宣告一個方法引數繫結到一個URI模板變數,用於提取當前請求URI中的部分到方法引數中。

編寫控制器和啟動類

在專案中編寫一個控制器club.throwable.ch1.controller.HelloController如下:

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Optional;

@Slf4j
@Controller
@RequestMapping(path = "/ch1")
public class HelloController {
    
    @RequestMapping(path = "/hello")
    public ResponseEntity<String> hello(@RequestParam(name = "name") String name) {
        String value = String.format("[%s] say hello", name);
        log.info("呼叫[/hello]介面,引數:{},響應結果:{}", name, value);
        return ResponseEntity.of(Optional.of(value));
    }
}

HelloController只提供了一個接收GET請求且請求的路徑為/ch1/hello的方法,它接收一個名稱為name的引數(引數必傳),然後返回簡單的文字:${name} say hello。可以使用衍生註解簡化如下:

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Optional;

@Slf4j
@RestController
@RequestMapping(path = "/ch1")
public class HelloController {

    @GetMapping(path = "/hello")
    public ResponseEntity<String> hello(@RequestParam(name = "name") String name) {
        String value = String.format("[%s] say hello", name);
        log.info("呼叫[/hello]介面,引數:{},響應結果:{}", name, value);
        return ResponseEntity.of(Optional.of(value));
    }
}

接著編寫一個啟動類club.throwable.ch1.Ch1Application,啟動類是SpringBoot應用程式的入口,需要提供一個main方法:

package club.throwable.ch1;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Ch1Application {

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

然後以DEBUG模式啟動一下:

Tomcat預設的啟動埠是8080,啟動完畢後見日誌如下:

用用瀏覽器訪問http://localhost:8080/ch1/hello?name=thrwoable可見輸出如下:

至此,一個簡單的基於spring-boot-starter-web開發的web應用已經完成。

切換Servlet容器

有些時候由於專案需要、運維規範或者個人喜好,並不一定強制要求使用Tomcat作為Servlet容器,常見的其他選擇有JettyUndertow,甚至Netty等。以JettyUndertow為例,切換為其他嵌入式Servlet容器需要從spring-boot-starter-web中排除Tomcat的依賴,然後引入對應的Servlet容器封裝好的starter

切換為Jetty,修改POM檔案中的dependencies元素:

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

切換為Undertow,修改POM檔案中的dependencies元素:

<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‐undertow</artifactId>
</dependency>

小結

這篇文章主要分析瞭如何基於SpringBoot搭建一個入門的web服務,還簡單介紹了一些常用的SpringMVC註解的功能,最後講解如何基於spring-boot-starter-web切換底層的Servlet容器。學會搭建MVC應用後,就可以著手嘗試不同的請求方法或者引數,嘗試常用註解的功能。

程式碼倉庫

這裡給出本文搭建的web模組的SpringBoot應用的倉庫地址(持續更新):

(本文完 c-2-d e-a-20200703 23:09 PM)

技術公眾號《Throwable文摘》(id:throwable-doge),不定期推送筆者原創技術文章(絕不抄襲或者轉載):

相關文章