欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringCloud Open feign 使用okhttp 優(yōu)化詳解

 更新時(shí)間:2021年02月25日 10:08:51   作者:漲知識(shí)的coder  
這篇文章主要介紹了SpringCloud Open feign 使用okhttp 優(yōu)化詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

我就廢話不多說(shuō)了,大家還是直接看代碼吧~

<!--web 模塊 -->
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
   <exclusions>
    <!--排除tomcat依賴 -->
    <exclusion>
     <artifactId>spring-boot-starter-tomcat</artifactId>
     <groupId>org.springframework.boot</groupId>
    </exclusion>
   </exclusions>
  </dependency>
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-aop</artifactId>
  </dependency>
  <!--undertow容器 -->
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-undertow</artifactId>
  </dependency>
  <!-- feign-okhttp -->
  <dependency>
   <groupId>io.github.openfeign</groupId>
   <artifactId>feign-okhttp</artifactId>
  </dependency>

配置pom,容器使用undertow,引入feign-okhttp

feign: 
# Okhttp參數(shù)配置
 httpclient:
 enabled: false
 okhttp:
 enabled: true
 max-connections: 200 # 默認(rèn)值
 max-connections-per-route: 50 # 默認(rèn)值

application.yml文件配置okhttp參數(shù)

import feign.Feign;
import okhttp3.ConnectionPool;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.cloud.openfeign.FeignAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;
@Configuration
@ConditionalOnClass(Feign.class)
@AutoConfigureBefore(FeignAutoConfiguration.class)
public class FeignOkHttpConfig {
 @Bean
 public okhttp3.OkHttpClient okHttpClient(){
  return new okhttp3.OkHttpClient.Builder()
    //設(shè)置連接超時(shí)
    .connectTimeout(60, TimeUnit.SECONDS)
    //設(shè)置讀超時(shí)
    .readTimeout(60, TimeUnit.SECONDS)
    //設(shè)置寫(xiě)超時(shí)
    .writeTimeout(120,TimeUnit.SECONDS)
    //是否自動(dòng)重連
    .retryOnConnectionFailure(true)
    .connectionPool(new ConnectionPool())
    .addInterceptor(new OkHttpLogInterceptor())
    //構(gòu)建OkHttpClient對(duì)象
    .build();
 }
}

創(chuàng)建FeignOkHttpConfig類文件

import lombok.extern.log4j.Log4j2;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import java.io.IOException;
@Log4j2
public class OkHttpLogInterceptor implements Interceptor {
 @Override
 public Response intercept(Interceptor.Chain chain) throws IOException {
  //這個(gè)chain里面包含了request和response,所以你要什么都可以從這里拿
  Request request = chain.request();
  long t1 = System.nanoTime();//請(qǐng)求發(fā)起的時(shí)間
  log.info(String.format("發(fā)送請(qǐng)求 %s on %s%n%s",
    request.url(), chain.connection(), request.headers()));
  Response response = chain.proceed(request);
  long t2 = System.nanoTime();//收到響應(yīng)的時(shí)間
  //這里不能直接使用response.body().string()的方式輸出日志
  //因?yàn)閞esponse.body().string()之后,response中的流會(huì)被關(guān)閉,程序會(huì)報(bào)錯(cuò),我們需要?jiǎng)?chuàng)建出一
  //個(gè)新的response給應(yīng)用層處理
  ResponseBody responseBody = response.peekBody(1024 * 1024);
  log.info(String.format("接收響應(yīng): [%s] %n返回json:【%s】 %.1fms%n%s",
    response.request().url(),
    responseBody.string(),
    (t2 - t1) / 1e6d,
    response.headers()));
  return response;
 }
}

創(chuàng)建OkHttpLogInterceptor日志攔截文件

注意FeignOkHttpConfig中添加

 @Bean
 public Contract feignContract() {
  return new feign.Contract.Default();
 }

feigin請(qǐng)求的@PostMapping @GetMapping等會(huì)不受支持

