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

SpringBoot中集成串口通信的項(xiàng)目實(shí)踐

 更新時(shí)間:2023年08月02日 11:35:04   作者:空山返景  
本文主要介紹了SpringBoot中集成串口通信,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

串口通信介紹

  • 串口通信是一種按位發(fā)送和接收字節(jié)的簡(jiǎn)單概念,盡管比并行通信慢,但串口可以同時(shí)使用一根線發(fā)送數(shù)據(jù)和接收數(shù)據(jù)。
  • 串口通信簡(jiǎn)單且能夠?qū)崿F(xiàn)遠(yuǎn)距離通信,例如,串口的長(zhǎng)度可達(dá)1200米,而并行通信的長(zhǎng)度限制為20米.
  • 串口通常用于ASCII碼字符的傳輸,通信使用地線、發(fā)送線和接收線三根線完成。
  • 重要的參數(shù)有波特率、數(shù)據(jù)位、停止位和奇偶校驗(yàn)。

波特率

這是一個(gè)衡量符號(hào)傳輸速率的參數(shù)。指的是信號(hào)被調(diào)制以后在單位時(shí)間內(nèi)的變化,即單位時(shí)間內(nèi)載波參數(shù)變化的次數(shù),如每秒鐘傳送240個(gè)字符,而每個(gè)字符格式包含10位(1個(gè)起始位,1個(gè)停止位,8個(gè)數(shù)據(jù)位),這時(shí)的波特率為240Bd,比特率為10位*240個(gè)/秒=2400bps。一般調(diào)制速率大于波特率,比如通常電話線的波特率為14400,28800和36600。波特率可以遠(yuǎn)遠(yuǎn)大于這些值,但是波特率和距離成反比。高波特率常常用于放置的很近的儀器間的通信,典型的例子就是GPIB設(shè)備的通信

數(shù)據(jù)位

這是衡量通信中實(shí)際數(shù)據(jù)位的參數(shù)。當(dāng)計(jì)算機(jī)發(fā)送一個(gè)信息包,實(shí)際的數(shù)據(jù)往往不會(huì)是8位的,標(biāo)準(zhǔn)的值是6、7和8位。如何設(shè)置取決于你想傳送的信息。比如,標(biāo)準(zhǔn)的ASCII碼是0~127(7位)。擴(kuò)展的ASCII碼是0~255(8位)。如果數(shù)據(jù)使用簡(jiǎn)單的文本(標(biāo)準(zhǔn) ASCII碼),那么每個(gè)數(shù)據(jù)包使用7位數(shù)據(jù)。每個(gè)包是指一個(gè)字節(jié),包括開始/停止位,數(shù)據(jù)位和奇偶校驗(yàn)位。由于實(shí)際數(shù)據(jù)位取決于通信協(xié)議的選取,術(shù)語(yǔ)“包”指任何通信的情況。

停止位

用于表示單個(gè)包的最后一位。典型的值為1,1.5和2位。由于數(shù)據(jù)是在傳輸線上定時(shí)的,并且每一個(gè)設(shè)備有其自己的時(shí)鐘,很可能在通信中兩臺(tái)設(shè)備間出現(xiàn)了小小的不同步。因此停止位不僅僅是表示傳輸?shù)慕Y(jié)束,并且提供計(jì)算機(jī)校正時(shí)鐘同步的機(jī)會(huì)。適用于停止位的位數(shù)越多,不同時(shí)鐘同步的容忍程度越大,但是數(shù)據(jù)傳輸率同時(shí)也越慢。

奇偶校驗(yàn)位

在串口通信中一種簡(jiǎn)單的檢錯(cuò)方式。有四種檢錯(cuò)方式:偶、奇、高和低。當(dāng)然沒有校驗(yàn)位也是可以的。對(duì)于偶和奇校驗(yàn)的情況,串口會(huì)設(shè)置校驗(yàn)位(數(shù)據(jù)位后面的一位),用一個(gè)值確保傳輸?shù)臄?shù)據(jù)有偶個(gè)或者奇?zhèn)€邏輯高位。例如,如果數(shù)據(jù)是011,那么對(duì)于偶校驗(yàn),校驗(yàn)位為0,保證邏輯高的位數(shù)是偶數(shù)個(gè)。如果是奇校驗(yàn),校驗(yàn)位為1,這樣就有3個(gè)邏輯高位。高位和低位不真正的檢查數(shù)據(jù),簡(jiǎn)單置位邏輯高或者邏輯低校驗(yàn)。這樣使得接收設(shè)備能夠知道一個(gè)位的狀態(tài),有機(jī)會(huì)判斷是否有噪聲干擾了通信或者是否傳輸和接收數(shù)據(jù)是否不同步。

