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

selenium+java破解極驗(yàn)滑動(dòng)驗(yàn)證碼的示例代碼

 更新時(shí)間:2018年01月05日 10:04:45   作者:臥顏沉默  
本篇文章主要介紹了selenium+java破解極驗(yàn)滑動(dòng)驗(yàn)證碼的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

摘要

分析驗(yàn)證碼素材圖片混淆原理,并采用selenium模擬人拖動(dòng)滑塊過(guò)程,進(jìn)而破解驗(yàn)證碼。

人工驗(yàn)證的過(guò)程

1、打開(kāi)威鋒網(wǎng)注冊(cè)頁(yè)面

2、移動(dòng)鼠標(biāo)至小滑塊,一張完整的圖片會(huì)出現(xiàn)(如下圖1)

3、點(diǎn)擊鼠標(biāo)左鍵,圖片中間會(huì)出現(xiàn)一個(gè)缺塊(如下圖2)

4、移動(dòng)小滑塊正上方圖案至缺塊處

5、驗(yàn)證通過(guò)

selenium模擬驗(yàn)證的過(guò)程

  1. 加載威鋒網(wǎng)注冊(cè)頁(yè)面
  2. 下載圖片1和缺塊圖片2
  3. 根據(jù)兩張圖片的差異計(jì)算平移的距離x
  4. 模擬鼠標(biāo)點(diǎn)擊事件,點(diǎn)擊小滑塊向右移動(dòng)x
  5. 驗(yàn)證通過(guò)
  6. 詳細(xì)分析

1、打開(kāi)chrome瀏覽器控制臺(tái),會(huì)發(fā)現(xiàn)圖1所示的驗(yàn)證碼圖片并不是極驗(yàn)后臺(tái)返回的原圖。而是由多個(gè)div拼接而成(如下圖3)

通過(guò)圖片顯示div的style屬性可知,極驗(yàn)后臺(tái)把圖片進(jìn)行切割加錯(cuò)位處理。把素材圖片切割成10 * 58大小的52張小圖,再進(jìn)行錯(cuò)位處理。在網(wǎng)頁(yè)上顯示的時(shí)候,再通過(guò)css的background-position屬性對(duì)圖片進(jìn)行還原。以上的圖1和圖2都是經(jīng)過(guò)了這種處理。在這種情況下,使用selenium模擬驗(yàn)證是需要對(duì)下載的驗(yàn)證碼圖片進(jìn)行還原。如上圖3的第一個(gè)div.gt_cut_fullbg_slice標(biāo)簽,它的大小為10px * 58px,其中style屬性為background-image: url("http://static.geetest.com/pictures/gt/969ffa43c/969ffa43c.webp"); background-position: -157px -58px;會(huì)把該屬性對(duì)應(yīng)url的圖片進(jìn)行一個(gè)平移操作,以左上角為參考,向左平移157px,向上平移58px,圖片超出部分不會(huì)顯示。所以上圖1所示圖片是由26 * 2個(gè)10px * 58px大小的div組成(如下圖4)。每一個(gè)小方塊的大小58 * 10

2、下載圖片并還原,上一步驟分析了圖片具體的混淆邏輯,具體還原圖片的代碼實(shí)現(xiàn)如下,主要邏輯是把原圖裁剪為52張小圖,然后拼接成一張完整的圖。

/**
 *還原圖片
 * @param type
 */
private static void restoreImage(String type) throws IOException {
  //把圖片裁剪為2 * 26份
  for(int i = 0; i < 52; i++){
    cutPic(basePath + type +".jpg"
        ,basePath + "result/" + type + i + ".jpg", -moveArray[i][0], -moveArray[i][1], 10, 58);
  }
  //拼接圖片
  String[] b = new String[26];
  for(int i = 0; i < 26; i++){
    b[i] = String.format(basePath + "result/" + type + "%d.jpg", i);
  }
  mergeImage(b, 1, basePath + "result/" + type + "result1.jpg");
  //拼接圖片
  String[] c = new String[26];
  for(int i = 0; i < 26; i++){
    c[i] = String.format(basePath + "result/" + type + "%d.jpg", i + 26);
  }
  mergeImage(c, 1, basePath + "result/" + type + "result2.jpg");
  mergeImage(new String[]{basePath + "result/" + type + "result1.jpg",
      basePath + "result/" + type + "result2.jpg"}, 2, basePath + "result/" + type + "result3.jpg");
  //刪除產(chǎn)生的中間圖片
  for(int i = 0; i < 52; i++){
    new File(basePath + "result/" + type + i + ".jpg").deleteOnExit();
  }
  new File(basePath + "result/" + type + "result1.jpg").deleteOnExit();
  new File(basePath + "result/" + type + "result2.jpg").deleteOnExit();
}

