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

SpringBoot集成iText實(shí)現(xiàn)電子簽章功能

 更新時(shí)間:2024年10月23日 10:50:00   作者:江南一點(diǎn)雨  
這篇文章主要為大家詳細(xì)介紹了SpringBoot如何集成iText實(shí)現(xiàn)電子簽章功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

一 電子簽章

1.1 什么是電子簽章

基于《中華人民共和國電子簽名法》等相關(guān)法規(guī)和技術(shù)規(guī)范,具有法律效力的電子簽章一定是需要使用 CA 數(shù)字證書進(jìn)行對(duì)文件簽名,并把 CA 數(shù)字證書存放在簽名后文件中。

如果一份簽名后的電子文件中無法查看到 CA 數(shù)字證書,僅存在一個(gè)公章圖片,那么就不屬于法律意義上的電子簽名。電子簽名法規(guī)定電子文件簽署時(shí)一定要使用CA數(shù)字證書,并沒有要求一定需要含有電子印章圖片,理論上電子簽章不需要到公安局進(jìn)行備案。

實(shí)際上,電子簽章是在電子簽名技術(shù)的基礎(chǔ)上添加了印章圖像外觀,沿襲了人們所習(xí)慣的傳統(tǒng)蓋章可視效果。電子簽章使用電子簽名技術(shù)來保障電子文件內(nèi)容的防篡改性和簽署者的不可否認(rèn)性。因此,電子簽章中,印章圖片并不是唯一鑒別是否簽章的條件,還要鑒別是否使用高級(jí)電子簽名技術(shù)和 CA 數(shù)字證書。

CA 數(shù)字證書是在互聯(lián)網(wǎng)中用于識(shí)別身份的一種具有權(quán)威性的電子文檔。CA 數(shù)字證書相當(dāng)于現(xiàn)實(shí)中的身份證。

現(xiàn)實(shí)中,如同個(gè)人需要去公安局申請(qǐng)辦理身份證一樣,CA 數(shù)字證書需要在“電子認(rèn)證服務(wù)機(jī)構(gòu)”(簡(jiǎn)稱 CA 機(jī)構(gòu))進(jìn)行申請(qǐng)辦理。中國工業(yè)和信息化部、工信部授權(quán) CA 機(jī)構(gòu)來制作、簽發(fā)數(shù)字證書,用非對(duì)稱加密的方式,生成一對(duì)密碼即私鑰與公開密鑰,并綁定了數(shù)字證書持有者的真實(shí)身份,人們可以在電子合同的締約過程中用它來證明自己的身份和驗(yàn)證對(duì)方的身份。

CA 機(jī)構(gòu)頒發(fā)的數(shù)字證書為公鑰證書和私鑰證書:公鑰證書是對(duì)外公開、任何人都可以使用的,而私鑰是專屬于簽署人所有的。當(dāng)需要簽署文檔時(shí),簽署人使用私鑰證書對(duì)電子文件(文檔哈希值)進(jìn)行加密,形成電子簽名。 (注:文檔哈希值計(jì)算時(shí)包含待簽 PDF 文檔內(nèi)容、印章圖片和印章坐標(biāo)位置信息)

哈希值是指將 PDF 文件按照一定的算法(目前主流是 SHA256 算法),形成一個(gè)唯一的文件代碼,類似于人類的指紋,任何一個(gè) PDF 文件只有一個(gè)哈希值,且不同 PDF 文件的哈希值不可能相同,而相同哈希值的 PDF 文件的內(nèi)容肯定相同。哈希算法是不可逆的,從哈希值無法推導(dǎo)出 PDF 原文內(nèi)容。

經(jīng)簽署人的私鑰證書加密之后的 PDF 原文哈希值就是電子簽名,電子簽名中有簽署人的姓名、身份證號(hào)碼、證書有效期、公鑰等信息,電子簽名放在 PDF 原文的簽名域中,就形成了帶有電子簽名的 PDF 文件。

