使用HTTPS和OAuth 2.0保护服务到服务的Spring微服务

“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证。

如果您使用Spring Boot,Spring Cloud和Spring Cloud Config,则只需最少的代码即可构建微服务架构。 将所有内容打包到Docker容器中,即可使用Docker Compose运行所有内容。 如果您在服务之间进行通信,则可以通过不在docker-compose.yml文件中公开其端口来确保服务的安全性。

但是,如果有人不小心暴露了微服务应用程序的端口会怎样? 他们仍然安全还是任何人都可以访问他们的数据?

在本文中,我将向您展示如何使用HTTPS和OAuth 2.0保护服务到服务的通信。

使用Spring Boot,Spring Cloud和Spring Cloud Config开发微服务堆栈

我将简化使用Spring Boot,Spring Cloud和Spring Cloud Config构建完整的微服务堆栈的过程。 我的好友拉斐尔(Raphael)写了一篇文章,介绍如何构建Spring微服务并将其Docker化用于生产 。 您可以使用他的示例应用程序作为起点。 克隆okta-spring-microservices-docker-example项目:

git clone https://github.com/oktadeveloper/okta-spring-microservices-docker-example.git spring-microservices-security
cd spring-microservices-security

此项目在Okta上需要两个OpenID Connect应用程序,一个用于开发,一个用于生产。 如果没有完成上述教程,则需要在Okta上创建每个应用程序。

在Okta上创建OpenID Connect应用程序

您可以注册一个免费的开发人员帐户 ,该帐户最多可以有0个月活跃用户,费用为$ 0。 对于这个例子来说应该足够了。

为什么选择Okta? 因为编写身份验证很无聊。 Okta具有身份验证和用户管理API,可让您更快地开发应用。 我们的API和SDK使您可以在几分钟内轻松地进行身份验证,管理和保护用户安全。

创建帐户后,在Okta的信息中心(“ 应用程序” >“ 添加应用程序” )中创建一个新的Web应用程序 。 给应用程序起一个您将记住的名称,复制现有的登录重定向URI,并使其使用HTTPS。 单击完成

结果应类似于下面的屏幕截图。

安全服务

创建另一个用于生产的应用程序。 我给我的Prod Microservices

在您克隆的项目中,修改config/school-ui.properties以使用开发应用程序中的设置。

okta.oauth2.issuer=https://{yourOktaDomain}/oauth2/default
okta.oauth2.clientId={devClientId}
okta.oauth2.clientSecret={devClientId}

当使用Maven单独运行应用程序时,将使用这些设置。 在Docker Compose上运行时使用生产设置。 修改config-data/school-ui-production.properties以使用生产应用程序中的设置。

okta.oauth2.clientId={prodClientId}
okta.oauth2.clientSecret={prodClientId}

您可以在spring.profiles.active docker-compose.yml看到spring.profiles.active打开生产配置文件:

school-ui:image: developer.okta.com/microservice-docker-school-ui:0.0.1-SNAPSHOTenvironment:- JAVA_OPTS=-DEUREKA_SERVER=http://discovery:8761/eureka-Dspring.profiles.active=productionrestart: on-failuredepends_on:- discovery- configports:- 8080:8080

Docker Compose从应用程序上方的目录中运行,并从config-data目录读取其数据。 因此,您需要将这些属性文件复制到此目录中。 从该项目的根目录运行以下命令。