還原過(guò)程需要注意的是,后臺(tái)返回錯(cuò)位的圖片是312 * 116大小的。而網(wǎng)頁(yè)上圖片div的大小是260 * 116。

3、計(jì)算平移距離,遍歷圖片的每一個(gè)像素點(diǎn),當(dāng)兩張圖的R、G、B之差的和大于255,說(shuō)明該點(diǎn)的差異過(guò)大,很有可能就是需要平移到該位置的那個(gè)點(diǎn),代碼如下。

BufferedImage fullBI = ImageIO.read(new File(basePath + "result/" + FULL_IMAGE_NAME + "result3.jpg"));
  BufferedImage bgBI = ImageIO.read(new File(basePath + "result/" + BG_IMAGE_NAME + "result3.jpg"));
  for (int i = 0; i < bgBI.getWidth(); i++){
    for (int j = 0; j < bgBI.getHeight(); j++) {
      int[] fullRgb = new int[3];
      fullRgb[0] = (fullBI.getRGB(i, j) & 0xff0000) >> 16;
      fullRgb[1] = (fullBI.getRGB(i, j) & 0xff00) >> 8;
      fullRgb[2] = (fullBI.getRGB(i, j) & 0xff);

      int[] bgRgb = new int[3];
      bgRgb[0] = (bgBI.getRGB(i, j) & 0xff0000) >> 16;
      bgRgb[1] = (bgBI.getRGB(i, j) & 0xff00) >> 8;
      bgRgb[2] = (bgBI.getRGB(i, j) & 0xff);
      if(difference(fullRgb, bgRgb) > 255){
        return i;
      }
    }
  }

4、模擬鼠標(biāo)移動(dòng)事件,這一步驟是最關(guān)鍵的步驟,極驗(yàn)驗(yàn)證碼后臺(tái)正是通過(guò)移動(dòng)滑塊的軌跡來(lái)判斷是否為機(jī)器所為。整個(gè)移動(dòng)軌跡的過(guò)程越隨機(jī)越好,我這里提供一種成功率較高的移動(dòng)算法,代碼如下。

  public static void move(WebDriver driver, WebElement element, int distance) throws InterruptedException {
    int xDis = distance + 11;
    System.out.println("應(yīng)平移距離:" + xDis);
    int moveX = new Random().nextInt(8) - 5;
    int moveY = 1;
    Actions actions = new Actions(driver);
    new Actions(driver).clickAndHold(element).perform();
    Thread.sleep(200);
    printLocation(element);
    actions.moveToElement(element, moveX, moveY).perform();
    System.out.println(moveX + "--" + moveY);
    printLocation(element);
    for (int i = 0; i < 22; i++){
      int s = 10;
      if (i % 2 == 0){
        s = -10;
      }
      actions.moveToElement(element, s, 1).perform();
      printLocation(element);
      Thread.sleep(new Random().nextInt(100) + 150);
    }

    System.out.println(xDis + "--" + 1);
    actions.moveByOffset(xDis, 1).perform();
    printLocation(element);
    Thread.sleep(200);
    actions.release(element).perform();
  }

完整代碼如下

