Trước đó chúng ta đã tìm hiểu về spring core webmvc, với các cấu hình tương đối phức tạp, tuy nhiên với spring boot, nó đã đóng gói cho chúng ta toàn bộ những cấu hình phức tạp đó rồi và chúng ta chỉ cần cài đặt các lớp nghiệp vụ thôi. Trong bài này Dũng sẽ cùng các bạn tìm hiểu về spring-boot-starter-web nhé.
Khởi tạo module
Chúng ta sẽ khởi tạo một module có tên spring-boot-web.
Cấu hình dự án
Chúng ta sẽ cần bổ sung thư viện spring-boot-starter-web vào spring-boot-web/pom.xml như sau:
<?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>vn.techmaster</groupId>
<artifactId>mastering-spring-boot</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>spring-boot-web</artifactId>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.3.1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
Thay vì phải bổ sung vài thư viện phụ thuộc thì bây giờ chúng ta chỉ cần duy nhất một thư viện có tên là spring-boot-starter-web mà thôi. Thực chất thì bên trong nó đã bổ sung các thư viện cần thiết cho chúng ta như dưới đây cũng tương tự như chúng ta đã làm với spring core webmvc:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>6.1.10</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>6.1.10</version>
</dependency>
Cài đặt controller
Chúng ta sẽ khởi tạo lớp HelloController để cài đặt một API có tên /api/v1/hello với mã nguồn như sau:
package vn.techmaster.spring_boot_web.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/api/v1/hello")
public String homePage() {
return "Hello Techmaster";
}
}
Ở đây bạn thấy một annotation mới là RestController, đừng quá hoang mang về nó, thực chất thì nó cũng giống với Component annotation để nói với spring rằng hãy tạo ra một đối tượng singleton cho lớp HelloController. Ngoài ra nó cũng nói với spring rằng đây là một lớp controller cài đặt theo kiểu REST, nếu bạn chưa biết REST là gì thì nó là một kiểu kiến trúc phần mềm hay nói đơn giản hơn thì nó khuyến khích việc trả về dữ text, json thay vì trả về dữ liệu html như thông thường để phù hợp với nhiều loại phần mềm hơn là chỉ phục vụ cho mỗi website. Bạn có thể tìm hiểu thêm về REST tại đây.
Khởi chạy dự án
Để khởi chạy dự án chúng ta sẽ cần tạo một lớp SpringBootWebStartUp có mã nguồn như sau:
package vn.techmaster.spring_boot_web;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootWebStartUp {
public static void main(String[] args) {
SpringApplication.run(SpringBootWebStartUp.class);
}
}
Chạy chương trình chúng ta sẽ thấy log in ra:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.3.1)
2024-06-28T11:36:15.541+07:00 INFO 2144 --- [ main] v.t.s.SpringBootWebStartUp : Starting SpringBootWebStartUp using Java 17.0.7 with PID 2144 (/Users/tvd12/Documents/techmaster/mastering-spring-boot/spring-boot-web/target/classes started by tvd12 in /Users/tvd12/Documents/techmaster/mastering-spring-boot)
2024-06-28T11:36:15.545+07:00 INFO 2144 --- [ main] v.t.s.SpringBootWebStartUp : No active profile set, falling back to 1 default profile: "default"
2024-06-28T11:36:16.821+07:00 INFO 2144 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
2024-06-28T11:36:16.842+07:00 INFO 2144 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2024-06-28T11:36:16.842+07:00 INFO 2144 --- [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.25]
2024-06-28T11:36:16.926+07:00 INFO 2144 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2024-06-28T11:36:16.927+07:00 INFO 2144 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1305 ms
2024-06-28T11:36:17.427+07:00 INFO 2144 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/'
2024-06-28T11:36:17.436+07:00 INFO 2144 --- [ main] v.t.s.SpringBootWebStartUp : Started SpringBootWebStartUp in 2.403 seconds (process running for 4.433)
Bây giờ chúng ta đã có một máy chủ tomcat http chạy trên cổng 8080, truy cập vào địa chỉ http://localhost:8080/api/v1/hello chúng ta sẽ nhận được kết quả như sau:
Sử dụng jetty thay vì tomcat
Mặc định thì spring boot started web sử dụng tomcat, tuy nhiên nếu bạn là một fan hâm mộ của jetty thì bạn cũng có thể chuyển qua sử dụng jetty thay vì tomcat khi thay đổi các phụ thuộc như sau:
<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>
</dependencies>
Khi bạn khởi chạy chương trình bạn sẽ thấy log hiện ra jetty thay vì tomcat như sau:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.3.1)
2024-06-28T13:26:57.122+07:00 INFO 2533 --- [ main] v.t.s.SpringBootWebStartUp : Starting SpringBootWebStartUp using Java 17.0.7 with PID 2533 (/Users/tvd12/Documents/techmaster/mastering-spring-boot/spring-boot-web/target/classes started by tvd12 in /Users/tvd12/Documents/techmaster/mastering-spring-boot)
2024-06-28T13:26:57.126+07:00 INFO 2533 --- [ main] v.t.s.SpringBootWebStartUp : No active profile set, falling back to 1 default profile: "default"
2024-06-28T13:26:58.384+07:00 INFO 2533 --- [ main] o.s.b.w.e.j.JettyServletWebServerFactory : Server initialized with port: 8080
2024-06-28T13:26:58.388+07:00 INFO 2533 --- [ main] org.eclipse.jetty.server.Server : jetty-12.0.10; built: 2024-05-30T04:40:36.563Z; git: 26106dfc84a03ddb6216062fe33b047fc332d0ce; jvm 17.0.7+8-LTS-224
2024-06-28T13:26:58.430+07:00 INFO 2533 --- [ main] o.e.j.s.h.ContextHandler.application : Initializing Spring embedded WebApplicationContext
2024-06-28T13:26:58.431+07:00 INFO 2533 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1230 ms
2024-06-28T13:26:58.508+07:00 INFO 2533 --- [ main] o.e.j.session.DefaultSessionIdManager : Session workerName=node0
2024-06-28T13:26:58.517+07:00 INFO 2533 --- [ main] o.e.jetty.server.handler.ContextHandler : Started osbwej.JettyEmbeddedWebAppContext@6a9b9909{application,/,b=file:/private/var/folders/l_/dx284gzj3yq2x6fq1zqq4h5h0000gn/T/jetty-docbase.8080.10949147279551123629/,a=AVAILABLE,h=oeje10s.SessionHandler@55d9b8f0{STARTED}}
2024-06-28T13:26:58.518+07:00 INFO 2533 --- [ main] o.e.j.e.servlet.ServletContextHandler : Started osbwej.JettyEmbeddedWebAppContext@6a9b9909{application,/,b=file:/private/var/folders/l_/dx284gzj3yq2x6fq1zqq4h5h0000gn/T/jetty-docbase.8080.10949147279551123629/,a=AVAILABLE,h=oeje10s.SessionHandler@55d9b8f0{STARTED}}
2024-06-28T13:26:58.522+07:00 INFO 2533 --- [ main] org.eclipse.jetty.server.Server : Started oejs.Server@3f1ddac2{STARTING}[12.0.10,sto=0] @2336ms
2024-06-28T13:26:58.935+07:00 INFO 2533 --- [ main] o.e.j.s.h.ContextHandler.application : Initializing Spring DispatcherServlet 'dispatcherServlet'
2024-06-28T13:26:58.936+07:00 INFO 2533 --- [ main] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2024-06-28T13:26:58.937+07:00 INFO 2533 --- [ main] o.s.web.servlet.DispatcherServlet : Completed initialization in 0 ms
2024-06-28T13:26:58.955+07:00 INFO 2533 --- [ main] o.e.jetty.server.AbstractConnector : Started ServerConnector@4d499d65{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
2024-06-28T13:26:58.957+07:00 INFO 2533 --- [ main] o.s.b.web.embedded.jetty.JettyWebServer : Jetty started on port 8080 (http/1.1) with context path '/'
2024-06-28T13:26:58.967+07:00 INFO 2533 --- [ main] v.t.s.SpringBootWebStartUp : Started SpringBootWebStartUp in 2.297 seconds (process running for 2.783)
Tổng kết
Như vậy chúng ta đã cùng nhau:
- Khởi chạy một web server với spring boot và tomcat.
- Khởi chạy một web server với spring boot và jetty.
Cám ơn bạn đã quan tâm đến bài viết|video này. Để nhận được thêm các kiến thức bổ ích bạn có thể:
- Đọc các bài viết của TechMaster trên facebook: https://www.facebook.com/techmastervn
- Xem các video của TechMaster qua Youtube: https://www.youtube.com/@TechMasterVietnam nếu bạn thấy video/bài viết hay bạn có thể theo dõi kênh của TechMaster để nhận được thông báo về các video mới nhất nhé.
- Chat với techmaster qua Discord: https://discord.gg/yQjRTFXb7a
Bình luận
good