1.2 簽名流程

文件電子簽名過程,如下圖:

其他人收到這個(gè)文件,即可使用PDF文件的簽名域中存儲(chǔ)的公鑰證書對(duì)電子簽名進(jìn)行解密,解密出來的文件哈希值如果與原文的哈希值一致,則代表這個(gè)文件沒有被篡改。

電子簽名文件驗(yàn)簽過程,如下圖:

1.3 技術(shù)選型

這塊主要有兩大技術(shù)體系:

  • 開源組織 Apache 的 PDFBox。
  • Adobe 的 iText,其中 iText 又分為 iText5 和 iText7。

那么這兩個(gè)該如何選擇呢?

  • PDFBox 的功能相對(duì)較弱,iText5 和 iText7 的功能非常強(qiáng)悍。
  • iText5 資料網(wǎng)上相對(duì)較多,如果出現(xiàn)問題容易找到解決方案。
  • PDFBox 和 iText7 的網(wǎng)上資料相對(duì)較少,如果出現(xiàn)問題不易找到相關(guān)解決方案。
  • PDFBox 目前提供的自定義簽章接口不完整;而 iText5 和 iText7 提供了處理自定義簽章的相關(guān)實(shí)現(xiàn)。
  • PDFBox 只能實(shí)現(xiàn)把簽章圖片加簽到 PDF 文件;iText5 和 iText7 除了可以把簽章圖片加簽到 PDF 文件,還可以實(shí)現(xiàn)直接對(duì)簽章進(jìn)行繪制,把文件繪制到簽章上。
  • PDFBox 和 iText5/iText7 使用的協(xié)議不一樣。PDFBox 使用的是 APACHE LICENSE VERSION 2.0(Licenses);iText5/iText7 使用的是 AGPL(itextpdf.com/agpl)。PDFBox免費(fèi)使用,AGPL 商用收費(fèi)。

因此這里松哥就以 iText5 為例來和小伙伴們演示如何給一個(gè) PDF 文件簽名。

二 實(shí)戰(zhàn)

2.1 生成數(shù)字證書

首先我們需要生成一個(gè)數(shù)字證書。

這個(gè)數(shù)字證書我們可以利用 JDK 自帶的工具生成,為了貼近實(shí)戰(zhàn),松哥這里使用 Java 代碼生成,生成數(shù)字證書的方式如下。

首先引入 Bouncy Castle,Bouncy Castle 是一個(gè)廣泛使用的開源加密庫,它為 Java 平臺(tái)提供了豐富的密碼學(xué)算法實(shí)現(xiàn),包括對(duì)稱加密、非對(duì)稱加密、哈希算法、數(shù)字簽名等。這個(gè)庫由于其廣泛的算法支持和可靠性而備受信任,被許多安全應(yīng)用和加密通信協(xié)議所采用 。

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcpkix-jdk15on</artifactId>
    <version>1.70</version>
</dependency>
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-ext-jdk15on</artifactId>
    <version>1.70</version>
</dependency>

接下來我們寫一個(gè)生成數(shù)字證書的工具類,如下:

import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.*;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;

import java.io.*;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author:江南一點(diǎn)雨
 * @site:http://www.javaboy.org
 * @微信公眾號(hào):江南一點(diǎn)雨
 * @github:https://github.com/lenve
 * @gitee:https://gitee.com/lenve
 */
public class PkcsUtils {

