51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

SpringBoot3.3 中如何实现多端口监听

SpringBoot3.3 中如何实现多端口监听

在 SpringBoot 应用中,通常情况下,我们只需要监听一个端口来处理 HTTP 请求。但在某些情况下,我们可能需要在同一个应用中监听多个端口,例如分别处理不同类型的请求,或者在同一个应用中暴露多个服务接口。本篇文章将详细讲解如何在 SpringBoot 中实现多端口监听,并结合代码示例进行深入讲解。

运行效果:

若想获取项目完整代码以及其他文章的项目源码,且在代码编写时遇到问题需要咨询交流,欢迎加入下方的知识星球。

项目环境与依赖配置

首先,我们需要创建一个 SpringBoot 项目,并确保项目中包含必要的依赖。以下是 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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.3.3</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.icoderoad</groupId>
	<artifactId>multi-port-demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>multi-port-demo</name>
	<description>Demo project for Spring Boot</description>
&lt;properties&gt;
	&lt;java.version&gt;17&lt;/java.version&gt;
&lt;/properties&gt;
&lt;dependencies&gt;
	
	&lt;!-- Spring Boot Web Starter --&gt;

        <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-web</artifactId>         </dependency>                  <!-- Thymeleaf 依赖 -->         <dependency>             <groupId>org.springframework.boot</groupId>             <artifactId>spring-boot-starter-thymeleaf</artifactId>         </dependency>

	&lt;dependency&gt;
		&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
		&lt;artifactId&gt;spring-boot-starter-test&lt;/artifactId&gt;
		&lt;scope&gt;test&lt;/scope&gt;
	&lt;/dependency&gt;
&lt;/dependencies&gt;

&lt;build&gt;
	&lt;plugins&gt;
		&lt;plugin&gt;
			&lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;
			&lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;
		&lt;/plugin&gt;
	&lt;/plugins&gt;
&lt;/build&gt;

</project>

配置多端口监听

在 SpringBoot 中,通过配置 application.yml 文件可以轻松实现多端口监听。以下是配置示例:

server:
  port: 8080 # 主端口

# 额外的端口配置 additional-ports:   - 8081   - 8082

编写配置类实现多端口监听

在配置文件中指定了额外的端口后,我们需要编写一个配置类,使用 Spring 的 EmbeddedWebServerFactoryCustomizer 来实现多端口监听。我们在 MultiPortConfig 类中为每个端口配置一个独立的 Spring 上下文。

package com.icoderoad.multi_port_demo.config;

import org.apache.catalina.connector.Connector; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.servlet.server.ServletWebServerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;

@Configuration public class MultiPortConfig {

    @Bean     public ServletWebServerFactory servletWebServerFactory() {         TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();         factory.addAdditionalTomcatConnectors(createConnector(8081)); // Add additional port 8081         factory.addAdditionalTomcatConnectors(createConnector(8082)); // Add additional port 8082         return factory;     }

    private Connector createConnector(int port) {         Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);         connector.setPort(port);         return connector;     } }

在这个配置类中,createAndStartContext 方法为 8081 和 8082 端口创建了独立的 Spring 上下文,每个上下文对应一个配置类(Port8081Config 和 Port8082Config),这些配置类会定义对应端口下的控制器。

为每个端口创建独立的配置类

现在,我们为每个端口创建独立的配置类,这些配置类将会注册相应的控制器。

8081 端口配置类

package com.icoderoad.multi_port_demo.config;

import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import com.icoderoad.multi_port_demo.controller.Port8081Controller;

@Configuration @EnableWebMvc public class Port8081Config {

    @Bean     public Port8081Controller port8081Controller() {         return new Port8081Controller();     } }

8082 端口配置类

package com.icoderoad.multi_port_demo.config;

import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import com.icoderoad.multi_port_demo.controller.Port8082Controller;

@Configuration @EnableWebMvc public class Port8082Config {

    @Bean     public Port8082Controller port8082Controller() {         return new Port8082Controller();     } }

这些配置类会在相应的端口上下文中注册对应的控制器。

控制器类定义

定义控制器类,每个控制器类对应一个端口,之前的控制器定义无需改变:

8080 端口的控制器(保持原有配置)