package com.github.wycm;
import org.apache.commons.io.FileUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.openqa.selenium.By;
import org.openqa.selenium.Point;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;
import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.util.Iterator;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class GeettestCrawler {
  private static String basePath = "src/main/resources/";
  private static String FULL_IMAGE_NAME = "full-image";
  private static String BG_IMAGE_NAME = "bg-image";
  private static int[][] moveArray = new int[52][2];
  private static boolean moveArrayInit = false;
  private static String INDEX_URL = "https://passport.feng.com/?r=user/register";
  private static WebDriver driver;

  static {
    System.setProperty("webdriver.chrome.driver", "D:/dev/selenium/chromedriver_V2.30/chromedriver_win32/chromedriver.exe");
    if (!System.getProperty("os.name").toLowerCase().contains("windows")){
      System.setProperty("webdriver.chrome.driver", "/Users/wangyang/workspace/selenium/chromedriver_V2.30/chromedriver");
    }
    driver = new ChromeDriver();
  }

  public static void main(String[] args) throws InterruptedException {
    for (int i = 0; i < 10; i++){
      try {
        invoke();
      } catch (IOException e) {
        e.printStackTrace();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    driver.quit();
  }
  private static void invoke() throws IOException, InterruptedException {
    //設(shè)置input參數(shù)
    driver.get(INDEX_URL);

    //通過(guò)[class=gt_slider_knob gt_show]
    By moveBtn = By.cssSelector(".gt_slider_knob.gt_show");
    waitForLoad(driver, moveBtn);
    WebElement moveElemet = driver.findElement(moveBtn);
    int i = 0;
    while (i++ < 15){
      int distance = getMoveDistance(driver);
      move(driver, moveElemet, distance - 6);
      By gtTypeBy = By.cssSelector(".gt_info_type");
      By gtInfoBy = By.cssSelector(".gt_info_content");
      waitForLoad(driver, gtTypeBy);
      waitForLoad(driver, gtInfoBy);
      String gtType = driver.findElement(gtTypeBy).getText();
      String gtInfo = driver.findElement(gtInfoBy).getText();
      System.out.println(gtType + "---" + gtInfo);
      /**
       * 再來(lái)一次:
       * 驗(yàn)證失?。?
       */
      if(!gtType.equals("再來(lái)一次:") && !gtType.equals("驗(yàn)證失敗:")){
        Thread.sleep(4000);
        System.out.println(driver);
        break;
      }
      Thread.sleep(4000);
    }
  }

  /**
   * 移動(dòng)
   * @param driver
   * @param element
   * @param distance
   * @throws InterruptedException
   */
  public static void move(WebDriver driver, WebElement element, int distance) throws InterruptedException {
    int xDis = distance + 11;
    System.out.println("應(yīng)平移距離:" + xDis);
    int moveX = new Random().nextInt(8) - 5;
    int moveY = 1;
    Actions actions = new Actions(driver);
    new Actions(driver).clickAndHold(element).perform();
    Thread.sleep(200);
    printLocation(element);
    actions.moveToElement(element, moveX, moveY).perform();
    System.out.println(moveX + "--" + moveY);
    printLocation(element);
    for (int i = 0; i < 22; i++){
      int s = 10;
      if (i % 2 == 0){
        s = -10;
      }
      actions.moveToElement(element, s, 1).perform();
//      printLocation(element);
      Thread.sleep(new Random().nextInt(100) + 150);
    }

    System.out.println(xDis + "--" + 1);
    actions.moveByOffset(xDis, 1).perform();
    printLocation(element);
    Thread.sleep(200);
    actions.release(element).perform();
  }
  private static void printLocation(WebElement element){
    Point point = element.getLocation();
    System.out.println(point.toString());
  }
  /**
   * 等待元素加載,10s超時(shí)
   * @param driver
   * @param by
   */
  public static void waitForLoad(final WebDriver driver, final By by){
    new WebDriverWait(driver, 10).until(new ExpectedCondition<Boolean>() {
      public Boolean apply(WebDriver d) {
        WebElement element = driver.findElement(by);
        if (element != null){
          return true;
        }
        return false;
      }
    });
  }

  /**
   * 計(jì)算需要平移的距離
   * @param driver
   * @return
   * @throws IOException
   */
  public static int getMoveDistance(WebDriver driver) throws IOException {
    String pageSource = driver.getPageSource();
    String fullImageUrl = getFullImageUrl(pageSource);
    FileUtils.copyURLToFile(new URL(fullImageUrl), new File(basePath + FULL_IMAGE_NAME + ".jpg"));
    String getBgImageUrl = getBgImageUrl(pageSource);
    FileUtils.copyURLToFile(new URL(getBgImageUrl), new File(basePath + BG_IMAGE_NAME + ".jpg"));
    initMoveArray(driver);
    restoreImage(FULL_IMAGE_NAME);
    restoreImage(BG_IMAGE_NAME);
    BufferedImage fullBI = ImageIO.read(new File(basePath + "result/" + FULL_IMAGE_NAME + "result3.jpg"));
    BufferedImage bgBI = ImageIO.read(new File(basePath + "result/" + BG_IMAGE_NAME + "result3.jpg"));
    for (int i = 0; i < bgBI.getWidth(); i++){
      for (int j = 0; j < bgBI.getHeight(); j++) {
        int[] fullRgb = new int[3];
        fullRgb[0] = (fullBI.getRGB(i, j) & 0xff0000) >> 16;
        fullRgb[1] = (fullBI.getRGB(i, j) & 0xff00) >> 8;
        fullRgb[2] = (fullBI.getRGB(i, j) & 0xff);

        int[] bgRgb = new int[3];
        bgRgb[0] = (bgBI.getRGB(i, j) & 0xff0000) >> 16;
        bgRgb[1] = (bgBI.getRGB(i, j) & 0xff00) >> 8;
        bgRgb[2] = (bgBI.getRGB(i, j) & 0xff);
        if(difference(fullRgb, bgRgb) > 255){
          return i;
        }
      }
    }
    throw new RuntimeException("未找到需要平移的位置");
  }
  private static int difference(int[] a, int[] b){
    return Math.abs(a[0] - b[0]) + Math.abs(a[1] - b[1]) + Math.abs(a[2] - b[2]);
  }
  /**
   * 獲取move數(shù)組
   * @param driver
   */
  private static void initMoveArray(WebDriver driver){
    if (moveArrayInit){
      return;
    }
    Document document = Jsoup.parse(driver.getPageSource());
    Elements elements = document.select("[class=gt_cut_bg gt_show]").first().children();
    int i = 0;
    for(Element element : elements){
      Pattern pattern = Pattern.compile(".*background-position: (.*?)px (.*?)px.*");
      Matcher matcher = pattern.matcher(element.toString());
      if (matcher.find()){
        String width = matcher.group(1);
        String height = matcher.group(2);
        moveArray[i][0] = Integer.parseInt(width);
        moveArray[i++][1] = Integer.parseInt(height);
      } else {
        throw new RuntimeException("解析異常");
      }
    }
    moveArrayInit = true;
  }
  /**
   *還原圖片
   * @param type
   */
  private static void restoreImage(String type) throws IOException {
    //把圖片裁剪為2 * 26份
    for(int i = 0; i < 52; i++){
      cutPic(basePath + type +".jpg"
          ,basePath + "result/" + type + i + ".jpg", -moveArray[i][0], -moveArray[i][1], 10, 58);
    }
    //拼接圖片
    String[] b = new String[26];
    for(int i = 0; i < 26; i++){
      b[i] = String.format(basePath + "result/" + type + "%d.jpg", i);
    }
    mergeImage(b, 1, basePath + "result/" + type + "result1.jpg");
    //拼接圖片
    String[] c = new String[26];
    for(int i = 0; i < 26; i++){
      c[i] = String.format(basePath + "result/" + type + "%d.jpg", i + 26);
    }
    mergeImage(c, 1, basePath + "result/" + type + "result2.jpg");
    mergeImage(new String[]{basePath + "result/" + type + "result1.jpg",
        basePath + "result/" + type + "result2.jpg"}, 2, basePath + "result/" + type + "result3.jpg");
    //刪除產(chǎn)生的中間圖片
    for(int i = 0; i < 52; i++){
      new File(basePath + "result/" + type + i + ".jpg").deleteOnExit();
    }
    new File(basePath + "result/" + type + "result1.jpg").deleteOnExit();
    new File(basePath + "result/" + type + "result2.jpg").deleteOnExit();
  }
  /**
   * 獲取原始圖url
   * @param pageSource
   * @return
   */
  private static String getFullImageUrl(String pageSource){
    String url = null;
    Document document = Jsoup.parse(pageSource);
    String style = document.select("[class=gt_cut_fullbg_slice]").first().attr("style");
    Pattern pattern = Pattern.compile("url\\(\"(.*)\"\\)");
    Matcher matcher = pattern.matcher(style);
    if (matcher.find()){
      url = matcher.group(1);
    }
    url = url.replace(".webp", ".jpg");
    System.out.println(url);
    return url;
  }
  /**
   * 獲取帶背景的url
   * @param pageSource
   * @return
   */
  private static String getBgImageUrl(String pageSource){
    String url = null;
    Document document = Jsoup.parse(pageSource);
    String style = document.select(".gt_cut_bg_slice").first().attr("style");
    Pattern pattern = Pattern.compile("url\\(\"(.*)\"\\)");
    Matcher matcher = pattern.matcher(style);
    if (matcher.find()){
      url = matcher.group(1);
    }
    url = url.replace(".webp", ".jpg");
    System.out.println(url);
    return url;
  }
  public static boolean cutPic(String srcFile, String outFile, int x, int y,
                 int width, int height) {
    FileInputStream is = null;
    ImageInputStream iis = null;
    try {
      if (!new File(srcFile).exists()) {
        return false;
      }
      is = new FileInputStream(srcFile);
      String ext = srcFile.substring(srcFile.lastIndexOf(".") + 1);
      Iterator<ImageReader> it = ImageIO.getImageReadersByFormatName(ext);
      ImageReader reader = it.next();
      iis = ImageIO.createImageInputStream(is);
      reader.setInput(iis, true);
      ImageReadParam param = reader.getDefaultReadParam();
      Rectangle rect = new Rectangle(x, y, width, height);
      param.setSourceRegion(rect);
      BufferedImage bi = reader.read(0, param);
      File tempOutFile = new File(outFile);
      if (!tempOutFile.exists()) {
        tempOutFile.mkdirs();
      }
      ImageIO.write(bi, ext, new File(outFile));
      return true;
    } catch (Exception e) {
      e.printStackTrace();
      return false;
    } finally {
      try {
        if (is != null) {
          is.close();
        }
        if (iis != null) {
          iis.close();
        }
      } catch (IOException e) {
        e.printStackTrace();
        return false;
      }
    }
  }
  /**
   * 圖片拼接 (注意:必須兩張圖片長(zhǎng)寬一致哦)
   * @param files 要拼接的文件列表
   * @param type 1橫向拼接,2 縱向拼接
   * @param targetFile 輸出文件
   */
  private static void mergeImage(String[] files, int type, String targetFile) {
    int length = files.length;
    File[] src = new File[length];
    BufferedImage[] images = new BufferedImage[length];
    int[][] ImageArrays = new int[length][];
    for (int i = 0; i < length; i++) {
      try {
        src[i] = new File(files[i]);
        images[i] = ImageIO.read(src[i]);
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
      int width = images[i].getWidth();
      int height = images[i].getHeight();
      ImageArrays[i] = new int[width * height];
      ImageArrays[i] = images[i].getRGB(0, 0, width, height, ImageArrays[i], 0, width);
    }
    int newHeight = 0;
    int newWidth = 0;
    for (int i = 0; i < images.length; i++) {
      // 橫向
      if (type == 1) {
        newHeight = newHeight > images[i].getHeight() ? newHeight : images[i].getHeight();
        newWidth += images[i].getWidth();
      } else if (type == 2) {// 縱向
        newWidth = newWidth > images[i].getWidth() ? newWidth : images[i].getWidth();
        newHeight += images[i].getHeight();
      }
    }
    if (type == 1 && newWidth < 1) {
      return;
    }
    if (type == 2 && newHeight < 1) {
      return;
    }
    // 生成新圖片
    try {
      BufferedImage ImageNew = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
      int height_i = 0;
      int width_i = 0;
      for (int i = 0; i < images.length; i++) {
        if (type == 1) {
          ImageNew.setRGB(width_i, 0, images[i].getWidth(), newHeight, ImageArrays[i], 0,
              images[i].getWidth());
          width_i += images[i].getWidth();
        } else if (type == 2) {
          ImageNew.setRGB(0, height_i, newWidth, images[i].getHeight(), ImageArrays[i], 0, newWidth);
          height_i += images[i].getHeight();
        }
      }
      //輸出想要的圖片
      ImageIO.write(ImageNew, targetFile.split("\\.")[1], new File(targetFile));

    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
}

pom文件依賴(lài)如下

  <dependency>
   <groupId>org.seleniumhq.selenium</groupId>
   <artifactId>selenium-server</artifactId>
   <version>3.0.1</version>
  </dependency>
  <!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
  <dependency>
   <groupId>org.jsoup</groupId>
   <artifactId>jsoup</artifactId>
   <version>1.7.2</version>
  </dependency>

最后

完整代碼已上傳至github,地址:https://github.com/wycm/selenium-geetest-crack

附上一張滑動(dòng)效果圖

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java實(shí)現(xiàn)隨機(jī)出題,10道10以內(nèi)加減法計(jì)算代碼實(shí)例

    Java實(shí)現(xiàn)隨機(jī)出題,10道10以內(nèi)加減法計(jì)算代碼實(shí)例

    這篇文章主要介紹了Java實(shí)現(xiàn)隨機(jī)出題,10道10以內(nèi)加減法計(jì)算,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • ElasticSearch的完整安裝教程

    ElasticSearch的完整安裝教程

    這篇文章主要給大家分享介紹了ElasticSearch的完整安裝教程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用ElasticSearch具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Java核心編程之文件隨機(jī)讀寫(xiě)類(lèi)RandomAccessFile詳解

    Java核心編程之文件隨機(jī)讀寫(xiě)類(lèi)RandomAccessFile詳解

    這篇文章主要為大家詳細(xì)介紹了Java核心編程之文件隨機(jī)讀寫(xiě)類(lèi)RandomAccessFile,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • 詳解JAVA常用的時(shí)間操作【實(shí)用】

    詳解JAVA常用的時(shí)間操作【實(shí)用】

    本文主要介紹了JAVA一些常用的時(shí)間操作,很實(shí)用,相信大家在開(kāi)發(fā)項(xiàng)目時(shí)會(huì)用到,下面就跟小編一起來(lái)看下吧
    2016-12-12
  • java 中數(shù)組初始化實(shí)例詳解

    java 中數(shù)組初始化實(shí)例詳解

    這篇文章主要介紹了 本文主要講數(shù)組的初始化方法、可變參數(shù)列表以及可變參數(shù)列表對(duì)函數(shù)重載的影響的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • Java 中的變量類(lèi)型

    Java 中的變量類(lèi)型

    這篇文章主要介紹了Java 中的變量類(lèi)型,一般包括局部變量、成員變量、類(lèi)變量,下面文章對(duì)這三種內(nèi)容的變量做了一個(gè)詳細(xì)介紹,需要的朋友可以參考一下
    2021-11-11
  • 詳解用Spring Boot Admin來(lái)監(jiān)控我們的微服務(wù)

    詳解用Spring Boot Admin來(lái)監(jiān)控我們的微服務(wù)

    這篇文章主要介紹了用Spring Boot Admin來(lái)監(jiān)控我們的微服務(wù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • java巧用@Convert實(shí)現(xiàn)表字段自動(dòng)轉(zhuǎn)entity

    java巧用@Convert實(shí)現(xiàn)表字段自動(dòng)轉(zhuǎn)entity

    本文主要介紹了java巧用@Convert實(shí)現(xiàn)表字段自動(dòng)轉(zhuǎn)entity,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-07-07
  • JDK安裝配置教程

    JDK安裝配置教程

    這篇文章主要為大家詳細(xì)介紹了JDK安裝配置教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • 基于SpringBoot實(shí)現(xiàn)郵箱找回密碼的代碼示例

    基于SpringBoot實(shí)現(xiàn)郵箱找回密碼的代碼示例

    本文主要介紹了如何基于SpringBoot實(shí)現(xiàn)郵箱找回密碼,文中通過(guò)代碼示例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-02-02

最新評(píng)論

平陆县| 荔波县| 汉阴县| 浦城县| 建瓯市| 德惠市| 东至县| 永州市| 梁河县| 福建省| 汽车| 海晏县| 垣曲县| 泗洪县| 郸城县| 察隅县| 东乡族自治县| 普兰店市| 宝清县| 山西省| 四平市| 酒泉市| 简阳市| 连州市| 汨罗市| 广平县| 瓮安县| 上栗县| 资阳市| 广灵县| 阆中市| 阳高县| 龙井市| 长沙县| 信宜市| 岳普湖县| 电白县| 师宗县| 巩留县| 孟连| 恩平市|