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

Java http加簽、驗簽實現(xiàn)方案詳解

 更新時間:2024年07月24日 10:43:46   作者:小先生ノ  
這篇文章主要介紹了Java http加簽、驗簽實現(xiàn)方案詳解,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

為什么要加密驗簽? 防止報文明文傳輸

數(shù)據(jù)在網(wǎng)絡傳輸過程中,容易被抓包。如果使用的是HTTP協(xié)議的請求/響應(Request OR Response),它是明文傳輸?shù)?,都是可以被截獲、篡改、重放(重發(fā))的。所以需要進行數(shù)據(jù)的加密驗簽,所以需要考慮以下幾點。

  • 防偽裝攻擊(案例:在公共網(wǎng)絡環(huán)境中,第三方 有意或惡意 的調用我們的接口)
  • 防篡改攻擊(案例:在公共網(wǎng)絡環(huán)境中,請求頭/查詢字符串/內容 在傳輸過程被修改)
  • 防重放攻擊(案例:在公共網(wǎng)絡環(huán)境中,請求被截獲,稍后被重放或多次重放)
  • 防數(shù)據(jù)信息泄漏(案例:截獲用戶登錄請求,截獲到賬號、密碼等)

實現(xiàn)方式

常見的方式,就是對關鍵字段加密。比如查詢訂單接口,就可以對訂單號進行加密。一般常用的加密算法對稱加密算法(如:AES),或者哈希算法處理(如:MD5)

對稱加密:加密和解密使用相同秘鑰的加密算法

采用單鑰密碼系統(tǒng)的加密方法,同一個密鑰可以同時用作信息的加密和解密,這種加密方法稱為對稱加密,也稱為單密鑰加密。

非對稱加密:非對稱加密算法需要兩個密鑰(公開密鑰和私有密鑰)。公鑰和私鑰是成對存在的,如果用公鑰對數(shù)據(jù)加密,只有對應的私鑰才能解密。 (非對稱加密是更安全的做法,加密是算法RSA或SM2)

非對稱加密算法需要兩個密鑰來進行加密和解密,這兩個密鑰是公開密鑰(public key,簡稱公鑰)和私有密鑰(private key,簡稱私鑰)。

加簽驗簽:使用Hash算法(如 MD5或者SHA-256)把原始請求參數(shù)生成報文摘要,然后用私鑰對這個摘要進行加密,得到報文對應的sign

加簽:用Hash函數(shù)把原始報文生成報文摘要,然后用私鑰對這個摘要進行加密,就得到這個報文對應的數(shù)字簽名。通常來說呢,請求方會把「數(shù)字簽名和報文原文」一并發(fā)送給接收方。

驗簽:接收方拿到原始報文和數(shù)字簽名后,用「同一個Hash函數(shù)」從報文中生成摘要A。另外,用對方提供的公鑰對數(shù)字簽名進行解密,得到摘要B,對比A和B是否相同,就可以得知報文有沒有被篡改過。

客戶端操作

請求參數(shù):

字段類型必傳說明
signString接口簽名,用戶接口驗證
app_idString開放平臺的APP_ID,例如:1234
date_timeString當前時間戳
keyString開發(fā)平臺的APP_KEY,例如:XA12#Da
nameString業(yè)務參數(shù)
ageString業(yè)務參數(shù)

業(yè)務參數(shù)消息體數(shù)據(jù)格式:Content-Type 指定為 application/json

1.將請求參數(shù)中除sign外的多個鍵值對,根據(jù)鍵按照字典序排序,并按照"key1=value1&key2=value2…"的格式拼成一個字符串

String sortStr=" age=11&app_id=1234&date_time=1656926899731&name=xxx"

2.將key拼接在第一步中排序后的字符串后面得到待簽名字符串

String sortStr ="age=11&app_id=1234&date_time=1656926899731&name=xxxkey=XA12#Da"

3.使用md5算法加密待加密字符串并轉為大寫即為sign

String sign ="57A132B7585F77B1948812275BE945B8"

4.將sign添加到請求參數(shù)中

https://www.baidu.com/test/get?age=11&app_id=1234&date_time=1656926899731&name=xxx&sign=57A132B7585F77B1948812275BE945B8

需要注意以下重要規(guī)則:

◆ 請求參數(shù)中有中文時,中文需要經(jīng)過url編碼,但計算簽名時不需要;

◆ 請求參數(shù)的值為空則不參與簽名;

◆ 參數(shù)名區(qū)分大小寫;

◆ sign參數(shù)不參與簽名;