圖一,使用默認(rèn)http

圖一,F(xiàn)eign通過(guò)jdk中的HttpURLConnection

圖二,F(xiàn)eign使用okhttp請(qǐng)求

補(bǔ)充:Feign、httpclient、OkHttp3 結(jié)合使用

1 Feign 客戶端實(shí)現(xiàn) 類型

前面介紹到了常用的Feign客戶端實(shí)現(xiàn)類,大致如下:

(1) Client.Default類:默認(rèn)的 feign.Client 客戶端實(shí)現(xiàn)類,內(nèi)部使用HttpURLConnnection 完成HTTP URL請(qǐng)求處理;

(2) ApacheHttpClient 類:內(nèi)部使用 Apache httpclient 開(kāi)源組件完成HTTP URL請(qǐng)求處理的feign.Client 客戶端實(shí)現(xiàn)類;

(3) OkHttpClient類:內(nèi)部使用 OkHttp3 開(kāi)源組件完成HTTP URL請(qǐng)求處理的feign.Client 客戶端實(shí)現(xiàn)類。

(4) LoadBalancerFeignClient 類:這是一個(gè)特殊的 feign.Client 客戶端實(shí)現(xiàn)類。內(nèi)部先使用 Ribbon 負(fù)載均衡算法計(jì)算server服務(wù)器,然后使用包裝的 delegate 客戶端實(shí)例,去完成 HTTP URL請(qǐng)求處理。

Feign 在啟動(dòng)的時(shí)候,有兩個(gè)與feign.Client 客戶端實(shí)例相關(guān)的自動(dòng)配置類,根據(jù)多種條件組合,去創(chuàng)建不同類型的 客戶端Spring IOC容器實(shí)例。

1.1.1 配置 LoadBalancerFeignClient 負(fù)載均衡容器實(shí)例

Feign有兩個(gè)與Client相關(guān)的自動(dòng)配置類:

(1)org.springframework.cloud.openfeign.ribbon.FeignRibbonClientAutoConfiguration

(2)org.springframework.cloud.openfeign.FeignAutoConfiguration

第一個(gè)自動(dòng)配置類,能夠配置具有負(fù)載均衡能力的FeignClient容器實(shí)例;第二自動(dòng)配置類,只能配置最原始的FeignClient容器實(shí)例。

具備負(fù)載均衡能力的 FeignClient 容器實(shí)例,所對(duì)應(yīng)的類型為 LoadBalancerFeignClient 類型。前面講到,在SpringCloud中,為了達(dá)到高可用,一個(gè)微服務(wù)至少應(yīng)該部署兩個(gè)以上節(jié)點(diǎn),從這個(gè)角度來(lái)說(shuō),LoadBalancerFeignClient 容器實(shí)例,已經(jīng)成為事實(shí)上的標(biāo)配。

事實(shí)上,第一個(gè)自動(dòng)配置類 FeignRibbonClientAutoConfiguration,在容器的裝配次序上,是優(yōu)先于第二個(gè)自動(dòng)配置類 FeignAutoConfiguration 的。具體可以參見(jiàn)其源碼,節(jié)選如下:

import com.netflix.loadbalancer.ILoadBalancer;
//….
@ConditionalOnClass({ILoadBalancer.class, Feign.class})
@Configuration
@AutoConfigureBefore({FeignAutoConfiguration.class}) // 本配置類具備優(yōu)先權(quán)
@EnableConfigurationProperties({FeignHttpClientProperties.class})
@Import({
HttpClientFeignLoadBalancedConfiguration.class, //配置:包裝ApacheHttpClient實(shí)例的負(fù)載均衡客戶端
OkHttpFeignLoadBalancedConfiguration.class, //配置:包裝OkHttpClient 實(shí)例的負(fù)載均衡客戶端
DefaultFeignLoadBalancedConfiguration.class //配置:包裝Client.Default 實(shí)例的負(fù)載均衡客戶端
})
public class FeignRibbonClientAutoConfiguration {
 //空的構(gòu)造器
 public FeignRibbonClientAutoConfiguration() {
 }
//….
}

