国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SpringCloud GateWay網(wǎng)關(guān)通過(guò)全局?jǐn)r截器GlobalFilter實(shí)現(xiàn)API日志

這篇具有很好參考價(jià)值的文章主要介紹了SpringCloud GateWay網(wǎng)關(guān)通過(guò)全局?jǐn)r截器GlobalFilter實(shí)現(xiàn)API日志。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

SpringCloud GateWay+RocketMQ實(shí)現(xiàn)API訪問(wèn)日志收集

需求背景

產(chǎn)品經(jīng)理突然找到我說(shuō),咱們這個(gè)產(chǎn)品貌似沒(méi)有實(shí)現(xiàn)之前舊的系統(tǒng)平臺(tái)操作日志了;希望我盡快實(shí)現(xiàn)這個(gè)需求,以應(yīng)對(duì)一些檢查;因?yàn)闀r(shí)間關(guān)系再加上人員問(wèn)題,跟我原先規(guī)劃得有些背道而馳
SpringCloud GateWay網(wǎng)關(guān)通過(guò)全局?jǐn)r截器GlobalFilter實(shí)現(xiàn)API日志,SpringCloud,微服務(wù),spring cloud,gateway,java

草擬方案

1.寫一個(gè)AOP日志Starter,再需要的模塊中引入,對(duì)應(yīng)方法去標(biāo)記注解,工程量比較大,目前所有的模塊的都得逐步去添加,個(gè)人比較懶,因此該方案?jìng)溥x
2. 在網(wǎng)關(guān)層通過(guò)全局?jǐn)r截器Filter攔截所有請(qǐng)求,通過(guò)MQ記錄日志,再通過(guò)監(jiān)聽(tīng)MQ實(shí)現(xiàn)日志入庫(kù),因?yàn)樵鹊募軜?gòu)已經(jīng)有MQ了,所以覺(jué)得這種方案更快捷,因?yàn)閿]起袖子往下干

具體實(shí)現(xiàn)(推薦使用方式1)

之前一直在看如何去獲取請(qǐng)求體;各種區(qū)分MediaType跟Method對(duì)應(yīng)不同的讀取方式,解析重新構(gòu)建請(qǐng)求往下游傳遞,中間出現(xiàn)了各種問(wèn)題;沒(méi)有解決的一個(gè)情況是有幾個(gè)接口都是base64圖片傳參的,早前的通過(guò)BodyInserter 去重新構(gòu)建請(qǐng)求體跟獲取響應(yīng)體,遇到這幾個(gè)接口都會(huì)出現(xiàn)報(bào)錯(cuò)

private Mono<Void> writeBodyLog(ServerWebExchange exchange, GatewayFilterChain chain, GatewayLog gatewayLog) {
        ServerRequest serverRequest = ServerRequest.create(exchange, messageReaders);
        Mono<String> modifiedBody = serverRequest.bodyToMono(String.class)
                .flatMap(body -> {
                    gatewayLog.setRequestBody(body);
                    return Mono.just(body);
                });
        // 通過(guò) BodyInserter 插入 body, 避免 request body 只能獲取一次
        BodyInserter bodyInserter = BodyInserters.fromPublisher(modifiedBody, String.class);
        HttpHeaders headers = new HttpHeaders();
        headers.putAll(exchange.getRequest().getHeaders());
        // the new content type will be computed by bodyInserter
        // and then set in the request decorator
        headers.remove(HttpHeaders.CONTENT_LENGTH);
        CachedBodyOutputMessage outputMessage = new CachedBodyOutputMessage(exchange, headers);
 return bodyInserter.insert(outputMessage, new BodyInserterContext()).then(Mono.defer(() -> {
 	// 重新封裝請(qǐng)求
	ServerHttpRequest decoratedRequest = requestDecorate(exchange,headers,outputMessage);
	// 處理響應(yīng)日志
	ServerHttpResponseDecorator decoratedResponse =recordResponse(exchange,gatewayLog);
	return chain.filter(exchange.mutate().request(decoratedRequest).response(decoratedResponse).build()).then(Mono.fromRunnable(() -> { writeAccessLog(gatewayLog);}));}));
}

報(bào)錯(cuò)IllegalReferenceCountException異常(io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1)。具體如下