服務端操作
1.接收到請求參數(shù),轉JSON格式
2.驗簽
   2.1拿出用戶簽名
   2.2根據(jù)APP_ID 拿去數(shù)據(jù)庫中的KEY,使用該KEY進行重簽參數(shù)
   2.3如果重簽結果和用戶簽名一致則通過,否則返回簽名錯誤
   2.4校驗參數(shù)中的時間戳,如果時間戳 超過當前時間5分鐘則簽名失效
3.如果c、d都通過則正常請求業(yè)務

package com.chinaunicom.utils;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.util.*;
/**
 * @author yming wang
 * @date 2024/3/4 13:48
 * @desc
 */
@Slf4j
public class SignUtil {
    /**
     * sign有效期
     */
    private static final int TIMES = 111 * 60 * 1000;
    public static boolean check(JSONObject params, String appKey, String sign) {
        try {
            //公鑰驗簽
            sign = RsaUtils.decryptByPublicKey(sign, appKey);
            if (!sign.equals(getSign(params, appKey))) {
                log.info("簽名內容正確");
                return false;
            }
            Long expireTime = params.getLong("timestamp");
            Long currTime = System.currentTimeMillis();
            if ((currTime - expireTime) < 0 || (currTime - expireTime) > TIMES) {
                log.info("簽名時間已過期");
                return false;
            }
            log.info("驗簽成功");
            return true;
        } catch (Exception e) {
            log.error("驗簽發(fā)生異常:", e);
        }
        return false;
    }
    /**
     * @param params
     * @return java.lang.String
     * @params:
     * @author yming wang
     * @date 2024/3/4 14:44
     * @desc 加簽算法: 原始報文 ---hash算法---> 消息摘要 ---RSA私鑰加密---> 數(shù)字簽名
     * 驗簽算法:數(shù)字簽名 ---RSA公鑰解密--> 消息摘要 ---> 根據(jù)參數(shù)重新摘要 ---> 對比摘要喜喜
     */
    public static String getSign(JSONObject params, String appKey) {
        //將參數(shù)進行升序
        String sortParams = sortParams(params, appKey);
        //將參數(shù)進行hash生成消息摘要
        String sign = SecureUtil.md5(sortParams);
        return sign;
    }
    /**
     * @param params
     * @param appKey
     * @return java.lang.String
     * @params:
     * @author yming wang
     * @date 2024/3/4 15:25
     * @desc 將參數(shù)進行升序
     */
    public static String sortParams(JSONObject params, String appKey) {
        List<Map.Entry<String, Object>> entries = new ArrayList<>(params.entrySet());
        Collections.sort(entries, Comparator.comparing(Map.Entry::getKey));
        StringBuffer str = new StringBuffer();
        for (Map.Entry<String, Object> entry : entries) {
            Object value = entry.getValue();
            if (value != null && StringUtils.isNotBlank(value.toString())) {
                str.append(entry.getKey());
                str.append("=");
                str.append(value);
                str.append("&");
            }
        }
        //md5加上鹽值避免根絕request body參數(shù)生成sign
        str.append("appKey");
        str.append("=");
        str.append(appKey);
        return str.toString();
    }
    public static void main(String[] args) throws Exception {
        String privateKey = "privateKey ";
        String publicKey = "publicKey ";
        JSONObject data = new JSONObject();
        data.put("appId", "10002");
        data.put("username", "用戶名");
        data.put("account", "用戶賬號");
        String pwd = RsaUtils.encryptByPrivateKey("用戶密碼", privateKey);
        log.info("encryptPwd:{}", pwd);
        data.put("password", pwd);
        long timestamp = System.currentTimeMillis();
        data.put("timestamp", timestamp);
        //消息摘要
        String sign = getSign(data, publicKey);
        log.info("timestamp:{}", timestamp);
        log.info("isTrue:{}", sign.equals(getSign(data, publicKey)));
        log.info("消息摘要:{}", sign);
        //生成數(shù)字證書
        sign = RsaUtils.encryptByPrivateKey(sign, privateKey);
        log.info("生成數(shù)字證書:{}", sign);
        log.info("打印請求參數(shù):{}", data);
        log.info("驗簽:{}", check(data, publicKey, sign));
    }
}
package com.chinaunicom.utils;
import lombok.extern.slf4j.Slf4j;
import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
/**
 * @program: CSDN
 * @description: yming wang
 * @author: wyming
 * @create: 2021-06-08 09:30:14
 **/
