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

簡單聊聊Java中驗證碼功能的實現(xiàn)

 更新時間:2023年06月07日 09:58:05   作者:god23bin  
相信大家都經(jīng)常接觸到驗證碼的,畢竟平時上網(wǎng)也能遇到各種驗證碼,需要我們輸入驗證碼進行驗證我們是人類,本篇文章就從這幾個方面出發(fā)說說驗證碼,廢話不多說,下面開始正文

前言

大家好,我是 god23bin,今天說說驗證碼功能的實現(xiàn),相信大家都經(jīng)常接觸到驗證碼的,畢竟平時上網(wǎng)也能遇到各種驗證碼,需要我們輸入驗證碼進行驗證我們是人類,而不是機器人。

驗證碼有多種類型,比如圖片驗證碼、短信驗證碼和郵件驗證碼等等,雖說多種類型,圖片也好,短信也好,郵件也好,都是承載驗證碼的載體,最主要的核心就是一個驗證碼的生成、存儲和校驗。

本篇文章就從這幾個方面出發(fā)說說驗證碼,廢話不多說,下面開始正文。

實現(xiàn)思路

驗證碼驗證的功能,其實現(xiàn)思路還是挺簡單的,不論是圖片驗證碼、短信驗證碼還是郵件驗證碼,無非就以下幾點:

  • 驗證碼本質(zhì)就是一堆字符的組合(數(shù)字也好,英文字母也好),后端生成驗證碼,并存儲到某個位置(比如存儲到 Redis,并設(shè)置驗證碼的過期時間)。
  • 返回驗證碼給前端頁面、發(fā)送短信驗證碼給用戶或者發(fā)送郵件驗證碼給用戶。驗證碼可以是以文字顯示或者圖片顯示。
  • 用戶輸入看到的驗證碼,并提交驗證(驗證也可以忽略大小寫,當(dāng)然具體看需求)。
  • 后端將用戶輸入的驗證碼拿過來進行校驗,對比用戶輸入的驗證碼是否和后端生成的一致,一致就驗證成功,否則驗證失敗。

驗證碼的生成

首先,需要知道的就是驗證碼的生成,這就涉及到生成驗證碼的算法,可以自己純手寫,也可以使用人家提供的工具,這里我就介紹下面 4 種生成驗證碼的方式。

1. 純原生手寫生成文本驗證碼

需求:隨機產(chǎn)生一個 n 位的驗證碼,每位可能是數(shù)字、大寫字母、小寫字母。

實現(xiàn):本質(zhì)就是隨機生成字符串,字符串可包含數(shù)字、大寫字母、小寫字母。

準備一個包含數(shù)字、大寫字母、小寫字母的字符串,借助 Random 類,循環(huán) n 次隨機獲取字符串的下標,就能拼接出一個隨機字符組成的字符串了。

package cn.god23bin.demo.util;
import java.util.Random;
public class MyCaptchaUtil {
	/**
     * 生成 n 位驗證碼
     * @param n 位數(shù)
     * @return n 位驗證碼
     **/
    public static String generateCode(int n) {
        String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < n; i++) {
            int index = random.nextInt(chars.length());
            sb.append(chars.charAt(index));
        }
        return sb.toString();
    }
}

2. 純原生手寫生成圖片驗證碼

實現(xiàn):使用 Java 的 awt 和 swing 庫來生成圖片驗證碼。下面使用 BufferedImage 類創(chuàng)建一個指定大小的圖片,然后隨機生成 n 個字符,將其畫在圖片上,將生成的字符和圖片驗證碼放到哈希表返回。后續(xù)我們就可以拿到驗證碼的文本值,并且可以將圖片驗證碼輸出到指定的輸出流中。