開始集成

組件介紹

對(duì)于Java集成串口通信,常見的選擇有 原生Java串口通信API、RXTX庫(kù)、jSerialComm庫(kù),

  • 原生Java串口通信API只支持到Java6版本,后續(xù)便不再維護(hù),所以不推薦使用
  • RXTX庫(kù)是過(guò)去主流開發(fā)串口通信使用的依賴組件,但是由于需要在jvm包中添加指定的依賴組件,其次,RXTX的穩(wěn)定性和兼容性可能存在一些問題,且僅維護(hù)至Jdk8版本,后續(xù)不再持續(xù)維護(hù)了,所以本次也不考慮使用它
  • 所以本次采用的是jSerialComm庫(kù),以下是jSerialComm庫(kù)的一些主要特點(diǎn)和功能:
    • 跨平臺(tái)支持:jSerialComm可以在多個(gè)操作系統(tǒng)上使用,包括Windows、Linux和MacOS等。
    • 多串口支持:它可以同時(shí)管理多個(gè)串口,通過(guò)獲取和管理已連接的串口列表,方便選擇和使用特定的串口。
    • 簡(jiǎn)單的API:jSerialComm提供了簡(jiǎn)潔易用的API,使串口的打開、讀取、寫入和關(guān)閉等操作變得簡(jiǎn)單和直觀。
    • 支持異步讀?。嚎梢允褂没卣{(diào)函數(shù)或監(jiān)聽器來(lái)異步讀取串口數(shù)據(jù),實(shí)現(xiàn)非阻塞的讀取操作。
    • 高性能:jSerialComm使用了底層的串口通信庫(kù),具有高效的讀寫性能,適用于處理大量的串口數(shù)據(jù)。
    • 可靠性和穩(wěn)定性:它經(jīng)過(guò)了充分測(cè)試和優(yōu)化,具有良好的穩(wěn)定性和可靠性,能夠處理各種串口通信場(chǎng)景。
    • 開源免費(fèi):jSerialComm是一個(gè)開源庫(kù),使用MIT許可證,可以免費(fèi)使用和修改。

Maven依賴導(dǎo)入

<!--    COM串口通信    -->
        <dependency>
            <groupId>com.fazecast</groupId>
            <artifactId>jSerialComm</artifactId>
            <version>2.6.2</version>
        </dependency>
        <!--    hutool工具    -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.6.5</version>
        </dependency>

配置類

創(chuàng)建一個(gè) SerialConfig 用于定義串口通用信息配置

import com.fazecast.jSerialComm.SerialPort;
import lombok.Data;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
/**
?* ?用于定義串口通用信息配置
?* */
@Configuration
public class SerialConfig {
? ? /**
? ? ?* ?波特率
? ? ?* */
? ? public static int baudRate = 19200;
? ? /**
? ? ?* 數(shù)據(jù)位
? ? ?*/
? ? public static int dataBits = 8;
? ? /**
? ? ?* 停止位 ( 1停止位 = 1 ?、 1.5停止位 = 2 、2停止位 = 3)
? ? ?* */
? ? public static int stopBits = 1;
? ? /**
? ? ?* 校驗(yàn)?zāi)J?( 無(wú)校驗(yàn) = 0 ?、奇校驗(yàn) = 1 、偶校驗(yàn) = 2、 標(biāo)記校驗(yàn) = 3、 空格校驗(yàn) = 4 ?)
? ? ?* */
? ? public static int parity = 1;
? ? /**
? ? ?* ?是否為 Rs485通信
? ? ?* */
? ? public static boolean rs485Mode = true;
? ? /**
? ? ?* ?串口讀寫超時(shí)時(shí)間(毫秒)
? ? ?* */
? ? public static int timeOut = 300;
? ? /**
? ? ?* 消息模式
? ? ?* 非阻塞模式: #TIMEOUT_NONBLOCKING ? ? ? ? ? 【在該模式下,readBytes(byte[], long)和writeBytes(byte[], long)調(diào)用將立即返回任何可用數(shù)據(jù)?!?
? ? ?* 寫阻塞模式: #TIMEOUT_WRITE_BLOCKING ? ? ? ?【在該模式下,writeBytes(byte[], long)調(diào)用將阻塞,直到所有數(shù)據(jù)字節(jié)都成功寫入輸出串口設(shè)備?!?
? ? ?* 半阻塞讀取模式: #TIMEOUT_READ_SEMI_BLOCKING 【在該模式下,readBytes(byte[], long)調(diào)用將阻塞,直到達(dá)到指定的超時(shí)時(shí)間或者至少可讀取1個(gè)字節(jié)的數(shù)據(jù)。】
? ? ?* 全阻塞讀取模式:#TIMEOUT_READ_BLOCKING ? ? ? 【在該模式下,readBytes(byte[], long)調(diào)用將阻塞,直到達(dá)到指定的超時(shí)時(shí)間或者可以返回請(qǐng)求的字節(jié)數(shù)?!?
? ? ?* 掃描器模式:#TIMEOUT_SCANNER ? ? ? ? ? ? ? ?【該模式適用于使用Java的java.util.Scanner類從串口進(jìn)行讀取,會(huì)忽略手動(dòng)指定的超時(shí)值以確保與Java規(guī)范的兼容性】
? ? ?* */
? ? public static int messageModel = SerialPort.TIMEOUT_READ_BLOCKING;
? ? /**
? ? ?* ?已打開的COM串口 (重復(fù)打開串口會(huì)導(dǎo)致后面打開的無(wú)法使用,所以打開一次就要記錄到公共變量存儲(chǔ))
? ? ?* */
? ? public final static Map<String, SerialPort> portMap = new HashMap<>();
}

串口工具類

準(zhǔn)備一個(gè)SerialService 用于創(chuàng)建串口,關(guān)閉串口,收發(fā)消息

import cn.hutool.core.codec.BCD;  
import com.fazecast.jSerialComm.SerialPort;  
import com.tce.station.common.config.SerialConfig;  
import lombok.AllArgsConstructor;  
import lombok.extern.slf4j.Slf4j;  
import org.springframework.stereotype.Service;  
import java.io.InputStream;  
import java.util.Arrays;  
import java.util.HashMap;  
import java.util.List;  
import java.util.Map;  
/**  
* 串口服務(wù)類  
* */  
@AllArgsConstructor  
@Slf4j  
@Service  
public class SerialService {  
/**  
* 獲取串口及狀態(tài)  
* */  
public Map<String, Boolean> getPortStatus(){  
        Map<String, Boolean> comStatusMap = new HashMap<>();  
        List<SerialPort> commPorts = Arrays.asList(SerialPort.getCommPorts());  
        commPorts.forEach(port->{  
        comStatusMap.put(port.getSystemPortName(), port.isOpen());  
    });  
    return comStatusMap;  
}  
/**  
* 添加串口連接  
* */  
public void connectSerialPort(String portName){  
    SerialPort commPort = SerialPort.getCommPort(portName);  
    if (commPort.isOpen()){  
        throw new RuntimeException("該串口已被占用");  
    }  
    if (SerialConfig.portMap.containsKey(portName)){  
        throw new RuntimeException("該串口已被占用");  
    }  
    // 打開端口  
    commPort.openPort();  
    if (!commPort.isOpen()){  
        throw new RuntimeException("打開串口失敗");  
    }  
    // 設(shè)置串口參數(shù) (波特率、數(shù)據(jù)位、停止位、校驗(yàn)?zāi)J?、是否為Rs485)  
    commPort.setComPortParameters(SerialConfig.baudRate, SerialConfig.dataBits,SerialConfig.stopBits, SerialConfig.stopBits, SerialConfig.rs485Mode);  
    // 設(shè)置串口超時(shí)和模式  
    commPort.setComPortTimeouts(SerialConfig.messageModel ,SerialConfig.timeOut, SerialConfig.timeOut);  
    // 添加至串口記錄Map  
    SerialConfig.portMap.put(portName, commPort);  
}  
/**  
* 關(guān)閉串口連接  
* */  
public boolean closeSerialPort(String portName){  
    if (!SerialConfig.portMap.containsKey(portName)){  
        throw new RuntimeException("該串口未啟用");  
    }  
    // 獲取串口  
    SerialPort port = SerialConfig.portMap.get(portName);  
    // 關(guān)閉串口  
    port.closePort();  
    // 需要等待一些時(shí)間,否則串口關(guān)閉不完全,會(huì)導(dǎo)致無(wú)法打開  
    try {  
        Thread.sleep(3000);  
    } catch (InterruptedException e) {  
        throw new RuntimeException(e);  
    }  
    if (port.isOpen()){  
        return false;  
    }else {  
        // 關(guān)閉成功返回  
        return true;  
    }  
}  
/**  
* 串口發(fā)送數(shù)據(jù)  
* */  
public void sendComData(String portName, byte[]sendBytes){  
    if (!SerialConfig.portMap.containsKey(portName)){  
        throw new RuntimeException("該串口未啟用");  
    }  
    // 獲取串口  
    SerialPort port = SerialConfig.portMap.get(portName);  
    // 發(fā)送串口數(shù)據(jù)  
    int i = port.writeBytes(sendBytes, sendBytes.length);  
    if (i == -1){  
        log.error("發(fā)送串口數(shù)據(jù)失敗{}, 數(shù)據(jù)內(nèi)容{}",portName, BCD.bcdToStr(sendBytes));  
        throw new RuntimeException("發(fā)送串口數(shù)據(jù)失敗");  
    }  
}  
/**  
* 串口讀取數(shù)據(jù)  
* */  
public byte[] readComData(String portName){  
    if (!SerialConfig.portMap.containsKey(portName)){  
        throw new RuntimeException("該串口未啟用");  
    }  
    // 獲取串口  
    SerialPort port = SerialConfig.portMap.get(portName);   
    // 讀取串口流  
    InputStream inputStream = port.getInputStream();  
    // 獲取串口返回的流大小  
    int availableBytes = 0;  
    try {  
        availableBytes = inputStream.available();  
    } catch (Exception e) {  
        e.printStackTrace();  
    }  
    // 讀取指定的范圍的數(shù)據(jù)流  
    byte[] readByte = new byte[availableBytes];  
    int bytesRead = 0;  
    try {  
        bytesRead = inputStream.read(readByte);  
    } catch (Exception e) {  
        e.printStackTrace();  
    }  
    return readByte;  
}  
}

串口業(yè)務(wù)類使用

基于以上的工具類就已經(jīng)可以對(duì)串口通信進(jìn)行開發(fā)了,以下是使用案例

1.創(chuàng)建串口連接

可以使用監(jiān)聽器方式接收數(shù)據(jù),但是需要進(jìn)行綁定,后續(xù)會(huì)介紹

// 從數(shù)據(jù)庫(kù)或者配置表中讀取設(shè)定要打開的串口
List<String> comList = comService.list();
// 關(guān)閉之前的監(jiān)聽連接(提取所有串口避免重復(fù)關(guān)閉) ?
SerialConfig.portMap.forEach((com,serialPort) ->{ ?
?? ?serialService.closeSerialPort(com); ?
});
// 等待之前的串口發(fā)送和 2倍監(jiān)聽超時(shí),避免還有串口通信線程未關(guān)閉 ?
try { ?
?? ?Thread.sleep((SerialConfig.timeOut + 1) * 2); ?
} catch (InterruptedException e) { ?
?? ?throw new RuntimeException(e); ?
}
// 清空COM口記錄 ?
SerialConfig.portMap.clear();
// 重新連接串口 ?
gunList.forEach(gun->{ ?
?? ?// 如果COM口沒有就打開 ?
?? ?if (!SerialConfig.portMap.containsKey(gun.getCom())){ ?
?? ??? ?// 創(chuàng)建連接 ?
?? ??? ?SerialPort serialPort = serialService.connectSerialPort(gun.getCom()); ?
?? ??? ?// 綁定監(jiān)聽器 ?
?? ??? ?// serialPort.addDataListener(new MessageListener()); ?
?? ?} ??
});

2.關(guān)閉串口連接

String com = "COM1";
serialService.closeSerialPort(com); 

3.定時(shí)發(fā)送串口數(shù)據(jù)

/**  
* 周期性向串口發(fā)送數(shù)據(jù)  
* */  
@Scheduled(fixedRate = 1500L)  
public void send{  
    // 因?yàn)槭亲枞潜O(jiān)聽線程,所以使用線程處理  
    Thread thread = new Thread(() -> {  
        try {  
            SerialConfig.portMap.forEach((com,serialPort)->{  
                // 等待0.1秒  
                try {  
                    Thread.sleep(100);  
                }catch (Exception e){  
                    e.printStackTrace();  
                }  
                // 調(diào)用業(yè)務(wù)邏輯獲取需要推送的數(shù)據(jù)
                byte[] sendBytes = getPushData(com);
                // 發(fā)送串口數(shù)據(jù)  
                serialService.sendComData(com, sendBytes);  
                log.info("向串口發(fā)送 {}",gun.getGunNum(), com, BCD.bcdToStr(sendBytes));  
            });  
        }catch (ConcurrentModificationException e){  
            log.info("COM口配置發(fā)生變化,等待配置生效");  
        }  
    });
    // 開啟發(fā)送線程  
    thread.start();  
}

4.周期性讀取串口數(shù)據(jù)

/**  
* 周期性讀取串口數(shù)據(jù)  
* */  
@Scheduled(fixedRate = 1000L)  
public void readComData() {  
    // 遍歷監(jiān)聽  
    SerialConfig.portMap.forEach((com,serialPort)->{  
        // 因?yàn)槭亲枞潜O(jiān)聽線程,所以使用線程處理,否則某個(gè)讀取失敗,會(huì)阻塞整個(gè)程序  
        Thread thread = new Thread(() -> {  
            byte[] readByte = serialService.readComData(com);  
            // 有數(shù)據(jù)才執(zhí)行
            if (readByte.length > 1) {  
            try {  
                log.info("收到串口數(shù)據(jù): {}", BCD.bcdToStr(readByte));  
                // 調(diào)用串口響應(yīng)業(yè)務(wù)操作  
                comOperationByData(comResult,BCD.strToBcd(res), com);  
            }catch (Exception e){  
                e.printStackTrace();  
            }  
        });  
        // 開啟線程
        thread.start();  
    }

5.監(jiān)聽式讀取串口數(shù)據(jù)

監(jiān)聽式讀取數(shù)據(jù)使用的是非阻塞行讀取數(shù)據(jù),有數(shù)據(jù)就會(huì)觸發(fā)
創(chuàng)建一個(gè)監(jiān)聽器

@Slf4j ?
public class MessageListener implements SerialPortDataListener { ?
@Autowired ?
ICommandService commandService; ?
/** ?
* 監(jiān)聽事件設(shè)置 ?
* */ ?
@Override ?
public int getListeningEvents() { ?
?? ?// 持續(xù)返回?cái)?shù)據(jù)流模式 ?
?? ?return SerialPort.LISTENING_EVENT_DATA_AVAILABLE; ?
?? ?// 收到數(shù)據(jù)立即返回 ?
?? ?// return SerialPort.LISTENING_EVENT_DATA_RECEIVED; ?
} ?
/** ?
* 收到數(shù)據(jù)監(jiān)聽回調(diào) ?
* */ ?
@Override ?
public void serialEvent(SerialPortEvent event) { ?
?? ?// 因?yàn)槭亲枞潜O(jiān)聽線程,所以使用線程處理 ?
?? ?Thread thread = new Thread(() -> { ?
?? ??? ?// 讀取串口流 ?
?? ??? ?InputStream inputStream = event.getSerialPort().getInputStream(); ?
?? ??? ?// 獲取串口返回的流大小 ?
?? ??? ?int availableBytes = 0; ?
?? ??? ?try { ?
?? ??? ??? ?availableBytes = inputStream.available(); ?
?? ??? ?} catch (Exception e) { ?
?? ??? ??? ?e.printStackTrace(); ?
?? ??? ?} ?
?? ??? ?// 讀取指定的范圍的數(shù)據(jù)流 ?
?? ??? ?byte[] readByte = new byte[availableBytes]; ?
?? ??? ?int bytesRead = 0; ?
?? ??? ?try { ?
?? ??? ??? ?bytesRead = inputStream.read(readByte); ?
?? ??? ?} catch (Exception e) { ?
?? ??? ??? ?e.printStackTrace(); ?
?? ??? ?} ?
?? ??? ?try { ?
?? ??? ??? ?inputStream.close(); ?
?? ??? ?} catch (IOException e) { ?
?? ??? ??? ?throw new RuntimeException("關(guān)閉串口流失敗"+e.getMessage()); ?
?? ??? ?} ?
?? ??? ?// 有數(shù)據(jù)才執(zhí)行
?? ??? ?if (readByte.length > 1) { ?
?? ??? ??? ?try { ?
?? ??? ??? ??? ?log.info("收到串口數(shù)據(jù): {}", BCD.bcdToStr(readByte)); ?
?? ??? ??? ??? ?// 調(diào)用串口響應(yīng)業(yè)務(wù)操作 ?
?? ??? ??? ??? ?comOperationByData(comResult,BCD.strToBcd(res), com); ?
?? ??? ??? ?}catch (Exception e){ ?
?? ??? ??? ??? ?e.printStackTrace(); ?
?? ??? ??? ?}?
?? ??? ?}?
?? ?}); ?
// 開啟線程
thread.start(); ?
} ?
}

給串口連接進(jìn)行綁定監(jiān)聽器

// 創(chuàng)建連接  
SerialPort serialPort = serialService.connectSerialPort(gun.getCom());  
// 綁定監(jiān)聽器  
serialPort.addDataListener(new MessageListener());

需要注意的是監(jiān)聽器接收數(shù)據(jù)和定時(shí)接收數(shù)據(jù)選取其中一個(gè)就好了

到此這篇關(guān)于SpringBoot中集成串口通信的項(xiàng)目實(shí)踐的文章就介紹到這了,更多相關(guān)SpringBoot 串口通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • @RefreshScope在Quartz 觸發(fā)器類導(dǎo)致異常問題解決分析

    @RefreshScope在Quartz 觸發(fā)器類導(dǎo)致異常問題解決分析

    這篇文章主要為大家介紹了@RefreshScope在Quartz 觸發(fā)器類導(dǎo)致異常問題解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • JavaWeb中的文件的上傳和下載

    JavaWeb中的文件的上傳和下載

    JavaWeb 文件的上傳和下載是指在Web應(yīng)用中實(shí)現(xiàn)用戶上傳文件到服務(wù)器和從服務(wù)器下載文件的功能,通過(guò)JavaWeb技術(shù),可以方便地實(shí)現(xiàn)文件的上傳和下載操作,提供更好的用戶體驗(yàn)和數(shù)據(jù)交互,需要的朋友可以參考下
    2023-10-10
  • Java 數(shù)組獲取最大和最小值的實(shí)例實(shí)現(xiàn)

    Java 數(shù)組獲取最大和最小值的實(shí)例實(shí)現(xiàn)

    這篇文章主要介紹了Java 數(shù)組獲取最大和最小值的實(shí)例實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • springboot配置請(qǐng)求超時(shí)時(shí)間(Http會(huì)話和接口訪問)

    springboot配置請(qǐng)求超時(shí)時(shí)間(Http會(huì)話和接口訪問)

    本文主要介紹了springboot配置請(qǐng)求超時(shí)時(shí)間,包含Http會(huì)話和接口訪問兩種,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-07-07
  • Java 8 Stream.distinct() 列表去重的操作

    Java 8 Stream.distinct() 列表去重的操作

    這篇文章主要介紹了Java 8 Stream.distinct() 列表去重的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • Spring循環(huán)依賴的處理方法

    Spring循環(huán)依賴的處理方法

    循環(huán)依賴是指兩個(gè)或多個(gè)組件之間相互依賴,形成一個(gè)閉環(huán),從而導(dǎo)致這些組件無(wú)法正確地被初始化或加載,這篇文章主要介紹了Spring循環(huán)依賴的處理,需要的朋友可以參考下
    2023-08-08
  • 23種設(shè)計(jì)模式(6)java裝飾者模式

    23種設(shè)計(jì)模式(6)java裝飾者模式

    這篇文章主要為大家詳細(xì)介紹了23種設(shè)計(jì)模式之java裝飾者模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • Spring Boot和Vue跨域請(qǐng)求問題原理解析

    Spring Boot和Vue跨域請(qǐng)求問題原理解析

    這篇文章主要介紹了Spring Boot和Vue跨域請(qǐng)求問題原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Eclipse常用快捷鍵總結(jié)(必看篇)

    Eclipse常用快捷鍵總結(jié)(必看篇)

    下面小編就為大家?guī)?lái)一篇Eclipse常用快捷鍵總結(jié)(必看篇)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-06-06
  • 解決Java字符串JSON轉(zhuǎn)換異常:cn.hutool.json.JSONException:?Mismatched?hr?and?body

    解決Java字符串JSON轉(zhuǎn)換異常:cn.hutool.json.JSONException:?Mismatched?

    這篇文章主要給大家介紹了關(guān)于如何解決Java字符串JSON轉(zhuǎn)換異常:cn.hutool.json.JSONException:?Mismatched?hr?and?body的相關(guān)資料,文中將解決的辦法通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01

最新評(píng)論