@Slf4j
public class RsaUtils {
    /**
     * 簽名算法名稱
     */
    private static final String RSA_KEY_ALGORITHM = "RSA";
    /**
     * 標準簽名算法名稱
     */
    private static final String RSA_SIGNATURE_ALGORITHM = "SHA1withRSA";
    private static final String RSA2_SIGNATURE_ALGORITHM = "SHA256withRSA";
    /**
     * RSA密鑰長度,默認密鑰長度是1024,密鑰長度必須是64的倍數(shù),在512到65536位之間,不管是RSA還是RSA2長度推薦使用2048
     */
    private static final int KEY_SIZE = 2048;
    /**
     * 生成密鑰對
     *
     * @return 返回包含公私鑰的map
     */
    public static Map<String, String> generateKey() {
        KeyPairGenerator keygen;
        try {
            keygen = KeyPairGenerator.getInstance(RSA_KEY_ALGORITHM);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("RSA初始化密鑰出現(xiàn)錯誤,算法異常");
        }
        SecureRandom secrand = new SecureRandom();
        //初始化隨機產生器
        secrand.setSeed("Alian".getBytes());
        //初始化密鑰生成器
        keygen.initialize(KEY_SIZE, secrand);
        KeyPair keyPair = keygen.genKeyPair();
        //獲取公鑰并轉成base64編碼
        byte[] pub_key = keyPair.getPublic().getEncoded();
        String publicKeyStr = Base64.getEncoder().encodeToString(pub_key);
        //獲取私鑰并轉成base64編碼
        byte[] pri_key = keyPair.getPrivate().getEncoded();
        String privateKeyStr = Base64.getEncoder().encodeToString(pri_key);
        //創(chuàng)建一個Map返回結果
        Map<String, String> keyPairMap = new HashMap<>();
        keyPairMap.put("publicKeyStr", publicKeyStr);
        keyPairMap.put("privateKeyStr", privateKeyStr);
        return keyPairMap;
    }
    /**
     * 公鑰加密(用于數(shù)據(jù)加密)
     *
     * @param data         加密前的字符串
     * @param publicKeyStr base64編碼后的公鑰
     * @return base64編碼后的字符串
     * @throws Exception
     */
    public static String encryptByPublicKey(String data, String publicKeyStr) throws Exception {
        //Java原生base64解碼
        byte[] pubKey = Base64.getDecoder().decode(publicKeyStr);
        //創(chuàng)建X509編碼密鑰規(guī)范
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pubKey);
        //返回轉換指定算法的KeyFactory對象
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
        //根據(jù)X509編碼密鑰規(guī)范產生公鑰對象
        PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
        //根據(jù)轉換的名稱獲取密碼對象Cipher(轉換的名稱:算法/工作模式/填充模式)
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        //用公鑰初始化此Cipher對象(加密模式)
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        //對數(shù)據(jù)加密
        byte[] encrypt = cipher.doFinal(data.getBytes());
        //返回base64編碼后的字符串
        return Base64.getEncoder().encodeToString(encrypt);
    }
    /**
     * 私鑰解密(用于數(shù)據(jù)解密)
     *
     * @param data          解密前的字符串
     * @param privateKeyStr 私鑰
     * @return 解密后的字符串
     * @throws Exception
     */
    public static String decryptByPrivateKey(String data, String privateKeyStr) throws Exception {
        //Java原生base64解碼
        byte[] priKey = Base64.getDecoder().decode(privateKeyStr);
        //創(chuàng)建PKCS8編碼密鑰規(guī)范
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(priKey);
        //返回轉換指定算法的KeyFactory對象
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
        //根據(jù)PKCS8編碼密鑰規(guī)范產生私鑰對象
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        //根據(jù)轉換的名稱獲取密碼對象Cipher(轉換的名稱:算法/工作模式/填充模式)
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        //用私鑰初始化此Cipher對象(解密模式)
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        //對數(shù)據(jù)解密
        byte[] decrypt = cipher.doFinal(Base64.getDecoder().decode(data));
        //返回字符串
        return new String(decrypt);
    }
    /**
     * 私鑰加密(用于數(shù)據(jù)簽名)
     *
     * @param data          加密前的字符串
     * @param privateKeyStr base64編碼后的私鑰
     * @return base64編碼后后的字符串
     * @throws Exception
     */
    public static String encryptByPrivateKey(String data, String privateKeyStr) throws Exception {
        //Java原生base64解碼
        byte[] priKey = Base64.getDecoder().decode(privateKeyStr);
        //創(chuàng)建PKCS8編碼密鑰規(guī)范
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(priKey);
        //返回轉換指定算法的KeyFactory對象
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
        //根據(jù)PKCS8編碼密鑰規(guī)范產生私鑰對象
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        //根據(jù)轉換的名稱獲取密碼對象Cipher(轉換的名稱:算法/工作模式/填充模式)
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        //用私鑰初始化此Cipher對象(加密模式)
        cipher.init(Cipher.ENCRYPT_MODE, privateKey);
        //對數(shù)據(jù)加密
        byte[] encrypt = cipher.doFinal(data.getBytes());
        //返回base64編碼后的字符串
        return Base64.getEncoder().encodeToString(encrypt);
    }
    /**
     * 公鑰解密(用于數(shù)據(jù)驗簽)
     *
     * @param data         解密前的字符串
     * @param publicKeyStr base64編碼后的公鑰
     * @return 解密后的字符串
     * @throws Exception
     */
    public static String decryptByPublicKey(String data, String publicKeyStr) throws Exception {
        //Java原生base64解碼
        byte[] pubKey = Base64.getDecoder().decode(publicKeyStr);
        //創(chuàng)建X509編碼密鑰規(guī)范
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pubKey);
        //返回轉換指定算法的KeyFactory對象
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
        //根據(jù)X509編碼密鑰規(guī)范產生公鑰對象
        PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
        //根據(jù)轉換的名稱獲取密碼對象Cipher(轉換的名稱:算法/工作模式/填充模式)
        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        //用公鑰初始化此Cipher對象(解密模式)
        cipher.init(Cipher.DECRYPT_MODE, publicKey);
        //對數(shù)據(jù)解密
        byte[] decrypt = cipher.doFinal(Base64.getDecoder().decode(data));
        //返回字符串
        return new String(decrypt);
    }
    /**
     * RSA簽名
     *
     * @param data     待簽名數(shù)據(jù)
     * @param priKey   私鑰
     * @param signType RSA或RSA2
     * @return 簽名
     * @throws Exception
     */
    public static String sign(byte[] data, byte[] priKey, String signType) throws Exception {
        //創(chuàng)建PKCS8編碼密鑰規(guī)范
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(priKey);
        //返回轉換指定算法的KeyFactory對象
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
        //根據(jù)PKCS8編碼密鑰規(guī)范產生私鑰對象
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
        //標準簽名算法名稱(RSA還是RSA2)
        String algorithm = RSA_KEY_ALGORITHM.equals(signType) ? RSA_SIGNATURE_ALGORITHM : RSA2_SIGNATURE_ALGORITHM;
        //用指定算法產生簽名對象Signature
        Signature signature = Signature.getInstance(algorithm);
        //用私鑰初始化簽名對象Signature
        signature.initSign(privateKey);
        //將待簽名的數(shù)據(jù)傳送給簽名對象(須在初始化之后)
        signature.update(data);
        //返回簽名結果字節(jié)數(shù)組
        byte[] sign = signature.sign();
        //返回Base64編碼后的字符串
        return Base64.getEncoder().encodeToString(sign);
    }
    /**
     * RSA校驗數(shù)字簽名
     *
     * @param data     待校驗數(shù)據(jù)
     * @param sign     數(shù)字簽名
     * @param pubKey   公鑰
     * @param signType RSA或RSA2
     * @return boolean 校驗成功返回true,失敗返回false
     */
    public static boolean verify(byte[] data, byte[] sign, byte[] pubKey, String signType) throws Exception {
        //返回轉換指定算法的KeyFactory對象
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_KEY_ALGORITHM);
        //創(chuàng)建X509編碼密鑰規(guī)范
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(pubKey);
        //根據(jù)X509編碼密鑰規(guī)范產生公鑰對象
        PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
        //標準簽名算法名稱(RSA還是RSA2)
        String algorithm = RSA_KEY_ALGORITHM.equals(signType) ? RSA_SIGNATURE_ALGORITHM : RSA2_SIGNATURE_ALGORITHM;
        //用指定算法產生簽名對象Signature
        Signature signature = Signature.getInstance(algorithm);
        //用公鑰初始化簽名對象,用于驗證簽名
        signature.initVerify(publicKey);
        //更新簽名內容
        signature.update(data);
        //得到驗證結果
        return signature.verify(sign);
    }
    public static void demo() throws Exception {
        Map<String, String> stringStringMap = generateKey();
        String publicKeyStr = stringStringMap.get("publicKeyStr");
        String privateKeyStr = stringStringMap.get("privateKeyStr");
        System.out.println("-----------------生成的公鑰和私鑰------------------------------");
        System.out.println("獲取到的公鑰:" + publicKeyStr);
        System.out.println("獲取到的私鑰:" + privateKeyStr);
        // 待加密數(shù)據(jù)
        String data = "tranSeq=1920542585&amount=100&payType=wechat";
        // 公鑰加密
        System.out.println("---------公鑰--------加密和解密------------------------------");
        System.out.println("待加密的數(shù)據(jù):" + data);
        String encrypt = RsaUtils.encryptByPublicKey(data, publicKeyStr);
        System.out.println("加密后數(shù)據(jù):" + encrypt);
        // 私鑰解密
        String decrypt = RsaUtils.decryptByPrivateKey(encrypt, privateKeyStr);
        System.out.println("解密后數(shù)據(jù):" + decrypt);
        // 私鑰加密
        System.out.println("----------私鑰-------加密和解密------------------------------");
        System.out.println("待加密的數(shù)據(jù):" + data);
        encrypt = RsaUtils.encryptByPrivateKey(data, privateKeyStr);
        System.out.println("加密后數(shù)據(jù):" + encrypt);
        // 私鑰解密
        decrypt = RsaUtils.decryptByPublicKey(encrypt, publicKeyStr);
        System.out.println("解密后數(shù)據(jù):" + decrypt);
    }
}