package com.icoderoad.multi_port_demo.controller;

import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;

@RestController public class Port8080Controller {

    @GetMapping("/port8080/service")     public ResponseEntity<String>  service() {           HttpHeaders headers = new HttpHeaders();         headers.setContentType(org.springframework.http.MediaType.TEXT_PLAIN);         headers.set(HttpHeaders.CONTENT_TYPE, "text/plain; charset=UTF-8");                  return new ResponseEntity<>("端口 8080 的服务数据", headers, HttpStatus.OK);              } }

8081 端口的控制器

package com.icoderoad.multi_port_demo.controller;

import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;

@RestController public class Port8081Controller {

@CrossOrigin(origins = &quot;http://localhost:8080&quot;) // 允许的前端地址

    @GetMapping("/port8081/service") public ResponseEntity<String>  service() {           HttpHeaders headers = new HttpHeaders();         headers.setContentType(org.springframework.http.MediaType.TEXT_PLAIN);         headers.set(HttpHeaders.CONTENT_TYPE, "text/plain; charset=UTF-8");                  return new ResponseEntity<>("端口 8081 的服务数据", headers, HttpStatus.OK);              } }

8082 端口的控制器

package com.icoderoad.multi_port_demo.controller;

import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController;

@RestController public class Port8082Controller {

@CrossOrigin(origins = &quot;http://localhost:8080&quot;) // 允许的前端地址

    @GetMapping("/port8082/service") public ResponseEntity<String>  service() {           HttpHeaders headers = new HttpHeaders();         headers.setContentType(org.springframework.http.MediaType.TEXT_PLAIN);         headers.set(HttpHeaders.CONTENT_TYPE, "text/plain; charset=UTF-8");                  return new ResponseEntity<>("端口 8082 的服务数据", headers, HttpStatus.OK);              } }

编写前端页面

在 src/main/resources/templates 目录下创建一个简单的 index.html 页面,使用 Thymeleaf 和 Bootstrap 进行前端展示。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>SpringBoot 多端口监听</title>
   <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
    <h1 class="mt-5">SpringBoot 多端口监听示例</h1>
    <p class="lead">此应用监听多个端口,分别处理不同的请求。</p>
    <p>主端口:8080</p>
    <p>额外端口:8081, 8082</p>
    
    <div class="row">
        <div class="col-md-4">
            <h3>端口 8080 数据</h3>
            <p id="data-8080">加载中...</p>
        </div>
        <div class="col-md-4">
            <h3>端口 8081 数据</h3>
            <p id="data-8081">加载中...</p>
        </div>
        <div class="col-md-4">
            <h3>端口 8082 数据</h3>
            <p id="data-8082">加载中...</p>
        </div>
    </div>
</div>

<script>     fetch('http://localhost:8080/port8080/service')         .then(response => response.text())         .then(data => {             document.getElementById('data-8080').textContent = data;         });

    fetch('http://localhost:8081/port8081/service')         .then(response => response.text())         .then(data => {             document.getElementById('data-8081').textContent = data;         });

    fetch('http://localhost:8082/port8082/service')         .then(response => response.text())         .then(data => {             document.getElementById('data-8082').textContent = data;         }); </script> </body> </html>

视图控制器实现

在 src/main/java/com/icoderoad/controller 目录下创建一个简单的控制器,用于处理 HTTP 请求。

package com.icoderoad.multi_port_demo.controller;

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

@Controller public class IndexController {

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

上述代码中,我们创建了一个简单的控制器类,提供了一个主页和一个返回监听端口信息的接口。

启动与验证

启动 SpringBoot 应用后,在浏览器中访问 http://localhost:8080、http://localhost:8081 和 http://localhost:8082,你会发现所有端口都可以正常响应请求,说明我们已经成功实现了多端口监听。

总结

通过本文的详细讲解,我们学习了如何在 SpringBoot 中实现多端口监听。这一功能在处理不同类型的请求或暴露多个服务接口时非常有用。我们通过配置 application.yml 文件和编写自定义配置类,结合前端展示,实现了这一功能。希望这篇文章能对大家有所帮助。


赞(7)
未经允许不得转载:工具盒子 » SpringBoot3.3 中如何实现多端口监听