從源碼中可以看到,F(xiàn)eignRibbonClientAutoConfiguration 的自動(dòng)配置有兩個(gè)前提條件:

(1)當(dāng)前的類路徑中,存在 ILoadBalancer.class 接口

(2)當(dāng)前的類路徑中,存在 Feign.class 接口

在這里,重點(diǎn)說(shuō)一下 ILoadBalancer.class 接口,該接口處于 ribbon 的jar包中。如果需要在類路徑中導(dǎo)入該jar包,則需要在Maven的pom.xml文件中,增加 ribbon 的相關(guān)依賴,具體如下:

  <!-- ribbon-->
  <dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
  </dependency>

為了加深大家對(duì)客戶端負(fù)載均衡的理解,這里將 ILoadBalancer.class 接口的兩個(gè)重要的抽象方法列出來(lái),具體如下:

package com.netflix.loadbalancer;
import java.util.List;
public interface ILoadBalancer {
 // 通過(guò)負(fù)載均衡算法計(jì)算server服務(wù)器
Server chooseServer(Object var1);
// 取得全部的服務(wù)器
List<Server> getAllServers();
//…
}

FeignRibbonClientAutoConfiguration 自動(dòng)配置類,并沒(méi)有直接配置LoadBalancerFeignClient 容器實(shí)例,而是使用@Import注解,通過(guò)導(dǎo)入其他配置類的方式,完成 LoadBalancerFeignClient 客戶端容器實(shí)例的配置。

分別導(dǎo)入了以下三個(gè)自動(dòng)配置類:

(1) HttpClientFeignLoadBalancedConfiguration.class

該配置類,負(fù)責(zé)配置一個(gè)包裝 ApacheHttpClient 實(shí)例的 LoadBalancerFeignClient負(fù)載均衡客戶端。

(2) OkHttpFeignLoadBalancedConfiguration.class

該配置類,負(fù)責(zé)配置一個(gè)包裝 OkHttpClient 實(shí)例的 LoadBalancerFeignClient負(fù)載均衡客戶端。

(3) DefaultFeignLoadBalancedConfiguration.class

該配置類,負(fù)責(zé)配置一個(gè)包裝 Client.Default 實(shí)例的 LoadBalancerFeignClient負(fù)載均衡客戶端。

1.1.2 包裝 ApacheHttpClient 實(shí)例的負(fù)載均衡容器實(shí)例

首先來(lái)看如何配置一個(gè)包裝 ApacheHttpClient 實(shí)例的負(fù)載均衡容器實(shí)例。這個(gè)IOC實(shí)例的配置,由 HttpClientFeignLoadBalancedConfiguration 自動(dòng)配置類完成的,其源碼節(jié)選如下:

@Configuration
@ConditionalOnClass({ApacheHttpClient.class})
@ConditionalOnProperty(
 value = {"feign.httpclient.enabled"},
 matchIfMissing = true
)
class HttpClientFeignLoadBalancedConfiguration {
 //空的構(gòu)造器
 HttpClientFeignLoadBalancedConfiguration() {
 }
 @Bean
 @ConditionalOnMissingBean({Client.class})
public Client feignClient(
CachingSpringLoadBalancerFactory cachingFactory,
SpringClientFactory clientFactory, HttpClient httpClient) 
{
  ApacheHttpClient delegate = new ApacheHttpClient(httpClient);
  return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory); // 進(jìn)行包裝
 }
//…省略不相干的代碼
}

首先,來(lái)看源碼中的 feignClient(…)方法,分為兩步:

(1)創(chuàng)建一個(gè) ApacheHttpClient 類型的 feign.Client客戶端實(shí)例,該實(shí)例的內(nèi)部使用 Apache httpclient 開(kāi)源組件完成HTTP URL請(qǐng)求處理;