    /**
     * 生成證書
     *
     * @return
     * @throws NoSuchAlgorithmException
     */
    private static KeyPair getKey() throws NoSuchAlgorithmException {
        KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA",
                new BouncyCastleProvider());
        generator.initialize(1024);
        // 證書中的密鑰 公鑰和私鑰
        KeyPair keyPair = generator.generateKeyPair();
        return keyPair;
    }

    /**
     * 生成證書
     *
     * @param password
     * @param issuerStr
     * @param subjectStr
     * @param certificateCRL
     * @return
     */
    public static Map<String, byte[]> createCert(String password, String issuerStr, String subjectStr, String certificateCRL) {
        Map<String, byte[]> result = new HashMap<String, byte[]>();
        try(ByteArrayOutputStream out= new ByteArrayOutputStream()) {
            // 標(biāo)志生成PKCS12證書
            KeyStore keyStore = KeyStore.getInstance("PKCS12", new BouncyCastleProvider());
            keyStore.load(null, null);
            KeyPair keyPair = getKey();
            // issuer與 subject相同的證書就是CA證書
            X509Certificate cert = generateCertificateV3(issuerStr, subjectStr,
                    keyPair, result, certificateCRL);
            // 證書序列號(hào)
            keyStore.setKeyEntry("cretkey", keyPair.getPrivate(),
                    password.toCharArray(), new X509Certificate[]{cert});
            cert.verify(keyPair.getPublic());
            keyStore.store(out, password.toCharArray());
            byte[] keyStoreData = out.toByteArray();
            result.put("keyStoreData", keyStoreData);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 生成證書
     * @param issuerStr
     * @param subjectStr
     * @param keyPair
     * @param result
     * @param certificateCRL
     * @return
     */
    public static X509Certificate generateCertificateV3(String issuerStr,
                                                        String subjectStr, KeyPair keyPair, Map<String, byte[]> result,
                                                        String certificateCRL) {
        ByteArrayInputStream bint = null;
        X509Certificate cert = null;
        try {
            PublicKey publicKey = keyPair.getPublic();
            PrivateKey privateKey = keyPair.getPrivate();
            Date notBefore = new Date();
            Calendar rightNow = Calendar.getInstance();
            rightNow.setTime(notBefore);
            // 日期加1年
            rightNow.add(Calendar.YEAR, 1);
            Date notAfter = rightNow.getTime();
            // 證書序列號(hào)
            BigInteger serial = BigInteger.probablePrime(256, new Random());
            X509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(
                    new X500Name(issuerStr), serial, notBefore, notAfter,
                    new X500Name(subjectStr), publicKey);
            JcaContentSignerBuilder jBuilder = new JcaContentSignerBuilder(
                    "SHA1withRSA");
            SecureRandom secureRandom = new SecureRandom();
            jBuilder.setSecureRandom(secureRandom);
            ContentSigner singer = jBuilder.setProvider(
                    new BouncyCastleProvider()).build(privateKey);
            // 分發(fā)點(diǎn)
            ASN1ObjectIdentifier cRLDistributionPoints = new ASN1ObjectIdentifier(
                    "2.5.29.31");
            GeneralName generalName = new GeneralName(
                    GeneralName.uniformResourceIdentifier, certificateCRL);
            GeneralNames seneralNames = new GeneralNames(generalName);
            DistributionPointName distributionPoint = new DistributionPointName(
                    seneralNames);
            DistributionPoint[] points = new DistributionPoint[1];
            points[0] = new DistributionPoint(distributionPoint, null, null);
            CRLDistPoint cRLDistPoint = new CRLDistPoint(points);
            builder.addExtension(cRLDistributionPoints, true, cRLDistPoint);
            // 用途
            ASN1ObjectIdentifier keyUsage = new ASN1ObjectIdentifier(
                    "2.5.29.15");
            // | KeyUsage.nonRepudiation | KeyUsage.keyCertSign
            builder.addExtension(keyUsage, true, new KeyUsage(
                    KeyUsage.digitalSignature | KeyUsage.keyEncipherment));
            // 基本限制 X509Extension.java
            ASN1ObjectIdentifier basicConstraints = new ASN1ObjectIdentifier(
                    "2.5.29.19");
            builder.addExtension(basicConstraints, true, new BasicConstraints(
                    true));
            X509CertificateHolder holder = builder.build(singer);
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            bint = new ByteArrayInputStream(holder.toASN1Structure()
                    .getEncoded());
            cert = (X509Certificate) cf.generateCertificate(bint);
            byte[] certBuf = holder.getEncoded();
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            // 證書數(shù)據(jù)
            result.put("certificateData", certBuf);
            //公鑰
            result.put("publicKey", publicKey.getEncoded());
            //私鑰
            result.put("privateKey", privateKey.getEncoded());
            //證書有效開始時(shí)間
            result.put("notBefore", format.format(notBefore).getBytes("utf-8"));
            //證書有效結(jié)束時(shí)間
            result.put("notAfter", format.format(notAfter).getBytes("utf-8"));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (bint != null) {
                try {
                    bint.close();
                } catch (IOException e) {
                }
            }
        }
        return cert;
    }

    public static void main(String[] args) throws Exception {
        // CN: 名字與姓氏    OU : 組織單位名稱
        // O :組織名稱  L : 城市或區(qū)域名稱  E : 電子郵件
        // ST: 州或省份名稱  C: 單位的兩字母國家代碼
        String issuerStr = "CN=javaboy,OU=產(chǎn)品研發(fā)部,O=江南一點(diǎn)雨,C=CN,E=javaboy@gmail.com,L=華南,ST=深圳";
        String subjectStr = "CN=javaboy,OU=產(chǎn)品研發(fā)部,O=江南一點(diǎn)雨,C=CN,E=javaboy@gmail.com,L=華南,ST=深圳";
        String certificateCRL = "http://www.javaboy.org";
        Map<String, byte[]> result = createCert("123456", issuerStr, subjectStr, certificateCRL);

        FileOutputStream outPutStream = new FileOutputStream("keystore.p12");
        outPutStream.write(result.get("keyStoreData"));
        outPutStream.close();
        FileOutputStream fos = new FileOutputStream(new File("keystore.cer"));
        fos.write(result.get("certificateData"));
        fos.flush();
        fos.close();
    }

}

運(yùn)行這個(gè)工具代碼,會(huì)在我們當(dāng)前工程目錄下生成 keystore.p12keystore.cer 兩個(gè)文件。

其中 keystore.cer 文件通常是一個(gè)以 DER 或 PEM 格式存儲(chǔ)的 X.509 公鑰證書,它包含了公鑰以及證書所有者的信息,如姓名、組織、地理位置等。

keystore.p12 文件是一個(gè) PKCS#12 格式的文件,它是一個(gè)個(gè)人信息交換標(biāo)準(zhǔn),用于存儲(chǔ)一個(gè)或多個(gè)證書以及它們對(duì)應(yīng)的私鑰。.p12 文件是加密的,通常需要密碼才能打開。這種文件格式便于將證書和私鑰一起分發(fā)或存儲(chǔ),常用于需要在不同系統(tǒng)或設(shè)備間傳輸證書和私鑰的場(chǎng)景。

總結(jié)下就是,.cer 文件通常只包含公鑰證書,而 .p12 文件可以包含證書和私鑰。

2.2 生成印章圖片

接下來我們用 Java 代碼繪制一個(gè)簽章圖片,如下:

public class SealSample {
    public static void main(String[] args) throws Exception {
        Seal seal = new Seal();
        seal.setSize(200);
        SealCircle sealCircle = new SealCircle();
        sealCircle.setLine(4);
        sealCircle.setWidth(95);
        sealCircle.setHeight(95);
        seal.setBorderCircle(sealCircle);
        SealFont mainFont = new SealFont();
        mainFont.setText("江南一點(diǎn)雨股份有限公司");
        mainFont.setSize(22);
        mainFont.setFamily("隸書");
        mainFont.setSpace(22.0);
        mainFont.setMargin(4);
        seal.setMainFont(mainFont);
        SealFont centerFont = new SealFont();
        centerFont.setText("★");
        centerFont.setSize(60);
        seal.setCenterFont(centerFont);
        SealFont titleFont = new SealFont();
        titleFont.setText("財(cái)務(wù)專用章");
        titleFont.setSize(16);
        titleFont.setSpace(8.0);
        titleFont.setMargin(54);
        seal.setTitleFont(titleFont);
        seal.draw("公章1.png");
    }
}

最終生成的簽章圖片類似下面這樣:

現(xiàn)在萬事具備,可以給 PDF 簽名了。

2.3 PDF 簽名

最后,我們可以通過如下代碼為 PDF 進(jìn)行簽名。

這里我們通過 iText 來實(shí)現(xiàn)電子簽章,因此需要先引入 iText:

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13.4</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>html2pdf</artifactId>
    <version>5.0.5</version>
</dependency>

接下來對(duì) PDF 文件進(jìn)行簽名:

public class SignPdf2 {

    /**
     * @param password pkcs12證書密碼
     * @param keyStorePath pkcs12證書路徑
     * @param signPdfSrc 簽名pdf路徑
     * @param signImage 簽名圖片
     * @param x
     * @param y
     * @return
     */
    public static byte[] sign(String password, String keyStorePath, String signPdfSrc, String signImage,
                              float x, float y) {
        File signPdfSrcFile = new File(signPdfSrc);
        PdfReader reader = null;
        ByteArrayOutputStream signPDFData = null;
        PdfStamper stp = null;
        FileInputStream fos = null;
        try {
            BouncyCastleProvider provider = new BouncyCastleProvider();
            Security.addProvider(provider);
            KeyStore ks = KeyStore.getInstance("PKCS12", new BouncyCastleProvider());
            fos = new FileInputStream(keyStorePath);
            // 私鑰密碼 為Pkcs生成證書是的私鑰密碼 123456
            ks.load(fos, password.toCharArray());
            String alias = (String) ks.aliases().nextElement();
            PrivateKey key = (PrivateKey) ks.getKey(alias, password.toCharArray());
            Certificate[] chain = ks.getCertificateChain(alias);
            reader = new PdfReader(signPdfSrc);
            signPDFData = new ByteArrayOutputStream();
            // 臨時(shí)pdf文件
            File temp = new File(signPdfSrcFile.getParent(), System.currentTimeMillis() + ".pdf");
            stp = PdfStamper.createSignature(reader, signPDFData, '\0', temp, true);
            stp.setFullCompression();
            PdfSignatureAppearance sap = stp.getSignatureAppearance();
            sap.setReason("數(shù)字簽名,不可改變");
            // 使用png格式透明圖片
            Image image = Image.getInstance(signImage);
            sap.setImageScale(0);
            sap.setSignatureGraphic(image);
            sap.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC);
            // 是對(duì)應(yīng)x軸和y軸坐標(biāo)
            sap.setVisibleSignature(new Rectangle(x, y, x + 185, y + 68), 1,
                    UUID.randomUUID().toString().replaceAll("-", ""));
            stp.getWriter().setCompressionLevel(5);
            ExternalDigest digest = new BouncyCastleDigest();
            ExternalSignature signature = new PrivateKeySignature(key, DigestAlgorithms.SHA512, provider.getName());
            MakeSignature.signDetached(sap, digest, signature, chain, null, null, null, 0, MakeSignature.CryptoStandard.CADES);
            stp.close();
            reader.close();
            return signPDFData.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {

            if (signPDFData != null) {
                try {
                    signPDFData.close();
                } catch (IOException e) {
                }
            }

            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                }
            }
        }
        return null;
    }

    public static void main(String[] args) throws Exception {
        byte[] fileData = sign("123456", "keystore.p12", 
                "待簽名.pdf",//
                "公章1.png", 100, 290);
        FileOutputStream f = new FileOutputStream(new File("已簽名.pdf"));
        f.write(fileData);
        f.close();
    }
}