[TID:N/A] 2023-03-27 11:38:34.767 ERROR 30056 --- [ctor-http-nio-4] r.n.channel.ChannelOperationsHandler     : [id: 0x53e73793, L:/192.168.1.53:6868 ! R:/192.168.1.62:56218] Error was received while reading the incoming data. The connection will be closed.
io.netty.util.IllegalReferenceCountException: refCnt: 0, decrement: 1
 at io.netty.util.internal.ReferenceCountUpdater.toLiveRealRefCnt(ReferenceCountUpdater.java:74) ~[netty-common-4.1.51.Final.jar:4.1.51.Final]
 at io.netty.util.internal.ReferenceCountUpdater.release(ReferenceCountUpdater.java:138) ~[netty-common-4.1.51.Final.jar:4.1.51.Final]
 at io.netty.buffer.AbstractReferenceCountedByteBuf.release(AbstractReferenceCountedByteBuf.java:100) ~[netty-buffer-4.1.51.Final.jar:4.1.51.Final]
 at io.netty.handler.codec.http.DefaultHttpContent.release(DefaultHttpContent.java:92) ~[netty-codec-http-4.1.51.Final.jar:4.1.51.Final]
 at io.netty.util.ReferenceCountUtil.release(ReferenceCountUtil.java:88) ~[netty-common-4.1.51.Final.jar:4.1.51.Final]
 at reactor.netty.channel.FluxReceive.onInboundNext(FluxReceive.java:344) ~[reactor-netty-0.9.10.RELEASE.jar:0.9.10.RELEASE]
 at reactor.netty.channel.ChannelOperations.onInboundNext(ChannelOperations.java:358) ~[reactor-netty-0.9.10.RELEASE.jar:0.9.10.RELEASE]
 at reactor.netty.http.server.HttpServerOperations.onInboundNext(HttpServerOperations.java:487) ~[reactor-netty-0.9.10.RELEASE.jar:0.9.10.RELEASE]
 at reactor.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:96) ~[reactor-netty-0.9.10.RELEASE.jar:0.9.10.RELEASE]
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [netty-transport-4.1.51.Final.jar:4.1.51.Final]
 at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [netty-transport-4.1.51.Final.jar:4.1.51.Final]
 at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) [netty-transport-4.1.51.Final.jar:4.1.51.Fina

造成這個(gè)問(wèn)題的點(diǎn)有一種說(shuō)法:DataBufferUtils.release(buffer)在低版本spring-core下是有問(wèn)題,詳見(jiàn):https://github.com/spring-projects/spring-framework/issues/26060;如果依賴的spring-cloud-starter-gateway版本較低,可以單獨(dú)升spring-core的版本spring-core升級(jí)為5.2.13.RELEASE及以上【本人嘗試后還是報(bào)錯(cuò)但不是上面的錯(cuò)誤了,沒(méi)再去定位】

<dependency>
        	<groupId>org.springframework.cloud</groupId>
        	<artifactId>spring-cloud-starter-gateway</artifactId>
			<exclusions>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring-core</artifactId>
				</exclusion>
			</exclusions>
    	</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>5.2.13.RELEASE</version>
		</dependency>

后來(lái)更改了requeset.getBody()的方式也可以完成日志實(shí)現(xiàn),完整代碼如下:

@Component
@Slf4j
@RequiredArgsConstructor
public class GatewayLogFilterBak230329 implements GlobalFilter, Ordered {
    private final ApplicationEventPublisher applicationEventPublisher;
    private static final String CONTENT_TYPE = "application/json";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        // 請(qǐng)求路徑
        String requestPath = request.getPath().pathWithinApplication().value();
        // 獲取路由信息
        Route route = getGatewayRoute(exchange);
        String ipAddress = IpUtils.getIp(request);
        GatewayLog gatewayLog = new GatewayLog();
        gatewayLog.setDevice(IpUtils.getServerDevices(request));
        gatewayLog.setProtocol(request.getURI().getScheme());
        gatewayLog.setRequestMethod(request.getMethodValue());
        gatewayLog.setRequestPath(requestPath);
        gatewayLog.setTargetServer(route.getUri().toString());
        gatewayLog.setStartTime(new Date().getTime());
        gatewayLog.setIp(ipAddress);
        Map<String, Object> headers = new HashMap<>();
        for (String key : request.getHeaders().keySet()) {
            headers.put(key, request.getHeaders().getFirst(key));
        }
        gatewayLog.setHeaders(JSON.toJSONString(headers));
        MediaType mediaType = request.getHeaders().getContentType();
        if (request.getHeaders().getContentType() != null) {
            gatewayLog.setRequestContentType(request.getHeaders().getContentType().toString());
        }

        if (mediaType != null && (MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(mediaType) || MediaType.APPLICATION_JSON.isCompatibleWith(mediaType))) {
            return writeBodyLog(exchange, chain, gatewayLog);
        } else {
            return writeBasicLog(exchange, chain, gatewayLog);
        }
    }

    @Override
    public int getOrder() {
        // 過(guò)濾器鏈路上的排序要在NettyWriteResponseFilter(這個(gè)攔截器默認(rèn)是-1)之前
        return -2;
    }

    /**
     * 獲取路由信息
     *
     * @param exchange
     * @return
     */
    private Route getGatewayRoute(ServerWebExchange exchange) {
        return exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
    }

    private Mono<Void> writeBasicLog(ServerWebExchange exchange, GatewayFilterChain chain, GatewayLog gatewayLog) {
        MultiValueMap<String, String> queryParams = exchange.getRequest().getQueryParams();
        gatewayLog.setRequestBody(getUrlParamsByMap(queryParams));

        //獲取響應(yīng)體
        ServerHttpResponseDecorator decoratedResponse = recordResponseLog(exchange, gatewayLog);

        return chain.filter(exchange.mutate().response(decoratedResponse).build())
                .then(Mono.fromRunnable(() -> {
                    // 打印日志
                    writeAccessLog(gatewayLog);
                }));
    }


    /**
     * 解決 request body 只能讀取一次問(wèn)題,
     * 參考: org.springframework.cloud.gateway.filter.factory.rewrite.ModifyRequestBodyGatewayFilterFactory
     *
     * @param exchange
     * @param chain
     * @param gatewayLog
     * @return
     */
    private Mono<Void> writeBodyLog(ServerWebExchange exchange, GatewayFilterChain chain, GatewayLog gatewayLog) {
        ServerHttpRequest request = exchange.getRequest();
        return DataBufferUtils.join(request.getBody())
                .flatMap(d -> Mono.just(Optional.of(d))).defaultIfEmpty(Optional.empty())
                .flatMap(optional -> {
                    try {
                        URI uri = request.getURI();
                        HttpHeaders headers = new HttpHeaders();
                        headers.putAll(exchange.getRequest().getHeaders());

                        byte[] bodyBytes = null;
                        if (optional.isPresent()) {
                            byte[] oldBytes = new byte[optional.get().readableByteCount()];
                            optional.get().read(oldBytes);
                            bodyBytes = oldBytes;
                        }
                        // 無(wú)Body請(qǐng)求重寫
                        if (ArrayUtils.isEmpty(bodyBytes)) {
                            return chain.filter(exchange.mutate().request(new ServerHttpRequestDecorator(request.mutate().uri(uri).build()) {
                                @Override
                                public HttpHeaders getHeaders() {
                                    return headers;
                                }
                            }).response(recordResponseLog(exchange, gatewayLog)).build());
                        }
                        String body = new String(bodyBytes, StandardCharsets.UTF_8);
                        gatewayLog.setRequestBody(body);
                        final byte[] finalBodyBytes = bodyBytes;
                        return chain.filter(exchange.mutate().request(new ServerHttpRequestDecorator(request.mutate().uri(uri).build()) {
                            @Override
                            public Flux<DataBuffer> getBody() {
                                DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(finalBodyBytes);
                                DataBufferUtils.retain(buffer);

                                return Flux.just(buffer);
                            }

                            @Override
                            public HttpHeaders getHeaders() {
                                return headers;
                            }
                        }).response(recordResponseLog(exchange, gatewayLog)).build()).then(Mono.fromRunnable(() -> {
                            writeAccessLog(gatewayLog);
                        }));
                    } catch (Exception ex) {
                        return chain.filter(exchange);
                    } finally {
                        if (optional.isPresent()) {
                            DataBufferUtils.release(optional.get());
                        }
                    }
                });
    }


    /**
     * 打印日志
     *
     * @param gatewayLog 網(wǎng)關(guān)日志
     */
    private void writeAccessLog(GatewayLog gatewayLog) {
        applicationEventPublisher.publishEvent(new GatewayLogEvent(this, gatewayLog));
    }

    /**
     * 記錄響應(yīng)日志
     * 通過(guò) DataBufferFactory 解決響應(yīng)體分段傳輸問(wèn)題。
     */
    private ServerHttpResponseDecorator recordResponseLog(ServerWebExchange exchange, GatewayLog gatewayLog) {
        ServerHttpResponse response = exchange.getResponse();
        DataBufferFactory bufferFactory = response.bufferFactory();

        return new ServerHttpResponseDecorator(response) {
            @Override
            public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
                if (body instanceof Flux) {
                    Date responseTime = new Date();
                    gatewayLog.setEndTime(responseTime.getTime());
                    // 計(jì)算執(zhí)行時(shí)間
                    long executeTime = (responseTime.getTime() - gatewayLog.getStartTime());
                    gatewayLog.setExecuteTime(executeTime);
                    gatewayLog.setStatus(response.getStatusCode().value() == 200 ? "成功" : "失敗");
                    // 獲取響應(yīng)類型,如果是 json 就打印
                    String originalResponseContentType = exchange.getAttribute(ServerWebExchangeUtils.ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR);

                    if (Objects.equals(this.getStatusCode(), HttpStatus.OK)
                            && StringUtils.isNotBlank(originalResponseContentType)
                            && originalResponseContentType.contains(CONTENT_TYPE)) {

                        Flux<? extends DataBuffer> fluxBody = Flux.from(body);
                        return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
                            // 合并多個(gè)流集合,解決返回體分段傳輸
                            DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
                            DataBuffer join = dataBufferFactory.join(dataBuffers);
                            byte[] content = new byte[join.readableByteCount()];
                            join.read(content);
                            // 釋放掉內(nèi)存
                            DataBufferUtils.release(join);
                            String responseResult = new String(content, StandardCharsets.UTF_8);
                            gatewayLog.setResponseData(responseResult);
                            return bufferFactory.wrap(content);
                        }));
                    }
                }
                // if body is not a flux. never got there.
                return super.writeWith(body);
            }
        };
    }


    /**
     * 將map參數(shù)轉(zhuǎn)換成url參數(shù)
     *
     * @param map
     * @return
     */
    private String getUrlParamsByMap(MultiValueMap<String, String> map) {
        if (ObjectUtils.isEmpty(map)) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, List<String>> entry : map.entrySet()) {
            sb.append(entry.getKey()).append("=").append(entry.getValue().get(0));
            sb.append("&");
        }
        String s = sb.toString();
        if (s.endsWith("&")) {
            s = StringUtils.substringBeforeLast(s, "&");
        }
        return s;
    }
}