(2)創(chuàng)建一個(gè) LoadBalancerFeignClient 負(fù)載均衡客戶端實(shí)例,將 ApacheHttpClient 實(shí)例包裝起來(lái),然后返回LoadBalancerFeignClient 客戶端實(shí)例,作為 feign.Client 類型的Spring IOC 容器實(shí)例。

然后,再看類 HttpClientFeignLoadBalancedConfiguration 上的兩個(gè)重要的注解:

(1)@ConditionalOnClass(ApacheHttpClient.class)

(2)@ConditionalOnProperty(value = “feign.httpclient.enabled”, matchIfMissing = true)

這兩個(gè)條件的含義為:

(1)必須滿足 ApacheHttpClient.class 在當(dāng)前類路徑中存在;

(2)必須滿足工程配置文件中 feign.httpclient.enabled 配置項(xiàng)的值為 true ;

如果以上兩個(gè)條件同時(shí)滿足,則 HttpClientFeignLoadBalancedConfiguration 自動(dòng)配置工作就會(huì)啟動(dòng)。

如何驗(yàn)證呢?

首先在工程配置文件中,將配置項(xiàng) feign.httpclient.enabled 的值,設(shè)置為 false 。

然后,在 HttpClientFeignLoadBalancedConfiguration 的 feignClient(…)方法內(nèi)的某行打上斷點(diǎn),重新啟動(dòng)項(xiàng)目,注意觀察會(huì)發(fā)現(xiàn),整個(gè)啟動(dòng)過(guò)程中,斷點(diǎn)沒(méi)有被命中。

接下來(lái),將配置項(xiàng) feign.httpclient.enabled 的值設(shè)置為 true,再一次啟動(dòng)項(xiàng)目,斷點(diǎn)被命中。由此,可以驗(yàn)證 HttpClientFeignLoadBalancedConfiguration 自動(dòng)配置類被啟動(dòng)。

為了滿足 @ConditionalOnClass(ApacheHttpClient.class) 的條件要求,由于ApacheHttpClient類的位置處于feign-httpclient相關(guān)的jar包中,所以,需要在pom文件加上 feign-httpclient 以及httpclient 組件相關(guān)的 Maven 依賴,具體如下:

 <dependency>
   <groupId>io.github.openfeign</groupId>
   <artifactId>feign-httpclient</artifactId>
   <version>9.5.1</version>
   <!--<version>${feign-httpclient.version}</version>-->
  </dependency>
<dependency>
 <groupId>org.apache.httpcomponents</groupId>
 <artifactId>httpclient</artifactId>
 <version>${httpclient.version}</version>
 </dependency>

對(duì)于 feign.httpclient.enabled 配置項(xiàng)設(shè)置,根據(jù) @ConditionalOnProperty 注解的屬性matchIfMissing=true 可知,這個(gè)可以不用配置,在默認(rèn)的情況下就為 true。換句話說(shuō),如果不做特別的配置,feign.httpclient.enabled 配置項(xiàng)的值,默認(rèn)為 true。

1.1.3 包裝 OkHttpClient 實(shí)例的負(fù)載均衡容器實(shí)例

接下來(lái),來(lái)看如何配置一個(gè)包裝 OkHttpClient 實(shí)例的負(fù)載均衡容器實(shí)例。這個(gè)IOC實(shí)例的配置,由 OkHttpFeignLoadBalancedConfiguration 自動(dòng)配置類完成的,其源碼節(jié)選如下:

@Configuration
@ConditionalOnClass({OkHttpClient.class})
@ConditionalOnProperty("feign.okhttp.enabled")
class OkHttpFeignLoadBalancedConfiguration {
 //空的構(gòu)造器
 OkHttpFeignLoadBalancedConfiguration () {
 }
 @Bean
 @ConditionalOnMissingBean({Client.class})
public Client feignClient(
CachingSpringLoadBalancerFactory cachingFactory,
SpringClientFactory clientFactory, HttpClient httpClient) 
{
  OkHttpClient delegate = new OkHttpClient (httpClient);
  return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory); // 進(jìn)行包裝
 }