這里所需要的參數(shù)基本上前文都提過了,不再多說。

從表面上看,簽名結(jié)束之后,PDF 文件上多了一個(gè)印章,如下:

本質(zhì)上,則是該 PDF 文件多了一個(gè)簽名信息,通過 Adobe 的 PDF 軟件可以查看,如下:

之所以顯示簽名有效性未知,是因?yàn)槲覀兪褂玫氖亲约荷傻臄?shù)字證書,如果從權(quán)威機(jī)構(gòu)申請(qǐng)的數(shù)字證書,就不會(huì)出現(xiàn)這個(gè)提示。

以上就是SpringBoot集成iText實(shí)現(xiàn)電子簽章功能的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot iText電子簽章的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring.Net在MVC中實(shí)現(xiàn)注入的原理解析

    Spring.Net在MVC中實(shí)現(xiàn)注入的原理解析

    這篇文章主要介紹了Spring.Net在MVC中實(shí)現(xiàn)注入的原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • Struts2實(shí)現(xiàn)文件上傳功能實(shí)例解析

    Struts2實(shí)現(xiàn)文件上傳功能實(shí)例解析

    這篇文章主要介紹了Struts2實(shí)現(xiàn)文件上傳功能實(shí)例解析,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-01-01
  • Java8函數(shù)式接口java.util.function速查大全

    Java8函數(shù)式接口java.util.function速查大全

    因?yàn)镴ava8引入了函數(shù)式接口,在java.util.function包含了幾大類函數(shù)式接口聲明,這篇文章主要給大家介紹了關(guān)于Java8函數(shù)式接口java.util.function速查的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • Spring深入講解實(shí)現(xiàn)AOP的三種方式

    Spring深入講解實(shí)現(xiàn)AOP的三種方式

    Spring的AOP就是通過動(dòng)態(tài)代理實(shí)現(xiàn)的,使用了兩個(gè)動(dòng)態(tài)代理,分別是JDK的動(dòng)態(tài)代理和CGLIB動(dòng)態(tài)代理,本文重點(diǎn)給大家介紹下Spring?Aop的三種實(shí)現(xiàn),感興趣的朋友一起看看吧
    2022-05-05
  • mybatis-plus自動(dòng)生成代碼的示例代碼

    mybatis-plus自動(dòng)生成代碼的示例代碼

    這篇文章主要介紹了mybatis-plus自動(dòng)生成代碼的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Java實(shí)現(xiàn)導(dǎo)入csv的示例代碼

    Java實(shí)現(xiàn)導(dǎo)入csv的示例代碼

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)導(dǎo)入csv的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-03-03
  • Java 并發(fā)編程學(xué)習(xí)筆記之Synchronized底層優(yōu)化

    Java 并發(fā)編程學(xué)習(xí)筆記之Synchronized底層優(yōu)化

    這篇文章主要介紹了Java 并發(fā)編程學(xué)習(xí)筆記之Synchronized底層優(yōu)化的相關(guān)資料,主要包含了重量級(jí)鎖,輕量級(jí)鎖,偏向鎖和其他優(yōu)化等方面,有需要的小伙伴可以參考下
    2016-05-05
  • Java如何獲取對(duì)象屬性及對(duì)應(yīng)值

    Java如何獲取對(duì)象屬性及對(duì)應(yīng)值

    這篇文章主要介紹了Java如何獲取對(duì)象屬性及對(duì)應(yīng)值,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • SpringMVC整合websocket實(shí)現(xiàn)消息推送及觸發(fā)功能

    SpringMVC整合websocket實(shí)現(xiàn)消息推送及觸發(fā)功能

    這篇文章主要為大家詳細(xì)介紹了SpringMVC整合websocket實(shí)現(xiàn)消息推送及觸發(fā)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • response.setContentType()參數(shù)以及作用詳解

    response.setContentType()參數(shù)以及作用詳解

    這篇文章主要介紹了response.setContentType()參數(shù)以及作用詳解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08

最新評(píng)論