最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringCloud?Gateway讀取Request?Body方式

 更新時(shí)間:2022年03月15日 09:58:02   作者:古甲哈醒  
這篇文章主要介紹了SpringCloud?Gateway讀取Request?Body方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Gateway讀取Request Body

我們使用SpringCloud Gateway做微服務(wù)網(wǎng)關(guān)的時(shí)候,經(jīng)常需要在過濾器Filter中讀取到Post請(qǐng)求中的Body內(nèi)容進(jìn)行日志記錄、簽名驗(yàn)證、權(quán)限驗(yàn)證等操作。我們知道,Request的Body是只能讀取一次的,如果直接通過在Filter中讀取,而不封裝回去回導(dǎo)致后面的服務(wù)無法讀取數(shù)據(jù)。

SpringCloud Gateway內(nèi)部提供了一個(gè)斷言工廠類ReadBodyPredicateFactory,這個(gè)類實(shí)現(xiàn)了讀取Request的Body內(nèi)容并放入緩存,我們可以通過從緩存中獲取body內(nèi)容來實(shí)現(xiàn)我們的目的。

分析ReadBodyPredicateFactory

public AsyncPredicate<ServerWebExchange> applyAsync(ReadBodyPredicateFactory.Config config) {
? ? ? ? return (exchange) -> {
? ? ? ? ? ? Class inClass = config.getInClass();
? ? ? ? ? ? Object cachedBody = exchange.getAttribute("cachedRequestBodyObject");
? ? ? ? ? ? if (cachedBody != null) {
? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? boolean test = config.predicate.test(cachedBody);
? ? ? ? ? ? ? ? ? ? exchange.getAttributes().put("read_body_predicate_test_attribute", test);
? ? ? ? ? ? ? ? ? ? return Mono.just(test);
? ? ? ? ? ? ? ? } catch (ClassCastException var7) {
? ? ? ? ? ? ? ? ? ? if (LOGGER.isDebugEnabled()) {
? ? ? ? ? ? ? ? ? ? ? ? LOGGER.debug("Predicate test failed because class in predicate does not match the cached body object", var7);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? return Mono.just(false);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? return DataBufferUtils.join(exchange.getRequest().getBody()).flatMap((dataBuffer) -> {
? ? ? ? ? ? ? ? ? ? DataBufferUtils.retain(dataBuffer);
? ? ? ? ? ? ? ? ? ? final Flux<DataBuffer> cachedFlux = Flux.defer(() -> {
? ? ? ? ? ? ? ? ? ? ? ? return Flux.just(dataBuffer.slice(0, dataBuffer.readableByteCount()));
? ? ? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? ? ? ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(exchange.getRequest()) {
? ? ? ? ? ? ? ? ? ? ? ? public Flux<DataBuffer> getBody() {
? ? ? ? ? ? ? ? ? ? ? ? ? ? return cachedFlux;
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? };
? ? ? ? ? ? ? ? ? ? return ServerRequest.create(exchange.mutate().request(mutatedRequest).build(), messageReaders).bodyToMono(inClass).doOnNext((objectValue) -> {
? ? ? ? ? ? ? ? ? ? ? ? exchange.getAttributes().put("cachedRequestBodyObject", objectValue);
? ? ? ? ? ? ? ? ? ? ? ? exchange.getAttributes().put("cachedRequestBody", cachedFlux);
? ? ? ? ? ? ? ? ? ? }).map((objectValue) -> {
? ? ? ? ? ? ? ? ? ? ? ? return config.predicate.test(objectValue);
? ? ? ? ? ? ? ? ? ? });
? ? ? ? ? ? ? ? });
? ? ? ? ? ? }
? ? ? ? };
? ? }

通過查看ReadBodyPredicateFactory內(nèi)部實(shí)現(xiàn),我們可以看到,該工廠類將request body內(nèi)容讀取后存放在 exchange的cachedRequestBodyObject中。

那么我們可以通過代碼:

exchange.getAttribute(“cachedRequestBodyObject”); //將body內(nèi)容取出來

知道如何取body內(nèi)容后,我們只需將該工廠類注冊(cè)到y(tǒng)ml配置文件中的predicates,然后從Filter中獲取即可。

配置ReadBodyPredicateFactory

查看ReadBodyPredicateFactory關(guān)于配置的代碼:

public <T> ReadBodyPredicateFactory.Config setPredicate(Class<T> inClass, Predicate<T> predicate) {
? ? ? ? ? ? this.setInClass(inClass);
? ? ? ? ? ? this.predicate = predicate;
? ? ? ? ? ? return this;
? ? ? ? }

配置該工廠類需要兩個(gè)參數(shù):

  • inClass:接收body內(nèi)容的對(duì)象Class,我們用字符串接收,配置String即可。
  • Predicate:Predicate的接口實(shí)現(xiàn)類,我們自定義一個(gè)Predicate的實(shí)現(xiàn)類即可。

自定義Predicate實(shí)現(xiàn),并注冊(cè)Bean。

? ? /**
? ? ?* 用于readBody斷言,可配置到y(tǒng)ml
? ? ?* @return
? ? ?*/
? ? @Bean
? ? public Predicate bodyPredicate(){
? ? ? ? return new Predicate() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public boolean test(Object o) {
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
? ? ? ? };
? ? }

兩個(gè)參數(shù)都有了,直接在yml中配置:

? ? ? ? predicates:
? ? ? ? - Path=/card/api/**
? ? ? ? - name: ReadBodyPredicateFactory #使用ReadBodyPredicateFactory斷言,將body讀入緩存
? ? ? ? ? args:
? ? ? ? ? ? inClass: '#{T(String)}'
? ? ? ? ? ? predicate: '#{@bodyPredicate}' #注入實(shí)現(xiàn)predicate接口類

編寫自定義GatewayFilterFactory

編寫自己的過濾器工廠類,讀取緩存的body內(nèi)容,并支持在配置文件中配置。

public class ReadBodyGatewayFilterFactory
? ? ? ? extends AbstractGatewayFilterFactory<ReadBodyGatewayFilterFactory.Config> {
? ? private Logger logger = LoggerFactory.getLogger(ReadBodyGatewayFilterFactory.class);
? ? private static final String CACHE_REQUEST_BODY_OBJECT_KEY = "cachedRequestBodyObject";
? ? public ReadBodyGatewayFilterFactory() {
? ? ? ? super(Config.class);
? ? }
? ? @Override
? ? public GatewayFilter apply(Config config) {
? ? ? ? return ((exchange, chain) -> {
? ? ? ? ? ? //利用ReadBodyPredicateFactory斷言,會(huì)將body讀入exchange的cachedRequestBodyObject中
? ? ? ? ? ? Object requestBody = exchange.getAttribute(CACHE_REQUEST_BODY_OBJECT_KEY);
? ? ? ? ? ? logger.info("request body is:{}", requestBody);
? ? ? ? ? ? return chain.filter(exchange);
? ? ? ? });
? ? }
? ? @Override
? ? public List<String> shortcutFieldOrder() {
? ? ? ? return Arrays.asList("withParams");//將參數(shù)放入
? ? }
? ? public static class Config {
? ? ? ? private boolean withParams;//接收配置的參數(shù)值,可以隨便寫
? ? ? ? public boolean isWithParams() {
? ? ? ? ? ? return withParams;
? ? ? ? }
? ? ? ? public void setWithParams(boolean withParams) {
? ? ? ? ? ? this.withParams = withParams;
? ? ? ? }
? ? }
}

將ReadBodyGatewayFilterFactory工程類在容器中注入。

? ? ?/**
? ? ?* 注入ReadBody過濾器
? ? ?* @return
? ? ?*/
? ? @Bean
? ? public ReadBodyGatewayFilterFactory readBodyGatewayFilterFactory() {
? ? ? ? return new ReadBodyGatewayFilterFactory();
? ? }

到此,我們的Filter類也可以在yml配置文件中直接配置使用了。

完整的yml配置

? ? ? - id: body_route #讀取post中的body路由
? ? ? ? order: 5
? ? ? ? uri: lb://API-CARD
? ? ? ? filters:
? ? ? ? - ReadBody=true #使用自定義的過濾器工廠類,讀取request body內(nèi)容
? ? ? ? predicates:
? ? ? ? - Path=/card/api/**
? ? ? ? - name: ReadBodyPredicateFactory #使用ReadBodyPredicateFactory斷言,將body讀入緩存
? ? ? ? ? args:
? ? ? ? ? ? inClass: '#{T(String)}'
? ? ? ? ? ? predicate: '#{@bodyPredicate}' #注入實(shí)現(xiàn)predicate接口類

OK,以上是通過ReadBodyPredicateFactory這個(gè)類讀取到request body內(nèi)容。

另外springcloud gateway內(nèi)部還提供了ModifyRequestBodyGatewayFilterFactory類用于修改body內(nèi)容,既然能修改,自然也能獲取body,大家可自行去研究。

Gateway自定義filter獲取body的數(shù)據(jù)為空

最近在使用SpringCloud Gateway進(jìn)行網(wǎng)關(guān)的開發(fā),我使用的版本是:SpringBoot的2.3.4.RELEASE+SpringCloud的Hoxton.SR8,在自定義過濾器時(shí)需要獲取ServerHttpRequest中body的數(shù)據(jù),發(fā)現(xiàn)一直無法獲取到數(shù)據(jù),經(jīng)過各種百度、谷歌,再加上自己的實(shí)踐,終于找到解決方案:

首先創(chuàng)建一個(gè)全局過濾器把body中的數(shù)據(jù)緩存起來

package com.cloudpath.gateway.portal.filter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpRequestDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
/**
?* @author mazhen
?* @className CacheBodyGlobalFilter
?* @Description 把body中的數(shù)據(jù)緩存起來
?* @date 2020/10/28 18:02
?*/
@Slf4j
@Component
public class CacheBodyGlobalFilter implements Ordered, GlobalFilter {
? ? // ?public static final String CACHE_REQUEST_BODY_OBJECT_KEY = "cachedRequestBodyObject";
? ? @Override
? ? public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
? ? ? ? if (exchange.getRequest().getHeaders().getContentType() == null) {
? ? ? ? ? ? return chain.filter(exchange);
? ? ? ? } else {
? ? ? ? ? ? return DataBufferUtils.join(exchange.getRequest().getBody())
? ? ? ? ? ? ? ? ? ? .flatMap(dataBuffer -> {
? ? ? ? ? ? ? ? ? ? ? ? DataBufferUtils.retain(dataBuffer);
? ? ? ? ? ? ? ? ? ? ? ? Flux<DataBuffer> cachedFlux = Flux
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? .defer(() -> Flux.just(dataBuffer.slice(0, dataBuffer.readableByteCount())));
? ? ? ? ? ? ? ? ? ? ? ? ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? exchange.getRequest()) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? ? ? ? ? ? ? public Flux<DataBuffer> getBody() {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return cachedFlux;
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? };
? ? ? ? ? ? ? ? ? ? ? ? //exchange.getAttributes().put(CACHE_REQUEST_BODY_OBJECT_KEY, cachedFlux);
? ? ? ? ? ? ? ? ? ? ? ? return chain.filter(exchange.mutate().request(mutatedRequest).build());
? ? ? ? ? ? ? ? ? ? });
? ? ? ? }
? ? }
? ? @Override
? ? public int getOrder() {
? ? ? ? return Ordered.HIGHEST_PRECEDENCE;
? ? }
}

CacheBodyGlobalFilter這個(gè)全局過濾器的目的就是把原有的request請(qǐng)求中的body內(nèi)容讀出來,并且使用ServerHttpRequestDecorator這個(gè)請(qǐng)求裝飾器對(duì)request進(jìn)行包裝,重寫getBody方法,并把包裝后的請(qǐng)求放到過濾器鏈中傳遞下去。這樣后面的過濾器中再使用exchange.getRequest().getBody()來獲取body時(shí),實(shí)際上就是調(diào)用的重載后的getBody方法,獲取的最先已經(jīng)緩存了的body數(shù)據(jù)。這樣就能夠?qū)崿F(xiàn)body的多次讀取了。

值得一提的是,這個(gè)過濾器的order設(shè)置的是Ordered.HIGHEST_PRECEDENCE,即最高優(yōu)先級(jí)的過濾器。優(yōu)先級(jí)設(shè)置這么高的原因是某些系統(tǒng)內(nèi)置的過濾器可能也會(huì)去讀body,這樣就會(huì)導(dǎo)致我們自定義過濾器中獲取body的時(shí)候報(bào)body只能讀取一次這樣的錯(cuò)誤如下:

java.lang.IllegalStateException: Only one connection receive subscriber allowed.
    at reactor.ipc.netty.channel.FluxReceive.startReceiver(FluxReceive.java:279)
    at reactor.ipc.netty.channel.FluxReceive.lambda$subscribe$2(FluxReceive.java:129)
    at 

所以,必須把CacheBodyGlobalFilter的優(yōu)先級(jí)設(shè)到最高。

在自定義的過濾器中嘗試獲取body中的數(shù)據(jù)

package com.cloudpath.iam.gateway.customerfilter;
import com.cloudpath.iam.gateway.utils.FilterRequestResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import java.util.Arrays;
import java.util.List;
/**
?* @author by mazhen
?* @Classname TestGatewayFilterFactory
?* @Description 自定義過濾器獲取body中的數(shù)據(jù)
?* @Date 2020/10/27 14:38
?*/
@Component
@Slf4j
public class TestGatewayFilterFactory extends AbstractGatewayFilterFactory<TestGatewayFilterFactory.Config> {
? ? @Override
? ? public List<String> shortcutFieldOrder() {
? ? ? ? return Arrays.asList("enabled");
? ? }
? ? public TestGatewayFilterFactory() {
? ? ? ? super(Config.class);
? ? ? ? log.info("Loaded TestGatewayFilterFactory");
? ? }
? ? @Override
? ? public GatewayFilter apply(Config config) {
? ? ? ? return (exchange, chain) -> {
? ? ? ? ? ? if (!config.isEnabled()) {
? ? ? ? ? ? ? ? return chain.filter(exchange);
? ? ? ? ? ? }
? ? ? ? ? ? if (null != exchange) {
? ? ? ? ? ? ? ? ServerHttpRequest httpRequest = exchange.getRequest();
? ? ? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? ? ? Flux<DataBuffer> dataBufferFlux = httpRequest.getBody();
? ? ? ? ? ? ? ? ? ? ? ? //獲取body中的數(shù)據(jù)
? ? ? ? ? ? ? ? ? ? ? ? String body = FilterRequestResponseUtil.resolveBodyFromRequest(dataBufferFlux);
? ? ? ? ? ? ? ? ? ? ? ? log.info("body:{}",body);
? ? ? ? ? ? ? ? ? ? } catch (Exception e) {
? ? ? ? ? ? ? ? ? ? ? ? log.error("異常:",e);
? ? ? ? ? ? ? ? ? ? ? ? return chain.filter(exchange);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? return chain.filter(exchange);
? ? ? ? };
? ? }
? ? public static class Config {
? ? ? ? /**
? ? ? ? ?* 控制是否開啟統(tǒng)計(jì)
? ? ? ? ?*/
? ? ? ? private boolean enabled;
? ? ? ? public Config() {
? ? ? ? }
? ? ? ? public boolean isEnabled() {
? ? ? ? ? ? return enabled;
? ? ? ? }
? ? ? ? public void setEnabled(boolean enabled) {
? ? ? ? ? ? this.enabled = enabled;
? ? ? ? }
? ? }
}

解析body的工具類

package com.cloudpath.iam.gateway.utils;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import reactor.core.publisher.Flux;
import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
?* @author mazhen
?* @className FilterHeadersUtil
?* @Description 過濾器請(qǐng)求/響應(yīng)工具類
?* @date 2020/10/29 9:31
?*/
public final class FilterRequestResponseUtil {
? ? /**
? ? ?* spring cloud gateway 獲取post請(qǐng)求的body體
? ? ?* @param body
? ? ?* @return
? ? ?*/
? ? public static String resolveBodyFromRequest( Flux<DataBuffer> body){
? ? ? ? AtomicReference<String> bodyRef = new AtomicReference<>();
? ? ? ? // 緩存讀取的request body信息
? ? ? ? body.subscribe(dataBuffer -> {
? ? ? ? ? ? CharBuffer charBuffer = StandardCharsets.UTF_8.decode(dataBuffer.asByteBuffer());
? ? ? ? ? ? DataBufferUtils.release(dataBuffer);
? ? ? ? ? ? bodyRef.set(charBuffer.toString());
? ? ? ? });
? ? ? ? //獲取request body
? ? ? ? return bodyRef.get();
? ? }
? ? /**
? ? ?* 讀取body內(nèi)容
? ? ?* @param body
? ? ?* @return
? ? ?*/
? ? public static String resolveBodyFromRequest2( Flux<DataBuffer> body){
? ? ? ? StringBuilder sb = new StringBuilder();
? ? ? ? body.subscribe(buffer -> {
? ? ? ? ? ? byte[] bytes = new byte[buffer.readableByteCount()];
? ? ? ? ? ? buffer.read(bytes);
? ? ? ? ? ? DataBufferUtils.release(buffer);
? ? ? ? ? ? String bodyString = new String(bytes, StandardCharsets.UTF_8);
? ? ? ? ? ? sb.append(bodyString);
? ? ? ? });
? ? ? ? return formatStr(sb.toString());
? ? }
? ? /**
? ? ?* 去掉空格,換行和制表符
? ? ?* @param str
? ? ?* @return
? ? ?*/
? ? private static String formatStr(String str){
? ? ? ? if (str != null && str.length() > 0) {
? ? ? ? ? ? Pattern p = Pattern.compile("\\s*|\t|\r|\n");
? ? ? ? ? ? Matcher m = p.matcher(str);
? ? ? ? ? ? return m.replaceAll("");
? ? ? ? }
? ? ? ? return str;
? ? }
}

解析body的內(nèi)容,網(wǎng)上普遍是上面的兩種方式,親測(cè)resolveBodyFromRequest方法解析body中的數(shù)據(jù),沒有1024字節(jié)的限制。

ps:我傳的參數(shù)有1萬多字節(jié)。。。。。。。

大家可以按需所選。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Spring+Quartz配置定時(shí)任務(wù)實(shí)現(xiàn)代碼

    Spring+Quartz配置定時(shí)任務(wù)實(shí)現(xiàn)代碼

    這篇文章主要介紹了Spring+Quartz配置定時(shí)任務(wù)實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • 淺析SpringBoot2.4 靜態(tài)資源加載問題

    淺析SpringBoot2.4 靜態(tài)資源加載問題

    這篇文章主要介紹了SpringBoot2.4 靜態(tài)資源加載問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • Springboot內(nèi)嵌tomcat應(yīng)用原理深入分析

    Springboot內(nèi)嵌tomcat應(yīng)用原理深入分析

    懂得SpringBoot的童鞋應(yīng)該很清楚,不管應(yīng)用程序是屬于何種類型,都是一個(gè)Main方法走遍天下,對(duì)于web應(yīng)用,只需要引入spring-boot-starter-web中這個(gè)依賴,應(yīng)用程序就好像直接給我們來了個(gè)tomcat一樣,對(duì)于嵌入式Tomcat,其實(shí)也非常簡(jiǎn)單,就是調(diào)用Tomcat提供的外部類
    2022-09-09
  • Java報(bào)NoClassDefFoundError異常的原因及解決

    Java報(bào)NoClassDefFoundError異常的原因及解決

    在 Java 開發(fā)過程中, java.lang.NoClassDefFoundError 是一個(gè)令人頭疼的運(yùn)行時(shí)錯(cuò)誤,本文將深入探討這一問題的原因和常見場(chǎng)景,并提供實(shí)用的解決方法,希望對(duì)大家有所幫助
    2025-03-03
  • SpringBoot集成itext實(shí)現(xiàn)html轉(zhuǎn)PDF

    SpringBoot集成itext實(shí)現(xiàn)html轉(zhuǎn)PDF

    iText是著名的開放源碼的站點(diǎn)sourceforge一個(gè)項(xiàng)目,是用于生成PDF文檔的一個(gè)java類庫(kù),本文主要介紹了如何利用itext實(shí)現(xiàn)html轉(zhuǎn)PDF,需要的可以參考下
    2024-03-03
  • Java BigInteger類,BigDecimal類,Date類,DateFormat類及Calendar類用法示例

    Java BigInteger類,BigDecimal類,Date類,DateFormat類及Calendar類用法示例

    這篇文章主要介紹了Java BigInteger類,BigDecimal類,Date類,DateFormat類及Calendar類用法,結(jié)合實(shí)例形式詳細(xì)分析了Java使用BigInteger類,BigDecimal類,Date類,DateFormat類及Calendar類進(jìn)行數(shù)值運(yùn)算與日期運(yùn)算相關(guān)操作技巧,需要的朋友可以參考下
    2019-03-03
  • 使用jaxws建立webservice客戶端并實(shí)現(xiàn)soap消息的handler驗(yàn)證示例

    使用jaxws建立webservice客戶端并實(shí)現(xiàn)soap消息的handler驗(yàn)證示例

    這篇文章主要介紹了使用jaxws建立webservice客戶端并實(shí)現(xiàn)soap消息的handler驗(yàn)證示例,需要的朋友可以參考下
    2014-03-03
  • 如何在Spring?Boot中使用MyBatis訪問數(shù)據(jù)庫(kù)

    如何在Spring?Boot中使用MyBatis訪問數(shù)據(jù)庫(kù)

    MyBatis可以通過簡(jiǎn)單的XML或者注解來配置和映射原始類型,接口,和Java POJO為數(shù)據(jù)庫(kù)中記錄,使用MyBatis幫助我們解決各種問題,本文介紹如何在Spring?Boot中使用MyBatis訪問數(shù)據(jù)庫(kù),感興趣的朋友一起看看吧
    2023-11-11
  • java抓包后對(duì)pcap文件解析示例

    java抓包后對(duì)pcap文件解析示例

    這篇文章主要介紹了java抓包后對(duì)pcap文件解析示例,需要的朋友可以參考下
    2014-03-03
  • Ribbon負(fù)載均衡算法原理與使用介紹

    Ribbon負(fù)載均衡算法原理與使用介紹

    在微服務(wù)中,對(duì)服務(wù)進(jìn)行拆分之后,必然會(huì)帶來微服務(wù)之間的通信需求,而每個(gè)微服務(wù)為了保證高可用性,又會(huì)去部署集群,那么面對(duì)一個(gè)集群微服務(wù)進(jìn)行通信的時(shí)候,如何進(jìn)行負(fù)載均衡也是必然需要考慮的問題
    2022-09-09

最新評(píng)論

梅州市| 垣曲县| 靖安县| 东乡县| 梅州市| 余干县| 龙川县| 上栗县| 东乡县| 门源| 育儿| 防城港市| 乐昌市| 西峡县| 蚌埠市| 永定县| 那坡县| 嵊泗县| 保定市| 始兴县| 呼和浩特市| 宽甸| 上蔡县| 曲麻莱县| 西峡县| 日喀则市| 天门市| 金昌市| 河池市| 称多县| 蓬莱市| 禄劝| 南丰县| 柳江县| 体育| 陆河县| 筠连县| 航空| 昔阳县| 木兰县| 铜陵市|