//…省略不相干的代碼
}

首先,來(lái)看源碼中的 feignClient(…)方法,分為兩步:

(1)創(chuàng)建一個(gè) OkHttpClient 類型的 feign.Client客戶端實(shí)例,該實(shí)例的內(nèi)部使用 OkHttp3 開(kāi)源組件完成HTTP URL請(qǐng)求處理;

(2)創(chuàng)建一個(gè) LoadBalancerFeignClient 負(fù)載均衡客戶端實(shí)例,將 OkHttpClient實(shí)例包裝起來(lái),然后返回LoadBalancerFeignClient 客戶端實(shí)例,作為 feign.Client 類型的Spring IOC 容器實(shí)例。

然后,再看類 OkHttpFeignLoadBalancedConfiguration 上的兩個(gè)重要的注解:

(1)@ConditionalOnClass(OkHttpClient.class)

(2)@ConditionalOnProperty(“feign.okhttp.enabled”)

這兩個(gè)條件的含義為:

(1)必須滿足 OkHttpClient.class 在當(dāng)前類路徑中存在;

(2)必須滿足工程配置文件中 feign.okhttp.enabled 配置項(xiàng)的值為 true 。

如果以上兩個(gè)條件同時(shí)滿足,則 OkHttpFeignLoadBalancedConfiguration 自動(dòng)配置工作就會(huì)啟動(dòng)。

為了滿足 @ConditionalOnClass(OkHttpClient.class) 的條件要求,由于OkHttpClient.class 類的位置處于 feign-okhttp 相關(guān)的jar包中,所以,需要在pom文件加上 feign-okhttp 以及 okhttp3 相關(guān)的 Maven 依賴。具體如下:

<!-- OkHttp -->
<dependency>
 <groupId>com.squareup.okhttp3</groupId>
 <artifactId>okhttp</artifactId>
</dependency>
<!-- feign-okhttp -->
<dependency>
 <groupId>io.github.openfeign</groupId>
 <artifactId>feign-okhttp</artifactId>
</dependency>

對(duì)于 feign.okhttp.enabled 配置項(xiàng)設(shè)置,在默認(rèn)的情況下就為 false。也就是說(shuō),如果需要使用feign-okhttp,則一定需要做特別的配置,在工程配置文件中,加上 feign.okhttp.enabled 配置項(xiàng)的值,并且值必須為 true。

如果需要使用 feign-okhttp,工程配置文件的配置項(xiàng)大致如下:

feign.httpclient.enabled=false
feign.okhttp.enabled=true

1.1.4 包裝 Client.Default 客戶端實(shí)例的負(fù)載均衡容器實(shí)例

最后,來(lái)看如何配置一個(gè)包裝默認(rèn)Client.Default 客戶端實(shí)例的負(fù)載均衡容器實(shí)例。這個(gè)IOC實(shí)例的配置,由 DefaultFeignLoadBalancedConfiguration 自動(dòng)配置類所完成的。該配置類,也就是 FeignRibbonClientAutoConfiguration 配置類通過(guò) @import 注解所導(dǎo)入的第3個(gè)配置類。

DefaultFeignLoadBalancedConfiguration 的源碼節(jié)選如下:

package org.springframework.cloud.openfeign.ribbon;
//…省略import
@Configuration
class DefaultFeignLoadBalancedConfiguration {
 DefaultFeignLoadBalancedConfiguration() {
 }
 @Bean
 @ConditionalOnMissingBean
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
 SpringClientFactory clientFactory)
 {
  return new LoadBalancerFeignClient(
new Default((SSLSocketFactory)null,
 (HostnameVerifier)null), cachingFactory, clientFactory);
 }
}

通過(guò)源碼可以看出,如果前面的兩個(gè)配置類的條件沒(méi)有滿足,feign.Client 的 IOC 容器實(shí)例沒(méi)有裝配,則:

(1) 創(chuàng)建一個(gè) Client.Default 默認(rèn)客戶端實(shí)例,該實(shí)例的內(nèi)部,使用HttpURLConnnection 完成URL請(qǐng)求處理;

(2) 創(chuàng)建一個(gè) LoadBalancerFeignClient 負(fù)載均衡客戶端實(shí)例,將 Client.Default 實(shí)例包裝起來(lái),然后返回LoadBalancerFeignClient 客戶端實(shí)例,作為 feign.Client 類型的Spring IOC 容器實(shí)例。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • SpringBoot創(chuàng)建Docker鏡像的方法步驟

    SpringBoot創(chuàng)建Docker鏡像的方法步驟

    這篇文章主要介紹了SpringBoot創(chuàng)建Docker鏡像的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • java二叉樹(shù)的數(shù)據(jù)插入算法介紹

    java二叉樹(shù)的數(shù)據(jù)插入算法介紹

    大家好,本篇文章主要講的是java二叉樹(shù)的數(shù)據(jù)插入算法介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • Java用?Gradle配置compile及implementation和api的區(qū)別

    Java用?Gradle配置compile及implementation和api的區(qū)別

    這篇文章主要介紹了Java用Gradle配置compile及implementation和api的區(qū)別,文章圍繞主題的相關(guān)資料展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-06-06
  • java實(shí)現(xiàn)水波紋擴(kuò)散效果

    java實(shí)現(xiàn)水波紋擴(kuò)散效果

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)水波紋擴(kuò)散效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • 詳解Spring中@Component和@Configuration的區(qū)別

    詳解Spring中@Component和@Configuration的區(qū)別

    一直有同學(xué)搞不清Spring中@Component和@Configuration這兩個(gè)注解有什么區(qū)別,所以這篇文章小編就給大家簡(jiǎn)單介紹一下@Component和@Configuration的區(qū)別,需要的朋友可以參考下
    2023-07-07
  • springboot項(xiàng)目啟動(dòng)的時(shí)候參數(shù)無(wú)效的解決

    springboot項(xiàng)目啟動(dòng)的時(shí)候參數(shù)無(wú)效的解決

    這篇文章主要介紹了springboot項(xiàng)目啟動(dòng)的時(shí)候參數(shù)無(wú)效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 詳解Java中Optional類的使用方法

    詳解Java中Optional類的使用方法

    Optional的作用是什么?他都有哪些方法?阿里規(guī)范點(diǎn)名說(shuō)盡量用Optional來(lái)避免空指針,那么什么場(chǎng)景用Optional?本篇文章圍繞這三點(diǎn)來(lái)進(jìn)行講解,感興趣的可以學(xué)習(xí)一下
    2022-05-05
  • SpringBoot中的Profile多環(huán)境配置方法

    SpringBoot中的Profile多環(huán)境配置方法

    這篇文章主要介紹了SpringBoot中的Profile多環(huán)境配置,SpringBoot提供了兩種多環(huán)境配置的方式,分別是使用profile文件進(jìn)行多環(huán)境配置以及使用@Profile注解進(jìn)行多環(huán)境配置,需要的朋友可以參考下
    2023-01-01
  • java堆排序原理與實(shí)現(xiàn)方法分析

    java堆排序原理與實(shí)現(xiàn)方法分析

    這篇文章主要介紹了java堆排序原理與實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了java堆排序的相關(guān)原理、實(shí)現(xiàn)方法與操作注意事項(xiàng),需要的朋友可以參考下
    2018-12-12
  • jfinal添加jcaptcha驗(yàn)證碼實(shí)現(xiàn)方法

    jfinal添加jcaptcha驗(yàn)證碼實(shí)現(xiàn)方法

    這篇文章主要介紹了jfinal的jcaptcha驗(yàn)證碼實(shí)現(xiàn)方法,大家參考使用吧
    2014-01-01

最新評(píng)論