后來(lái)也參考了蠻多大牛文章,自己也去找了很久gateway源代碼,終于在這個(gè)工具類ServerWebExchangeUtils中發(fā)現(xiàn)有更好實(shí)現(xiàn)的點(diǎn),cacheRequestBody()這個(gè)方法,英文注釋大概是說(shuō)可以緩存請(qǐng)求正文到這個(gè)屬性中;后續(xù)可以通過(guò)獲取屬性的方式獲取到請(qǐng)求正文;拿著這個(gè)方法去百度果然有人也是這么解決請(qǐng)求體的問(wèn)題,直接上代碼。

方式一:通過(guò)兩個(gè)攔截器終于實(shí)現(xiàn)了日志記錄

@Slf4j
@Component
// 頂級(jí)過(guò)濾器用來(lái)緩存請(qǐng)求正文
public class CacheGlobalRequestBodyFilter implements Ordered, GatewayFilter, GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return ServerWebExchangeUtils
                .cacheRequestBody(
                        exchange,
                        (request) -> chain.filter(
                                exchange.mutate().request(request).build()));
    }
    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE;
    }
}
@Slf4j
@Component
@RequiredArgsConstructor
public class GatewayLogFilter implements GlobalFilter, Ordered {
    private final ApplicationEventPublisher applicationEventPublisher;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        // 請(qǐng)求路徑
        String requestPath = request.getPath().pathWithinApplication().value();
        // 獲取路由信息
        Route route = getGatewayRoute(exchange);
        String ipAddress = IpUtils.getIp(request);
        GatewayLog gatewayLog = new GatewayLog();
        gatewayLog.setDevice(IpUtils.getServerDevices(request));
        gatewayLog.setProtocol(request.getURI().getScheme());
        gatewayLog.setRequestMethod(request.getMethodValue());
        gatewayLog.setRequestPath(requestPath);
        gatewayLog.setTargetServer(route.getUri().toString());
        gatewayLog.setStartTime(new Date().getTime());
        gatewayLog.setIp(ipAddress);
        Map<String, Object> headers = new HashMap<>();
        for (String key : request.getHeaders().keySet()) {
            headers.put(key, request.getHeaders().getFirst(key));
        }
        gatewayLog.setHeaders(JSON.toJSONString(headers));
        if (request.getHeaders().getContentType() != null) {
            gatewayLog.setRequestContentType(request.getHeaders().getContentType().toString());
        }
        // GatewayUtil.getRequestBodyContent(exchange)這里實(shí)際上就是一個(gè)獲取 exchange.getAttribute(ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR)屬性而已
        gatewayLog.setRequestBody(GatewayUtil.getRequestBodyContent(exchange));
        //獲取響應(yīng)體
        ServerHttpResponseDecorator decoratedResponse = recordResponseLog(exchange, gatewayLog);
        return chain.filter(exchange.mutate().response(decoratedResponse).build())
                .then(Mono.fromRunnable(() -> {
                    // 打印日志
                    writeAccessLog(gatewayLog);
                }));
    }

    @Override
    public int getOrder() {
        return 0;
    }

    /**
     * 獲取路由信息
     *
     * @param exchange
     * @return
     */
    private Route getGatewayRoute(ServerWebExchange exchange) {
        return exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
    }

    /**
     * 打印日志
     *
     * @param gatewayLog 網(wǎng)關(guān)日志
     */
    private void writeAccessLog(GatewayLog gatewayLog) {
        applicationEventPublisher.publishEvent(new GatewayLogEvent(this, gatewayLog));
    }

    /**
     * 記錄響應(yīng)日志
     * 通過(guò) DataBufferFactory 解決響應(yīng)體分段傳輸問(wèn)題。
     */
    private ServerHttpResponseDecorator recordResponseLog(ServerWebExchange exchange, GatewayLog gatewayLog) {
        ServerHttpResponse response = exchange.getResponse();
        DataBufferFactory bufferFactory = response.bufferFactory();

        return new ServerHttpResponseDecorator(response) {
            @Override
            public Mono<Void> writeWith(Publisher<? extends DataBuffer> body) {
                if (body instanceof Flux) {
                    Date responseTime = new Date();
                    gatewayLog.setEndTime(responseTime.getTime());
                    // 執(zhí)行時(shí)間
                    long executeTime = (responseTime.getTime() - gatewayLog.getStartTime());
                    gatewayLog.setExecuteTime(executeTime);
                    gatewayLog.setStatus(response.getStatusCode().value() == 200 ? "成功" : "失敗");
                    // 獲取響應(yīng)類型json
                    String originalResponseContentType = exchange.getAttribute(ServerWebExchangeUtils.ORIGINAL_RESPONSE_CONTENT_TYPE_ATTR);

                    if (Objects.equals(this.getStatusCode(), HttpStatus.OK) && StringUtils.isNotBlank(originalResponseContentType)
                            && originalResponseContentType.contains(MediaType.APPLICATION_JSON_VALUE)) {
                        Flux<? extends DataBuffer> fluxBody = Flux.from(body);
                        return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
                            // 合并多個(gè)流集合,解決返回體分段傳輸
                            DataBufferFactory dataBufferFactory = new DefaultDataBufferFactory();
                            DataBuffer join = dataBufferFactory.join(dataBuffers);
                            byte[] content = new byte[join.readableByteCount()];
                            join.read(content);
                            // 釋放掉內(nèi)存
                            DataBufferUtils.release(join);
                            String responseResult = new String(content, StandardCharsets.UTF_8);
                            gatewayLog.setResponseData(responseResult);
                            return bufferFactory.wrap(content);
                        }));
                    }
                }
                // if body is not a flux. never got there.
                return super.writeWith(body);
            }
        };
    }
}