package cn.god23bin.demo.util;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import java.util.Map;
public class MyCaptchaUtil {
	/**
     * 生成 n 位的圖片驗證碼
     * @param n 位數(shù)
     * @return 哈希表,code 獲取文本驗證碼,img 獲取 BufferedImage 圖片對象
     **/
    public static Map<String, Object> generateCodeImage(int n) {
        int width = 100, height = 50;
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();
        g.setColor(Color.LIGHT_GRAY);
        g.fillRect(0, 0, width, height);
        String chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < n; i++) {
            int index = random.nextInt(chars.length());
            char c = chars.charAt(index);
            sb.append(c);
            g.setColor(new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255)));
            g.setFont(new Font("Arial", Font.BOLD, 25));
            g.drawString(Character.toString(c), 20 + i * 15, 25);
        }
        Map<String, Object> res = new HashMap<>();
        res.put("code", sb.toString());
        res.put("img", image);
        return res;
    }
}

我們可以寫一個獲取驗證碼的接口,以二進制流輸出返回給前端,前端可以直接使用 img 標簽來顯示我們返回的圖片,只需在 src 屬性賦值我們的獲取驗證碼接口。

@RequestMapping("/captcha")
@RestController
public class CaptchaController {
    @GetMapping("/code/custom")
    public void getCode(HttpServletResponse response) {
        Map<String, Object> map = MyCaptchaUtil.generateCodeImage(5);
        System.out.println(map.get("code"));
        BufferedImage img = (BufferedImage) map.get("img");
        // 設(shè)置響應(yīng)頭,防止緩存
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/png");
        try {
            ImageIO.write(img, "png", response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3. 使用 Hutool 工具生成圖形驗證碼

引入依賴:可以單獨引入驗證碼模塊或者全部模塊都引入

<!-- 驗證碼模塊 -->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-captcha</artifactId>
    <version>5.8.15</version>
</dependency>
<!-- 全部模塊都引入 -->
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.15</version>
</dependency>

生成線段干擾的驗證碼:

// 設(shè)置圖形驗證碼的寬和高,同時生成了驗證碼,可以通過 lineCaptcha.getCode() 獲取文本驗證碼
LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);

生成圓圈干擾的驗證碼:

// 設(shè)置圖形驗證碼的寬、高、驗證碼字符數(shù)、干擾元素個數(shù)
CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100, 4, 20);

生成扭曲干擾的驗證碼:

// 定義圖形驗證碼的寬、高、驗證碼字符數(shù)、干擾線寬度
ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(200, 100, 4, 4);

獲取驗證碼接口:

@RequestMapping("/captcha")
@RestController
public class CaptchaController {
    @GetMapping("/code/hutool")
    public void getCodeByHutool(HttpServletResponse response) {
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);
        System.out.println("線段干擾的驗證碼:" + lineCaptcha.getCode());
        // 設(shè)置響應(yīng)頭,防止緩存
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/png");
        try {
            lineCaptcha.write(response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4. 使用 Kaptcha 生成驗證碼

Kaptcha 是谷歌的一個生成驗證碼工具包,我們簡單配置其屬性就可以實現(xiàn)驗證碼的驗證功能。

引入依賴項:它只有一個版本:2.3.2

<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>

簡單看看 kaptcha 屬性:

屬性描述默認值
kaptcha.border圖片邊框,合法值:yes , noyes
kaptcha.border.color邊框顏色,合法值: r,g,b (and optional alpha) 或者 white,black,blue.black
kaptcha.border.thickness邊框厚度,合法值:>01
kaptcha.image.width圖片寬200
kaptcha.image.height圖片高50
kaptcha.producer.impl圖片實現(xiàn)類com.google.code.kaptcha.impl.DefaultKaptcha
kaptcha.textproducer.impl文本實現(xiàn)類com.google.code.kaptcha.text.impl.DefaultTextCreator
kaptcha.textproducer.char.string文本集合,驗證碼值從此集合中獲取abcde2345678gfynmnpwx
kaptcha.textproducer.char.length驗證碼長度5
kaptcha.textproducer.font.names字體Arial, Courier
kaptcha.textproducer.font.size字體大小40px
kaptcha.textproducer.font.color字體顏色,合法值: r,g,b 或者 white,black,blue.black
kaptcha.textproducer.char.space文字間隔2
kaptcha.noise.impl干擾實現(xiàn)類com.google.code.kaptcha.impl.DefaultNoise
kaptcha.noise.color干擾顏色,合法值: r,g,b 或者 white,black,blue.black
kaptcha.obscurificator.impl圖片樣式: 水紋com.google.code.kaptcha.impl.WaterRipple 魚眼com.google.code.kaptcha.impl.FishEyeGimpy 陰影com.google.code.kaptcha.impl.ShadowGimpycom.google.code.kaptcha.impl.WaterRipple
kaptcha.background.impl背景實現(xiàn)類com.google.code.kaptcha.impl.DefaultBackground
kaptcha.background.clear.from背景顏色漸變,開始顏色light grey
kaptcha.background.clear.to背景顏色漸變,結(jié)束顏色white
kaptcha.word.impl文字渲染器com.google.code.kaptcha.text.impl.DefaultWordRenderer
kaptcha.session.keysession keyKAPTCHA_SESSION_KEY
kaptcha.session.datesession dateKAPTCHA_SESSION_DATE

簡單配置下 Kaptcha:

package cn.god23bin.demo.config;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
@Configuration
public class KaptchaConfig {
    /**
     * 配置生成圖片驗證碼的bean
     * @return
     */
    @Bean(name = "kaptchaProducer")
    public DefaultKaptcha getKaptchaBean() {
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        Properties properties = new Properties();
        properties.setProperty("kaptcha.border", "no");
        properties.setProperty("kaptcha.textproducer.font.color", "black");
        properties.setProperty("kaptcha.textproducer.char.space", "4");
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        properties.setProperty("kaptcha.textproducer.char.string", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
        Config config = new Config(properties);
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}

也是和 Hutool 一樣,很簡單就能生成驗證碼了。如下:

// 生成文字驗證碼
String text = kaptchaProducer.createText();
// 生成圖片驗證碼
BufferedImage image = kaptchaProducer.createImage(text);

獲取驗證碼接口:

@RequestMapping("/captcha")
@RestController
public class CaptchaController {
    @Autowired
    private Producer kaptchaProducer;
    @GetMapping("/code/kaptcha")
    public void getCodeByKaptcha(HttpServletResponse response) {
        // 生成文字驗證碼
        String text = kaptchaProducer.createText();
        System.out.println("文字驗證碼:" + text);
        // 生成圖片驗證碼
        BufferedImage image = kaptchaProducer.createImage(text);
        // 設(shè)置響應(yīng)頭,防止緩存
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");
        try {
            ImageIO.write(image, "jpg", response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

驗證碼的存儲與校驗

上面的驗證碼的生成,就僅僅是生成驗證碼,并沒有將驗證碼存儲在后端,所以現(xiàn)在我們需要做的是:將驗證碼存儲起來,便于后續(xù)的校驗對比。

那么存儲到什么地方呢?如果你沒接觸過 Redis,那么第一次的想法可能就是存儲到關(guān)系型數(shù)據(jù)庫中,比如 MySQL。想當(dāng)年,我最開始的想法就是這樣哈哈哈。

不過,目前用得最多的就是將驗證碼存儲到 Redis 中,好處就是減少了數(shù)據(jù)庫的壓力,加快了驗證碼的讀取效率,還能輕松設(shè)置驗證碼的過期時間。

簡單配置 Redis

引入 Redis 依賴項:

我們使用 Spring Data Redis,它提供了 RedisTemplate 和 StringRedisTemplate 模板類,簡化了我們使用 Java 進行 Redis 的操作。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

簡單配置下 Redis:

spring:
  redis:
    host: localhost
    port: 6379
    database: 1
    timeout: 5000
@Configuration
public class RedisConfig extends CachingConfigurerSupport {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        // 大多數(shù)情況,都是選用<String, Object>
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        // 使用JSON的序列化對象,對數(shù)據(jù) key 和 value 進行序列化轉(zhuǎn)換
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        // ObjectMapper 是 Jackson 的一個工作類,作用是將 JSON 轉(zhuǎn)成 Java 對象,即反序列化?;?qū)?Java 對象轉(zhuǎn)成 JSON,即序列化
        ObjectMapper mapper = new ObjectMapper();
        // 設(shè)置序列化時的可見性,第一個參數(shù)是選擇序列化哪些屬性,比如時序列化 setter? 還是 filed? 第二個參數(shù)是選擇哪些修飾符權(quán)限的屬性來序列化,比如 private 或者 public,這里的 any 是指對所有權(quán)限修飾的屬性都可見(可序列化)
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        jackson2JsonRedisSerializer.setObjectMapper(mapper);
        // 設(shè)置 RedisTemplate 模板的序列化方式為 jacksonSeial
        template.setDefaultSerializer(jackson2JsonRedisSerializer);
        return template;
    }
}

將驗證碼存儲到 Redis

將驗證碼存儲到 Redis 設(shè)置 5 分鐘的過期時間,Redis 是 Key Value 這種形式存儲的,所以需要約定好 Key 的命名規(guī)則。

命名的時候,為了區(qū)分為每個用戶生成的驗證碼,所以需要一個標識,剛好可以通過當(dāng)前請求的 HttpSession 中的 SessionID 作為唯一標識,拼接到 Key 的名稱中。

當(dāng)然,也不一定使用 SessionID 作為唯一標識,如果能知道其他的,也可以用其他的作為標識,比如拼接用戶的手機號。

實現(xiàn):

@RequestMapping("/captcha")
@RestController
public class CaptchaController {
    @Autowired
    private Producer kaptchaProducer;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @GetMapping("/code")
    public void getCode(HttpServletRequest request, HttpServletResponse response) {
        // 生成文字驗證碼
        String text = kaptchaProducer.createText();
        System.out.println("文字驗證碼:" + text);
        // 生成圖片驗證碼
        BufferedImage image = kaptchaProducer.createImage(text);
        // 存儲到 Redis 設(shè)置 5 分鐘的過期時間
        // 約定好存儲的 Key 的命名規(guī)則,這里使用 code_sessionId_type_1 表示圖形驗證碼
        // Code_sessionId_Type_1:分為 3 部分,code 表明是驗證碼,sessionId 表明是給哪個用戶的驗證碼,type_n 表明驗證碼類型,n 為 1 表示圖形驗證碼,2 表示短信驗證碼,3 表示郵件驗證碼
        String key = "code_" + request.getSession().getId() + "_type_1";
        redisTemplate.opsForValue().set(key, text, 5, TimeUnit.SECONDS);
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");
        try {
            ImageIO.write(image, "jpg", response.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

上面代碼中有一個額外的設(shè)計就是,由于發(fā)送的驗證碼有多種類型(圖形驗證碼、短信驗證碼、郵件驗證碼),所以加多了一個 type_n 來標識當(dāng)前存儲的驗證碼是什么類型的,方便以后出現(xiàn)問題快速定位。

實際上,這里的命名規(guī)則,可以根據(jù)你的具體需求來定制,又比如說,登錄的時候需要驗證碼、注冊的時候也需要驗證碼、修改用戶密碼的時候也需要驗證碼,為了便于出現(xiàn)問題進行定位,也可以繼續(xù)加多一個標識 when_n,n 為 1 表示注冊、n 為 2 表示登錄,以此類推。

校驗

我們模擬登錄的時候進行驗證碼的校驗,使用一個 LoginDTO 對象來接收前端的登錄相關(guān)的參數(shù)。

package cn.god23bin.demo.model.domain.dto;
import lombok.Data;
@Data
public class LoginDTO {
    private String username;
    private String password;
    /**
     * 驗證碼
     */
    private String code;
}

寫一個登錄接口,登錄的過程中,校驗用戶輸入的驗證碼。

@RequestMapping("/user")
@RestController
public class UserController {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @PostMapping("/login")
    public Result<String> login(@RequestBody LoginDTO loginDTO, HttpServletRequest request) {
        if (!"root".equals(loginDTO.getUsername()) || !"123456".equals(loginDTO.getPassword())) {
            return Result.fail("登錄失敗!賬號或密碼不正確!");
        }
        // 校驗用戶輸入的驗證碼
        String code = loginDTO.getCode();
        String codeInRedis = (String) redisTemplate.opsForValue().get("code_" + request.getSession().getId() + "_type_1");
        if (!code.equals(codeInRedis)) {
            return Result.fail("驗證碼不正確!");
        }
        return Result.ok("登錄成功!");
    }
}

至此,便完成了驗證碼功能的實現(xiàn)。

獲取驗證碼的安全設(shè)計

驗證碼功能的實現(xiàn)現(xiàn)在是OK的,但還有一點需要注意,那就是防止驗證碼被隨意調(diào)用獲取,或者被大量調(diào)用。如果不做限制,那么誰都能調(diào)用,就非常大的可能會被攻擊了。

我們上面實現(xiàn)的驗證碼功能是圖形驗證碼,是校驗用戶從圖形驗證碼中看到后輸入的數(shù)字字母組合跟后端生成的組合是否是一致的。對于圖形驗證碼,到這里就可以了,不用限制(當(dāng)然想限制也可以)。但是對于短信驗證碼,就還不可以。我們需要額外考慮一些防刷機制,以保障系統(tǒng)的安全性和可靠性(因為發(fā)短信是要錢的?。。?。

對于短信來說,一種常見的攻擊方式是「短信轟炸」,攻擊者通過自動批量提交手機號碼、模擬IP等手段,對系統(tǒng)進行大規(guī)模的短信請求,從而消耗資源或干擾正常業(yè)務(wù)。為了應(yīng)對這種情況,我們需要設(shè)計一些防刷機制。

防刷機制

目前我了解到的防刷機制有下面幾種,如果你有別的方法,歡迎評論說出來噢!

  • 圖形驗證碼或者滑動驗證:發(fā)送短信前先使用圖形驗證碼或者滑動進行驗證,驗證成功才能調(diào)用發(fā)送短信驗證碼的接口。
  • 時間限制:從用戶點擊發(fā)送短信驗證碼開始,前端進行一個 60 秒的倒數(shù),在這 60 秒之內(nèi),用戶無法提交發(fā)送信息的請求的,這樣就限制了發(fā)送短信驗證碼的接口的調(diào)用次數(shù)。不過這種方式,如果被攻擊者知道了發(fā)送短信的接口,那也是會被刷的。
  • 手機號限制:對使用同一個手機號碼進行注冊或者其他發(fā)送短信驗證碼的操作的時候,系統(tǒng)可以對這個手機號碼進行限制,例如,一天只能發(fā)送 5 條短信驗證碼,超出限制則做出提示(如:系統(tǒng)繁忙,請稍后再試)。然而,這也只能夠避免人工手動刷短信而已,對于批量使用不同手機號碼來刷短信的機器,同樣是會被刷。
  • IP地址限制:記錄請求的IP地址,并對同一 IP 地址的請求進行限制,比如限制某個 IP 地址在一定時間內(nèi)只能發(fā)送特定數(shù)量的驗證碼。同樣,也是可以被轟炸的。

至于這些機制的實現(xiàn),有機會再寫寫,你感興趣的話可以自己去操作試試!

總結(jié)

本篇文字就說了驗證碼功能的實現(xiàn)思路和實現(xiàn),包括驗證碼的生成、存儲、展示和校驗。

  • 生成驗證碼可以手寫也可以借助工具。
  • 存儲一般是存儲在 Redis 中的,當(dāng)然你想存儲在 MySQL 中也不是不可以,就是需要自己去實現(xiàn)諸如過期時間的功能。
  • 展示可以通過文本展示或者圖片展示,我們可以返回一個二進制流給前端,前端通過 img 標簽的 src 屬性去請求我們的接口。
  • 校驗就拿到用戶輸入的驗證碼,和后端生成的驗證碼進行比對,相同就驗證成功,否則失敗。

最后我們也說了驗證碼的防刷機制,這是需要考慮的,這里的防刷機制對于使用大量不同手機號、不同 IP 地址是沒效果的,依舊可以暴刷。所以這部分內(nèi)容還是有待研究的。

以上就是簡單聊聊Java中驗證碼功能的實現(xiàn)的詳細內(nèi)容,更多關(guān)于Java驗證碼的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 更改Maven軟件源為阿里云源的方法詳解

    更改Maven軟件源為阿里云源的方法詳解

    這篇文章主要介紹了更改Maven軟件源為阿里云源的方法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • Redis實現(xiàn)商品秒殺功能頁面流程

    Redis實現(xiàn)商品秒殺功能頁面流程

    這篇文章主要介紹了Redis實現(xiàn)商品秒殺功能的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-09-09
  • 淺談Spring與SpringMVC父子容器的關(guān)系與初始化

    淺談Spring與SpringMVC父子容器的關(guān)系與初始化

    這篇文章主要介紹了淺談Spring與SpringMVC父子容器的關(guān)系與初始化,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • java實現(xiàn)基于UDP協(xié)議的聊天小程序操作

    java實現(xiàn)基于UDP協(xié)議的聊天小程序操作

    UDP是與TCP相對應(yīng)的協(xié)議,UDP適用于一次只傳送少量數(shù)據(jù)、對可靠性要求不高的應(yīng)用環(huán)境。正因為UDP協(xié)議沒有連接的過程,所以它的通信效率高;但也正因為如此,它的可靠性不如TCP協(xié)議高,本文給大家介紹java實現(xiàn)基于UDP協(xié)議的聊天小程序操作,感興趣的朋友一起看看吧
    2021-10-10
  • SpringBoot-Mail工具實現(xiàn)郵箱驗證碼登錄注冊功能

    SpringBoot-Mail工具實現(xiàn)郵箱驗證碼登錄注冊功能

    現(xiàn)在許多pc程序都有著使用郵箱驗證碼實現(xiàn)登錄注冊的功能,那么我們應(yīng)該如何完成郵箱驗證碼功能呢,我們可以使用springboot內(nèi)置的springboot-mail再結(jié)合redis來完成這個功能,感興趣的朋友跟隨小編一起看看吧
    2024-07-07
  • Java使用Graphics2D繪制SVG和PNG的方法

    Java使用Graphics2D繪制SVG和PNG的方法

    Java提供了許多圖形處理類和方法,如Graphics2D、AffineTransform、Stroke等,這些都可以用于繪制SVG圖像,Graphics2D是Java中用于繪制2D圖形的類,本文給大家介紹如何使用Graphics2D繪制SVG和PNG,需要的朋友可以參考下
    2023-06-06
  • 詳解JVM 運行時內(nèi)存使用情況監(jiān)控

    詳解JVM 運行時內(nèi)存使用情況監(jiān)控

    這篇文章主要介紹了詳解JVM 運行時內(nèi)存使用情況監(jiān)控,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • 數(shù)據(jù)同步利器DataX簡介及如何使用

    數(shù)據(jù)同步利器DataX簡介及如何使用

    DataX?是阿里云?DataWorks數(shù)據(jù)集成?的開源版本,使用Java?語言編寫,在阿里巴巴集團內(nèi)被廣泛使用的離線數(shù)據(jù)同步工具/平臺,今天給大家分享一個阿里開源的數(shù)據(jù)同步工具DataX,在Github擁有14.8k的star,非常受歡迎
    2024-02-02
  • Javaweb中使用Servlet編寫簡單的接口案例詳解

    Javaweb中使用Servlet編寫簡單的接口案例詳解

    文章介紹了如何使用Servlet編寫一個簡單的接口來校驗用戶提交的密碼長度是否在6到12位之間,代碼分為后端部分和前端部分,給大家介紹的非常詳細,感興趣的朋友一起看看吧
    2025-02-02
  • java能寫爬蟲程序嗎

    java能寫爬蟲程序嗎

    在本篇文章里小編給大家整理的是一篇關(guān)于java是否能寫爬蟲程序的一篇文章,對此有興趣的朋友們可以學(xué)習(xí)下。
    2021-01-01

最新評論