到此這篇關于Java http加簽、驗簽實現(xiàn)方案的文章就介紹到這了,更多相關Java http加簽、驗簽內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Springboot處理異常的常見方式

    Springboot處理異常的常見方式

    SpringBoot框架異常處理有多種處理方式,今天就帶大家了解一下常見的springboot異常處理方式,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • 一個牛人給Java初學者的建議(必看篇)

    一個牛人給Java初學者的建議(必看篇)

    下面小編就為大家?guī)硪黄粋€牛人給Java初學者的建議(必看篇)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-05-05
  • VSCode新手教程之配置Java環(huán)境的詳細教程

    VSCode新手教程之配置Java環(huán)境的詳細教程

    這篇文章主要給大家介紹了關于VSCode新手教程之配置Java環(huán)境的詳細教程,工欲善其事必先利其器,想要工作順利我們先搭建好JAVA的開發(fā)環(huán)境,需要的朋友可以參考下
    2023-10-10
  • Java實現(xiàn)簡單的斗地主游戲

    Java實現(xiàn)簡單的斗地主游戲

    這篇文章主要為大家詳細介紹了Java實現(xiàn)簡單的斗地主游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • idea設置@Author文件頭注釋的實現(xiàn)步驟

    idea設置@Author文件頭注釋的實現(xiàn)步驟

    本文主要介紹了idea設置@Author文件頭注釋的實現(xiàn)步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-07-07
  • java8根據(jù)某一屬性過濾去重的實例

    java8根據(jù)某一屬性過濾去重的實例

    這篇文章主要介紹了java8根據(jù)某一屬性過濾去重的實例,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Java跨模塊調用方式

    Java跨模塊調用方式

    這篇文章主要介紹了Java跨模塊調用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 如何使用IntelliJ?IDEA進行Java內存分析詳解

    如何使用IntelliJ?IDEA進行Java內存分析詳解

    這篇文章主要介紹了如何使用IntelliJ?IDEA進行Java內存分析的相關資料,包括內存消耗情況的查看、內存泄漏的分析、垃圾回收情況的優(yōu)化等,通過IntelliJIDEA提供的工具,開發(fā)者可以有效地提升應用程序的性能和穩(wěn)定性,需要的朋友可以參考下
    2025-05-05
  • Java的List集合中泛型使用詳解

    Java的List集合中泛型使用詳解

    這篇文章主要介紹了Java的List集合中泛型使用詳解,泛型類,如果沒有指定具體的數(shù)據(jù)類型,此時,操作類型是Object,泛型的類型參數(shù)只能是類類型,不能是基本數(shù)據(jù)類型,需要的朋友可以參考下
    2023-12-12
  • JAVA后臺實現(xiàn)文件批量下載方式

    JAVA后臺實現(xiàn)文件批量下載方式

    這篇文章主要介紹了JAVA后臺實現(xiàn)文件批量下載方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05

最新評論

石柱| 太白县| 西青区| 久治县| 新野县| 墨竹工卡县| 清远市| 麻城市| 宁武县| 鹤壁市| 恭城| 本溪市| 云浮市| 吴旗县| 旬阳县| 凯里市| 竹溪县| 绥德县| 玉溪市| 汤阴县| 常山县| 临邑县| 精河县| 林口县| 庆安县| 德兴市| 合水县| 镇雄县| 井研县| 沂南县| 海安县| 双流县| 祁连县| 普兰县| 永兴县| 六盘水市| 北海市| 紫阳县| 昌黎县| 醴陵市| 湟源县|