方式二 通過(guò)AdaptCachedBodyGlobalFilter實(shí)現(xiàn)請(qǐng)求體緩存

@Component
@RequiredArgsConstructor
public class GatewayCommonConfig{ 
    private final GatewayProperties gatewayProperties;
    private final ApplicationContext applicationContext;

    @PostConstruct
    public void init(){
        //發(fā)布對(duì)應(yīng)路由的EnableBodyCachingEvent事件
        gatewayProperties.getRoutes().forEach(e->{
            EnableBodyCachingEvent enableBodyCachingEvent = new EnableBodyCachingEvent(new Object(), e.getId());
            //發(fā)布事件
            applicationContext.publishEvent(enableBodyCachingEvent);
        });
    }
}

然后 就可以在自定義的攔截器中通過(guò)request.getBody()獲取請(qǐng)求體了文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-665352.html

方式一參考鏈接:

方式一參考鏈接:

方式二參考鏈接:

到了這里,關(guān)于SpringCloud GateWay網(wǎng)關(guān)通過(guò)全局?jǐn)r截器GlobalFilter實(shí)現(xiàn)API日志的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 登錄用戶信息獲取 網(wǎng)關(guān)+攔截器+feign請(qǐng)求添加請(qǐng)求頭

    登錄用戶信息獲取 網(wǎng)關(guān)+攔截器+feign請(qǐng)求添加請(qǐng)求頭

    給所有請(qǐng)求添加用戶身份 網(wǎng)關(guān)已經(jīng)給所有請(qǐng)求添加了用戶身份,也就是authorization頭信息。 ? 創(chuàng)建ThreadLocal工具類 : 創(chuàng)建攔截器:? 將攔截器注冊(cè)到SpringMvc,讓它生效: ?將以上代碼(攔截器,config,utils) 放到哪個(gè)微服務(wù)中,哪個(gè)微服務(wù)/**路徑就會(huì)有攔截功能 沒(méi)有用戶信息的請(qǐng)求將會(huì)

    2024年02月09日
    瀏覽(18)
  • UniApp 封裝全局請(qǐng)求示例并配置攔截器以及錯(cuò)誤回調(diào)指南

    本文將介紹如何在 UniApp 中封裝全局請(qǐng)求示例,并配置請(qǐng)求攔截器和錯(cuò)誤回調(diào)函數(shù),以便統(tǒng)一處理網(wǎng)絡(luò)請(qǐng)求、添加請(qǐng)求頭、處理錯(cuò)誤等功能。通過(guò)本指南,你將學(xué)習(xí)如何優(yōu)化請(qǐng)求流程并提高代碼的可維護(hù)性。 首先,確保你已經(jīng)創(chuàng)建了一個(gè) UniApp 項(xiàng)目。 在項(xiàng)目的根目錄下創(chuàng)建一

    2024年02月08日
    瀏覽(23)
  • vue全家桶進(jìn)階之路46:Vue3 Axios攔截器和globalProperties全局設(shè)置

    在Vue.js 3中,使用Axios與Vue.js 2.x中類似,但是需要進(jìn)行一些修改和更新,下面是Vue.js 3中Axios的定義和使用方式: 首先,你需要安裝Axios和Vue.js 3.x,可以使用npm或yarn等包管理工具安裝: 然后,在你的Vue.js 3應(yīng)用程序中,你可以使用以下代碼來(lái)導(dǎo)入和使用Axios: 上面的代碼使用

    2023年04月20日
    瀏覽(21)
  • Spring MVC學(xué)習(xí)隨筆-Ajax集成(JSON格式返回?cái)?shù)據(jù))、攔截器(MyInterceptor)、全局異常處理(GlobalExceptionResolver)

    Spring MVC學(xué)習(xí)隨筆-Ajax集成(JSON格式返回?cái)?shù)據(jù))、攔截器(MyInterceptor)、全局異常處理(GlobalExceptionResolver)

    學(xué)習(xí)視頻:【編程不良人】繼spring之后快速入門springmvc,面對(duì)SpringMVC不用慌 引入相關(guān)依賴 開(kāi)發(fā)控制器 日期格式修正 可以正常響應(yīng) 攔截器 :Interceptor 攔截 中斷 類似于javaweb中的Filter,不過(guò)沒(méi)有Filter那么強(qiáng)大 作用 Spring MVC的攔截器是一種用于在請(qǐng)求處理過(guò)程中進(jìn)行預(yù)處理和后處

    2024年02月05日
    瀏覽(23)
  • GateWay自定義網(wǎng)關(guān)全局?jǐn)r截

    在com.xxxxa.gateway.filter包下創(chuàng)建 是在網(wǎng)關(guān)下面操作: 網(wǎng)關(guān)的包里創(chuàng)建: 定義方式是非常簡(jiǎn)單,只需實(shí)現(xiàn) GlobalFilter 接口 —————————————————————————————————————————————— 在filter中編寫自定義邏輯,可以實(shí)現(xiàn)下列功能: 登

    2024年02月10日
    瀏覽(17)
  • 數(shù)據(jù)權(quán)限攔截器,多租戶攔截器

    WEB類型軟件產(chǎn)品,在Java(SpringBoot)+MybatisPlus架構(gòu)場(chǎng)景下,本文針對(duì)下面兩個(gè)問(wèn)題,提供解決方案: 多租戶的產(chǎn)品,想在表內(nèi)級(jí)別上,實(shí)現(xiàn)租戶數(shù)據(jù)隔離(分表、分庫(kù)方案不在本文討論范圍內(nèi))。 ToB、ToG類型的軟件產(chǎn)品,需要實(shí)現(xiàn)數(shù)據(jù)權(quán)限鑒權(quán)。例如用戶數(shù)據(jù)、部門數(shù)據(jù)、租戶

    2024年02月02日
    瀏覽(27)
  • SpringCloud GateWay 在全局過(guò)濾器中注入OpenFeign網(wǎng)關(guān)后無(wú)法啟動(dòng)

    SpringCloud GateWay 在全局過(guò)濾器中注入OpenFeign網(wǎng)關(guān)后無(wú)法啟動(dòng)

    目錄 一、問(wèn)題 二、原因 1、修改配置 2、添加@Lazy注解在client上面 ?3、啟動(dòng)成功 當(dāng)在gateway的全局過(guò)濾器GlobalFilter中注入OpenFeign接口的時(shí)候會(huì)一直卡在路由中,但是不會(huì)進(jìn)一步,導(dǎo)致啟動(dòng)未成功也未報(bào)錯(cuò)失敗 在gateway網(wǎng)關(guān)中不能使用openfeign同步調(diào)用 三、解決方法 在注入的Aut

    2024年01月19日
    瀏覽(20)
  • SpringBoot加入攔截器——登錄攔截器的實(shí)現(xiàn)

    SpringBoot加入攔截器——登錄攔截器的實(shí)現(xiàn)

    ? ? ? ? 攔截器 Interceptor 在 Spring MVC 中的地位等同于 Servlet 規(guī)范中的過(guò)濾器 Filter,攔截的是處理器的執(zhí)行,由于是全局行為,因此常用于做一些通用的功能,如請(qǐng)求日志打印、權(quán)限控制等。 ? ? ? ? 核心原理:AOP思想 preHandle:? 預(yù)先處理,在目標(biāo)的controller方法執(zhí)行之前,進(jìn)行

    2024年02月15日
    瀏覽(19)
  • VUE3 請(qǐng)求攔截器 響應(yīng)攔截器

    1,導(dǎo)入axios? (使用axios進(jìn)行接口的請(qǐng)求,頁(yè)面發(fā)送http請(qǐng)求,很多情況我們要對(duì)請(qǐng)求和其響應(yīng)進(jìn)行特定的處理,如:判斷token,設(shè)置請(qǐng)求頭。如果請(qǐng)求數(shù)非常多,單獨(dú)對(duì)每一個(gè)請(qǐng)求進(jìn)行處理會(huì)變得非常麻煩,程序的優(yōu)雅性也會(huì)大打折扣。所以axios為開(kāi)發(fā)者提供了這樣一個(gè)API:攔

    2024年02月16日
    瀏覽(25)
  • 自定義注解與攔截器實(shí)現(xiàn)不規(guī)范sql攔截(攔截器實(shí)現(xiàn)篇)

    自定義注解與攔截器實(shí)現(xiàn)不規(guī)范sql攔截(攔截器實(shí)現(xiàn)篇)

    最近考慮myBatis中sql語(yǔ)句使用規(guī)范的問(wèn)題,如果漏下條件或者寫一些不規(guī)范語(yǔ)句會(huì)對(duì)程序性能造成很大影響。最好的方法就是利用代碼進(jìn)行限制,通過(guò)攔截器進(jìn)行sql格式的判斷在自測(cè)環(huán)節(jié)就能找到問(wèn)題。寫了個(gè)簡(jiǎn)單情景下的demo,并通過(guò)idea插件來(lái)將myBatis的mapper方法都打上攔截器

    2024年01月22日
    瀏覽(29)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包