cp config/*.properties config-data/.

使用Docker Compose启动Spring微服务堆栈

该项目在其根目录中有一个聚合器pom.xml ,使您可以使用一个命令来构建所有项目。 运行以下Maven命令为每个项目构建,测试和构建Docker映像。

mvn clean install

如果您尚未安装Maven,则可以使用SDKMAN进行安装! sdk install maven

该过程完成后,使用Docker Compose启动所有应用程序{config,discovery,school-service和school-ui}。 如果尚未安装,请参阅安装Docker Compose 。

docker-compose up -d

您可以使用Kitematic查看每个应用程序启动时的日志。

在您喜欢的浏览器中导航到http://localhost:8080 。 完成后,您应该可以登录并查看学校课程列表。

安全服务

Spring Security和OAuth 2.0

此示例使用Okta的Spring Boot Starter ,它是Spring Security之上的薄层。 Okta入门程序简化了配置,并在访问令牌中进行了观众验证。 它还允许您指定将用于创建Spring Security授权的声明。

docker-compose.yml文件不会将school-service公开给外界。 它通过不指定ports

school-ui项目有一个SchoolController类,该类使用Spring的RestTemplateschool-service进行RestTemplate

@GetMapping("/classes")
@PreAuthorize("hasAuthority('SCOPE_profile')")
public ResponseEntity<List<TeachingClassDto>> listClasses() {return restTemplate.exchange("http://school-service/class", HttpMethod.GET, null,new ParameterizedTypeReference<List<TeachingClassDto>>() {});
}

您会注意到此类的端点上存在安全性,但是服务之间不存在安全性。 我将在下面的步骤中向您展示如何解决该问题。

首先,公开school-service的端口,以模拟有人用粗俗的方式进行配置。 在docker-compose.yml更改school-service配置以公开其端口。

school-service:image: developer.okta.com/microservice-docker-school-service:0.0.1-SNAPSHOTenvironment:- JAVA_OPTS=-DEUREKA_SERVER=http://discovery:8761/eurekadepends_on:- discovery- configports:- 8081:8081

使用Docker Compose重新启动一切:

docker-compose down
docker-compose up -d

您会看到不需要身份验证即可查看http://localhost:8081 。 kes! 😱

在继续下一部分之前, 请确保关闭所有Docker容器。

docker-compose down

HTTPS无处不在!

HTTPS代表“安全” HTTP。 HTTPS连接经过加密,其内容比HTTP连接难读得多。 近年来,即使在开发过程中,在所有地方都使用HTTPS的趋势已经发生了很大的变化。 使用HTTPS时可能会遇到一些问题,因此尽早发现它们是很好的。

让我们加密是一个提供免费HTTPS证书的证书颁发机构。 它还具有用于自动续订的API。 简而言之,它使HTTPS变得如此简单,没有理由不使用它! 有关如何将certbot与“让我们加密”一起使用以生成证书的说明,请参阅将社交登录名添加到您的JHipster应用程序 。

我也鼓励您签出Spring Boot Starter ACME 。 这是一个Spring Boot模块,它使用Let's Encrypt和自动证书管理环境(ACME)协议简化了生成证书的过程。

使用mkcert简化本地TLS

我最近发现了一个名为mkcert的工具,该工具可以创建localhost证书。 您可以在macOS上使用Homebrew安装它

brew install mkcert
brew install nss # Needed for Firefox

如果您使用的是Linux,则需要先安装certutil

sudo apt install libnss3-tools

然后使用Linuxbrew运行brew install mkcert命令。 Windows用户可以使用Chocolately或Scoop 。

执行以下mkcert命令以为localhost127.0.0.1 ,您的计算机名称和discovery主机(如docker-compose.yml所引用)生成证书。

mkcert -install
mkcert localhost 127.0.0.1 ::1 `hostname` discovery

如果这样生成的文件中带有数字,请重命名文件,使其没有数字。

mv localhost+2.pem localhost.pem
mv localhost+2-key.pem localhost-key.pem

使用Spring Boot的HTTPS

Spring Boot不支持带有PEM扩展名的证书,但是您可以将其转换为Spring Boot支持的PKCS12扩展名。 您可以使用OpenSSL将证书和私钥转换为PKCS12。 这对于“加密我们生成的证书”也是必要的。

运行openssl转换证书:

openssl pkcs12 -export -in localhost.pem -inkey \
localhost-key.pem -out keystore.p12 -name bootifulsecurity

在出现提示时指定密码。

在项目的根目录中创建一个https.env文件,并指定以下属性以启用HTTPS。

export SERVER_SSL_ENABLED=true
export SERVER_SSL_KEY_STORE=../keystore.p12
export SERVER_SSL_KEY_STORE_PASSWORD={yourPassword}
export SERVER_SSL_KEY_ALIAS=bootifulsecurity
export SERVER_SSL_KEY_STORE_TYPE=PKCS12

更新.gitignore文件以排除.env文件,以便密钥库密码不会最终出现在源代码管理中。

*.env

运行source https.env来设置这些环境变量。 或者,甚至更好的方法是,将其添加到.bashrc.zshrc文件中,以便为每个新Shell设置这些变量。 是的,您也可以将它们包含在每个应用程序的application.properties ,但随后会将机密存储在源代码管理中。 如果您没有将此示例检入源代码管理,则可以复制/粘贴以下设置。

server.ssl.enabled=true
server.ssl.key-store=../keystore.p12
server.ssl.key-store-password: {yourPassword}
server.ssl.key-store-type: PKCS12
server.ssl.key-alias: bootifulsecurity

启动discovery应用程序:

cd discovery
source ../https.env
mvn spring-boot:run

然后确认您可以通过https://localhost:8761访问它。

安全服务

打开docker-compose.yml并将http所有实例更改为https 。 编辑school-ui/src/main/java/…​/ui/controller/SchoolController.java以将对school-service的调用更改为使用HTTPS。

return restTemplate.exchange("https://school-service/class", HttpMethod.GET, null,new ParameterizedTypeReference<List<TeachingClassDto>>() {});

更新{config,school-service,school-ui}/src/main/resources/application.properties以添加使每个实例注册为安全应用程序的属性。

eureka.instance.secure-port-enabled=true
eureka.instance.secure-port=${server.port}
eureka.instance.status-page-url=https://${eureka.hostname}:${server.port}/actuator/info
eureka.instance.health-check-url=https://${eureka.hostname}:${server.port}/actuator/health
eureka.instance.home-page-url=https://${eureka.hostname}${server.port}/

另外,将每个application.properties (和bootstrap.yml )的Eureka地址更改为https://localhost:8761/eureka

school-ui项目中的application.properties没有指定端口。 您需要添加server.port=8080

此时,您应该能够通过在每个项目中(在单独的终端窗口中)运行以下命令来启动所有应用程序。

source ../https.env
./mvnw spring-boot:start

https://localhost:8080确认所有工作正常。 然后使用killall java杀死所有内容。

结合使用HTTPS和Docker Compose

Docker不读取环境变量,也不了解您的本地CA(证书颁发机构),并且您不能将父目录中的文件添加到映像中。

要解决此问题,您需要将keystore.p12localhost.pem复制到每个项目的目录中。 第一个将用于Spring Boot,第二个将被添加到每个映像上的Java Keystore中。

cp localhost.pem keystore.p12 config/.
cp localhost.pem keystore.p12 discovery/.
cp localhost.pem keystore.p12 school-service/.
cp localhost.pem keystore.p12 school-ui/.

然后修改每个项目的Dockerfile以复制证书并将其添加到其信任存储中。

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ADD target/*.jar app.jar
ADD keystore.p12 keystore.p12
USER root
COPY localhost.pem $JAVA_HOME/jre/lib/security
RUN \cd $JAVA_HOME/jre/lib/security \&& keytool -keystore cacerts -storepass changeit -noprompt \-trustcacerts -importcert -alias bootifulsecurity -file localhost.pem
ENV JAVA_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar" ]

然后使用Spring Boot和HTTPS的环境变量创建一个.env文件。

SERVER_SSL_ENABLED=true
SERVER_SSL_KEY_STORE=keystore.p12
SERVER_SSL_KEY_STORE_PASSWORD={yourPassword}
SERVER_SSL_KEY_ALIAS=bootifulsecurity
SERVER_SSL_KEY_STORE_TYPE=PKCS12
EUREKA_INSTANCE_HOSTNAME={yourHostname}

您可以通过运行hostname来获取{yourHostname}的值。

Docker Compose具有一个“ env_file”配置选项,允许您读取此文件以获取环境变量。 更新docker-compose.yml以为每个应用程序指定一个env_file

version: '3'
services:discovery:env_file:- .env...config:env_file:- .env...school-service:env_file:- .env...school-ui:env_file:- .env...

您可以通过从根目录运行docker-compose config来确保其正常工作。

运行mvn clean install以启用Eureka注册启用HTTPS来重建所有Docker映像。 然后开始一切。

docker-compose up -d

现在,您的所有应用程序都在带有HTTPS的Docker中运行! 在https://localhost:8080证明。

如果您的应用程序无法启动或无法彼此通信,请确保您的主机名与.env主机名匹配。

您可以进一步提高安全性:使用OAuth 2.0保护您的学校服务API。

OAuth 2.0的API安全性

将Okta Spring Boot Starter和Spring Cloud Config添加到school-service/pom.xml

<dependency><groupId>com.okta.spring</groupId><artifactId>okta-spring-boot-starter</artifactId><version>1.1.0</version>
</dependency>
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId>
</dependency>

然后在school-service/src/main/java/…​/service/configuration创建一个SecurityConfiguration.java类:

package com.okta.developer.docker_microservices.service.configuration;import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated().and().oauth2ResourceServer().jwt();}
}

创建一个school-service/src/test/resources/test.properties文件并添加属性,以便Okta的配置通过,并且在测试时不使用发现或配置服务器。

okta.oauth2.issuer=https://{yourOktaDomain}/oauth2/default
okta.oauth2.clientId=TEST
spring.cloud.discovery.enabled=false
spring.cloud.config.discovery.enabled=false
spring.cloud.config.enabled=false

然后修改ServiceApplicationTests.java以加载此文件以用于测试属性:

import org.springframework.test.context.TestPropertySource;...
@TestPropertySource(locations="classpath:test.properties")
public class ServiceApplicationTests {...
}

添加school-service/src/main/resources/bootstrap.yml文件,该文件允许该实例从Spring Cloud Config中读取其配置。

eureka:client:serviceUrl:defaultZone: ${EUREKA_SERVER:https://localhost:8761/eureka}
spring:application:name: school-servicecloud:config:discovery:enabled: trueserviceId: CONFIGSERVERfailFast: true

然后复制config/school-ui.properties以具有等效的school-service

cp config/school-ui.properties config/school-service.properties

对于Docker Compose,您还需要使用以下设置创建config-data/school-service.properties

okta.oauth2.issuer=https://{yourOktaDomain}/oauth2/default
okta.oauth2.clientId={prodClientId}
okta.oauth2.clientSecret={prodClientId}

您还需要修改docker-compose.yml以便在失败时重新启动school-service

school-service:...restart: on-failure

您可以在Okta上创建一个使用客户端凭据的服务应用程序,但是这篇文章已经足够复杂了。 有关该方法的更多信息,请参阅使用Spring Boot和OAuth 2.0进行安全的服务器到服务器通信 。

您需要做的最后一步是修改SchoolController (在school-ui项目中),以向其对school-server的请求中添加OAuth 2.0访问令牌。

例子1.向RestTemplate添加一个AccessToken
package com.okta.developer.docker_microservices.ui.controller;import com.okta.developer.docker_microservices.ui.dto.TeachingClassDto;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClient;
import org.springframework.security.oauth2.client.OAuth2AuthorizedClientService;
import org.springframework.security.oauth2.client.authentication.OAuth2AuthenticationToken;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;import java.io.IOException;
import java.util.List;@Controller
@RequestMapping("/")
public class SchoolController {private final OAuth2AuthorizedClientService authorizedClientService;private final RestTemplate restTemplate;public SchoolController(OAuth2AuthorizedClientService clientService,RestTemplate restTemplate) { (1)this.authorizedClientService = clientService;this.restTemplate = restTemplate;}@RequestMapping("")public ModelAndView index() {return new ModelAndView("index");}@GetMapping("/classes")@PreAuthorize("hasAuthority('SCOPE_profile')")public ResponseEntity<List<TeachingClassDto>> listClasses(@AuthenticationPrincipal OAuth2AuthenticationToken authentication) { (2)OAuth2AuthorizedClient authorizedClient =this.authorizedClientService.loadAuthorizedClient(authentication.getAuthorizedClientRegistrationId(),authentication.getName()); (3)OAuth2AccessToken accessToken = authorizedClient.getAccessToken(); (4)restTemplate.getInterceptors().add(getBearerTokenInterceptor(accessToken.getTokenValue())); (5)return restTemplate.exchange("https://school-service/class", HttpMethod.GET, null,new ParameterizedTypeReference<List<TeachingClassDto>>() {});}private ClientHttpRequestInterceptor getBearerTokenInterceptor(String accessToken) {return (request, bytes, execution) -> {request.getHeaders().add("Authorization", "Bearer " + accessToken);return execution.execute(request, bytes);};}
}
  1. OAuth2AuthorizedClientService依赖项添加到构造函数
  2. OAuth2AuthenticationToken注入listClasses()方法
  3. authentication创建OAuth2AuthorizedClient
  4. 从授权客户端获取访问令牌
  5. 将访问令牌添加到Authorization标头中

而已! 由于school-uischool-service使用相同的OIDC应用程序设置,因此服务器将识别并验证访问令牌(也是JWT),并允许访问。

此时,您可以选择使用./mvnw spring-boot:run或Docker Compose单独运行所有应用程序。 后一种方法只需要几个命令。

mvn clean install
docker-compose down
docker-compose up -d

使用HTTP Basic Auth与Eureka和Spring Cloud Config进行安全的微服务通信

为了进一步提高微服务,Eureka Server和Spring Cloud Config之间的安全性,您可以添加HTTP基本身份验证。 为此,您需要在configdiscovery项目中都添加spring-boot-starter-security作为依赖项。 然后,您需要为每个参数指定一个spring.security.user.password并对其进行加密。 您可以在Spring Cloud Config的安全性文档中了解有关如何执行此操作的更多信息。

在两个项目中都配置了Spring Security之后,就可以调整URL以在其中包含用户名和密码。 例如,以下是在school-ui项目的bootstrap.yml

eureka:client:serviceUrl:defaultZone: ${EUREKA_SERVER:https://username:password@localhost:8761/eureka}

您需要对docker-compose.yml的URL进行类似的调整。

增强您对Spring微服务,Docker和OAuth 2.0的了解

本教程向您展示了如何确保微服务体系结构中的服务到服务通信是安全的。 您学习了如何在所有地方使用HTTPS以及如何使用OAuth 2.0和JWT锁定API。

您可以在oktadeveloper / okta-spring-microservices-https-example上的GitHub上找到此示例的源代码。

如果您想进一步探讨这些主题,我想您会喜欢以下博客文章:

  • 构建Spring微服务并对其进行Dockerize生产
  • 使用Spring Boot为Microbrews构建微服务架构
  • 使用Spring Boot 2.0和OAuth 2.0构建并保护微服务
  • 使用OAuth 2.0和JHipster开发微服务架构
  • 使用Spring Boot和OAuth 2.0进行安全的服务器到服务器通信

这些博客文章有助于使本文中的所有内容都能正常工作:

  • 使用Spring Cloud Netflix Eureka进行安全发现
  • 让我们加密保护的Spring Boot

有问题吗? 在下面的评论中询问他们! 如果您的问题与这篇文章无关,请将其发布到我们的开发者论坛 。

要获取有关更多技术博客文章的通知, 请在Twitter上关注我们@oktadev或订阅我们的YouTube频道 。

“具有HTTPS和OAuth 2.0的安全的服务到服务的Spring微服务”最初于2019年3月7日发布在Okta开发者博客上。

“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证。

翻译自: https://www.javacodegeeks.com/2019/03/secure-service-spring-microservices.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/343435.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java ee13_一口气了解多线程及其Java实现

进程&#xff1a;进程就是应用程序在内存中分配的空间&#xff0c;也就是正在运行的程序&#xff0c;各个进程之间不干扰。同时进程保存着程序每一个时刻运行的状态。程序&#xff1a;用某种编程语言(java、python等)编写&#xff0c;能够完成一定任务或者功能的代码集合&#…

apache camel_Apache Camel中的断路器模式

apache camel骆驼通常在分布式环境中用于访问远程资源。 远程服务可能由于各种原因和期间而失败。 对于短时间后暂时不可用且可恢复的服务&#xff0c;重试策略可能会有所帮助。 但是某些服务可能会失败或挂起更长时间&#xff0c;从而使调用应用程序无响应且速度缓慢。 防止级…

matlab 形态学 颗粒_数字图像处理Matlab-形态学图像处理(附代码)

这是一篇基于matlab&#xff0c;数字图像处理的形态学研究与实现的文章&#xff0c;希望能对你产生帮助。我还写了一套《数字图像处理》(冈萨雷斯版本)的学习笔记&#xff0c;欢迎关注我的csdn同名主页&#xff0c;一起学习成长~1.Objectives:1&#xff0e;利用 MATLAB 研究二值…

视频光端机维护三大步骤

视频光端机分为发射端设备和接收端设备&#xff0c;发射端设备和摄像机一样置于室外&#xff0c;工程人员通常是对发射端设备过行维护测试。对于视频光端机的检修工作&#xff0c;我们一般分为三个步骤来进行测试。接下来就由飞畅科技的小编来带大家详细了解下视频光端机维护的…

2021年广东-国家开放大学考试指南(必看)-远程辅助以及微信公众号查题

考前准备工作 一、电脑以及摄像头、浏览器准备 1&#xff1a;一台比较流畅的电脑&#xff0c;这个千万不能马虎&#xff0c;万一考试电脑蓝屏或者卡顿&#xff0c;那是很要命的。 2&#xff1a;摄像头&#xff1a;笔记本有自带的可以用自带的&#xff0c;如果是台式机&#…

飞畅科技——视频光端机用光模块的选型详解

光模块的出现简化了数字视频光端机的设计&#xff0c;我们只要把光模块当作一个具有光电转换功能的部件就可以了。那么针对各种不同的光端机&#xff0c;应该怎样选择相应的光模块呢&#xff1f;接下来就由飞畅科技的小编来为大家详细介绍下视频光端机用光模块的选型&#xff0…

视频监控中的光端机是干什么用的?

现如今&#xff0c;随着社会的进步和经济的发展&#xff0c;人民生活开始富裕&#xff0c;经济宽裕的家庭用户已开始考虑使用监控产品来保护自己&#xff0c;监控已经呈现融入家庭生活的趋势。就数字监控而言&#xff0c;虽然是后起之秀&#xff0c;但依然是现阶段发展趋势。光…

每个Java开发人员都应该知道的10个基本工具

大家好&#xff0c;我们已经到了2019年的第二个月&#xff0c;我相信你们所有人都已经为2019年的学习目标以及如何实现这些目标制定了目标。 我一直在撰写一系列文章&#xff0c;为您提供一些知识&#xff0c;使您可以学习和改进以成为2019年更好的全方位开发人员&#xff0c;例…

spring集成jndi_Spring应用程序与JNDI连接池的集成测试

spring集成jndi我们都知道&#xff0c;无论何时连接到数据库&#xff0c;都需要使用连接池。 所有使用JDBC 4类的现代驱动程序都支持它。 在本文中&#xff0c;我们将概述Spring应用程序中的连接池&#xff0c;以及如何在非JEE环境&#xff08;例如测试&#xff09;中处理相同的…

数字光端机和模拟视频光端机的六个不同点

说到模拟视频光端机与数字光端机的不同之处&#xff0c;在这里飞畅科技的小编要介绍六点不一样的地方来详细讲解模拟视频光端机与数字光端机的不同。模拟视频光端机与数字光端机究竟有何区别&#xff0c;这也是众多用户所关心的确问题&#xff0c;本文从以下几个方面进行如下论…

在硒中按TagName定位元素

硒定位器是处理网页上的元素时的关键。 从ID&#xff0c;名称&#xff0c;类&#xff0c;标记名&#xff0c;XPath&#xff0c;CSS选择器等定位器列表中&#xff0c;可以根据需要选择其中任何一种&#xff0c;然后在网页上找到Web元素。 由于与tagName或linktext相比&#xff0…

Java注解参数类型枚举值_EffectiveJava-5-枚举和注解

用enum代替int常量1. int枚举&#xff1a;引入枚举前&#xff0c;一般是声明一组具名的int常量&#xff0c;每个常量代表一个类型成员&#xff0c;这种方法叫做int枚举模式。int枚举模式是类型不安全的&#xff0c;例如下面两组常量&#xff1a;性别和动物种类&#xff0c;二者…

工业交换机:如果出现了物理性故障该怎么判断?

一般工业交换机出现故障大致可以分为&#xff1a;软性能故障和物理性故障。软性能故障一般是指工业交换机在研发设计方面出现的问题。今天就由飞畅科技的小编来给大家聊聊工业交换机物理性故障该怎么判断&#xff1f;一起来看看吧&#xff01; 物理层故障主要是指交换机本身的…

q7goodies事例_Java 8 Friday Goodies:精益并发

q7goodies事例在Data Geekery &#xff0c;我们喜欢Java。 而且&#xff0c;由于我们真的很喜欢jOOQ的流畅的API和查询DSL &#xff0c;我们对Java 8将为我们的生态系统带来什么感到非常兴奋。 我们已经写了一些关于Java 8好东西的博客 &#xff0c;现在我们觉得是时候开始一个…

工业交换机的外壳设计重要吗?

工业交换机一般使用在环境比较恶劣的地方&#xff0c;例如工厂等&#xff0c;为了让工业交换机更好的使用&#xff0c;工业交换机的外壳设计起到至关重要的作用&#xff0c;工业交换机的外壳可以更好的保护工业交换机的使用&#xff0c;那么如何才能选到实用的工业交换机外壳呢…

工业交换机和工业4G路由器的区分

工业交换机也称作工业以太网交换机&#xff0c;即应用于工业控制领域的以太网交换机设备&#xff0c;由于采用的网络标准&#xff0c;其开放性好、应用广泛以及价格低廉、使用的是透明而统一的TCP/IP协议&#xff0c;以太网已经成为工业控制领域的主要通信标准。工业交换机具有…

工业交换机和工业级光纤收发器的区别

工业交换机和工业级光纤收发器都是网络数据传输设备中的重要组成部分。工业交换机是进行网络内数据交换的一种以太网连接设备&#xff0c;而工业级光纤收发器是延长传输距离的一种光电转换设备。那么他们之间具体有哪些不同之处呢&#xff1f;接下来就由飞畅科技的小编来为大家…

工业交换机选择时需要注意什么?

工业以太网交换机是用于连接以太网的设备&#xff0c;应用十分广泛&#xff0c;主要应用于&#xff1a;煤矿安全、轨道交通、工厂自动化、水处理系统、城市安防等。现如今&#xff0c;市场上的工业交换机品牌厂家有很多&#xff0c;如何选购合适的以太网交换机是件令人困扰的事…

html如何与php,html页面怎么跟php文件连接

HTML页面调用PHP文件的方法是要通过JavaScript来实现&#xff0c;在生成静态页面时&#xff0c;可以根据数据库id给html页面生成一个对应的JavaScript文件来调用PHP文件。HTML页面调用PHP文件的方法是要通过JavaScript来实现&#xff0c;在生成静态页面时&#xff0c;可以根据数…

为使节构建控制平面的指南第3部分-特定于域的配置API

这是探索为Envoy Proxy构建控制平面的系列文章的第3部分。 在本博客系列中&#xff0c;我们将研究以下领域&#xff1a; 采用一种机制来动态更新Envoy的路由&#xff0c;服务发现和其他配置 确定哪些组件构成了控制平面&#xff0c;包括后备存储&#xff0c;服务发现API&…