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

SpringBoot+Netty實(shí)現(xiàn)簡單聊天室的示例代碼

 更新時(shí)間:2022年02月01日 09:42:16   作者:醉意丶千層夢  
這篇文章主要介紹了如何利用SpringBoot Netty實(shí)現(xiàn)簡單聊天室,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)SpringBoot有一定幫助,感興趣的同學(xué)可以了解一下

一、實(shí)現(xiàn)

1.User類

import java.util.Objects;

public class User {

? ? public String id;
? ? public String nickname;

? ? public User(String id, String nickname) {
? ? ? ? super();
? ? ? ? this.id = id;
? ? ? ? this.nickname = nickname;
? ? }

? ? public String getId() {
? ? ? ? return id;
? ? }

? ? public void setId(String id) {
? ? ? ? this.id = id;
? ? }

? ? public String getNickname() {
? ? ? ? return nickname;
? ? }

? ? public void setNickname(String nickname) {
? ? ? ? this.nickname = nickname;
? ? }

? ? @Override
? ? public boolean equals(Object o) {
? ? ? ? if (this == o)
? ? ? ? ? ? return true;
? ? ? ? if (o == null || getClass() != o.getClass())
? ? ? ? ? ? return false;
? ? ? ? User user = (User) o;
? ? ? ? return id.equals(user.getId());
? ? }

? ? @Override
? ? public int hashCode() {

? ? ? ? return Objects.hash(id);
? ? }

? ? public String getUid() {

? ? ? ? return id;
? ? }
}

2.SocketSession類

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.AttributeKey;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class SocketSession {

? ? public static final AttributeKey<SocketSession> SESSION_KEY = AttributeKey.valueOf("SESSION_KEY");

? ? /**
? ? ?* 用戶實(shí)現(xiàn)服務(wù)端會話管理的核心
? ? ?*/
// 通道
? ? private Channel channel;
? ? // 用戶
? ? private User user;

? ? // session唯一標(biāo)示
? ? private final String sessionId;

? ? private String group;

? ? /**
? ? ?* session中存儲的session 變量屬性值
? ? ?*/
? ? private Map<String, Object> map = new HashMap<String, Object>();

? ? public SocketSession(Channel channel) {//注意傳入?yún)?shù)channel。不同客戶端會有不同channel
? ? ? ? this.channel = channel;
? ? ? ? this.sessionId = buildNewSessionId();
? ? ? ? channel.attr(SocketSession.SESSION_KEY).set(this);
? ? }

? ? // 反向?qū)Ш?
? ? public static SocketSession getSession(ChannelHandlerContext ctx) {//注意ctx,不同的客戶端會有不同ctx
? ? ? ? Channel channel = ctx.channel();
? ? ? ? return channel.attr(SocketSession.SESSION_KEY).get();
? ? }

? ? // 反向?qū)Ш?
? ? public static SocketSession getSession(Channel channel) {
? ? ? ? return channel.attr(SocketSession.SESSION_KEY).get();
? ? }

? ? public String getId() {
? ? ? ? return sessionId;
? ? }

? ? private static String buildNewSessionId() {
? ? ? ? String uuid = UUID.randomUUID().toString();
? ? ? ? return uuid.replaceAll("-", "");
? ? }

? ? public synchronized void set(String key, Object value) {
? ? ? ? map.put(key, value);
? ? }

? ? public synchronized <T> T get(String key) {
? ? ? ? return (T) map.get(key);
? ? }

? ? public boolean isValid() {
? ? ? ? return getUser() != null ? true : false;
? ? }

? ? public User getUser() {
? ? ? ? return user;
? ? }

? ? public void setUser(User user) {
? ? ? ? this.user = user;
? ? }

? ? public String getGroup() {
? ? ? ? return group;
? ? }

? ? public void setGroup(String group) {
? ? ? ? this.group = group;
? ? }

? ? public Channel getChannel() {
? ? ? ? return channel;
? ? }
}

3.SessionGroup

import com.google.gson.Gson;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.ChannelGroupFuture;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.ImmediateEventExecutor;
import org.springframework.util.StringUtils;

import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public final class SessionGroup {

? ? private static SessionGroup singleInstance = new SessionGroup();

? ? // 組的映射
? ? private ConcurrentHashMap<String, ChannelGroup> groupMap = new ConcurrentHashMap<>();

? ? public static SessionGroup inst() {
? ? ? ? return singleInstance;
? ? }

? ? public void shutdownGracefully() {

? ? ? ? Iterator<ChannelGroup> groupIterator = groupMap.values().iterator();
? ? ? ? while (groupIterator.hasNext()) {
? ? ? ? ? ? ChannelGroup group = groupIterator.next();
? ? ? ? ? ? group.close();
? ? ? ? }
? ? }

? ? public void sendToOthers(Map<String, String> result, SocketSession s) {
? ? ? ? // 獲取組
? ? ? ? ChannelGroup group = groupMap.get(s.getGroup());
? ? ? ? if (null == group) {
? ? ? ? ? ? return;
? ? ? ? }
? ? ? ? Gson gson=new Gson();
? ? ? ? String json = gson.toJson(result);
? ? ? ? // 自己發(fā)送的消息不返回給自己
// ? ? ?Channel channel = s.getChannel();
? ? ? ? // 從組中移除通道
// ? ? ?group.remove(channel);
? ? ? ? ChannelGroupFuture future = group.writeAndFlush(new TextWebSocketFrame(json));
? ? ? ? future.addListener(f -> {
? ? ? ? ? ? System.out.println("完成發(fā)送:"+json);
// ? ? ? ? ?group.add(channel);//發(fā)送消息完畢重新添加。

? ? ? ? });
? ? }

? ? public void addSession(SocketSession session) {

? ? ? ? String groupName = session.getGroup();
? ? ? ? if (StringUtils.isEmpty(groupName)) {
? ? ? ? ? ? // 組為空,直接返回
? ? ? ? ? ? return;
? ? ? ? }
? ? ? ? ChannelGroup group = groupMap.get(groupName);
? ? ? ? if (null == group) {
? ? ? ? ? ? group = new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE);
? ? ? ? ? ? groupMap.put(groupName, group);
? ? ? ? }
? ? ? ? group.add(session.getChannel());
? ? }

? ? /**
? ? ?* 關(guān)閉連接, 關(guān)閉前發(fā)送一條通知消息
? ? ?*/
? ? public void closeSession(SocketSession session, String echo) {
? ? ? ? ChannelFuture sendFuture = session.getChannel().writeAndFlush(new TextWebSocketFrame(echo));
? ? ? ? sendFuture.addListener(new ChannelFutureListener() {
? ? ? ? ? ? public void operationComplete(ChannelFuture future) {
? ? ? ? ? ? ? ? System.out.println("關(guān)閉連接:"+echo);
? ? ? ? ? ? ? ? future.channel().close();
? ? ? ? ? ? }
? ? ? ? });
? ? }

? ? /**
? ? ?* 關(guān)閉連接
? ? ?*/
? ? public void closeSession(SocketSession session) {

? ? ? ? ChannelFuture sendFuture = session.getChannel().close();
? ? ? ? sendFuture.addListener(new ChannelFutureListener() {
? ? ? ? ? ? public void operationComplete(ChannelFuture future) {
? ? ? ? ? ? ? ? System.out.println("發(fā)送所有完成:"+session.getUser().getNickname());
? ? ? ? ? ? }
? ? ? ? });

? ? }

? ? /**
? ? ?* 發(fā)送消息
? ? ?* @param ctx 上下文
? ? ?* @param msg 待發(fā)送的消息
? ? ?*/
? ? public void sendMsg(ChannelHandlerContext ctx, String msg) {
? ? ? ? ChannelFuture sendFuture = ctx.writeAndFlush(new TextWebSocketFrame(msg));
? ? ? ? sendFuture.addListener(f -> {//發(fā)送監(jiān)聽
? ? ? ? ? ? System.out.println("對所有發(fā)送完成:"+msg);
? ? ? ? });
? ? }
}

4.WebSocketTextHandler類

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;

import java.util.HashMap;
import java.util.Map;

public class WebSocketTextHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

? ? @Override
? ? protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
? ? ? ? SocketSession session = SocketSession.getSession(ctx);
? ? ? ? TypeToken<HashMap<String, String>> typeToken = new TypeToken<HashMap<String, String>>() {
? ? ? ? };

? ? ? ? Gson gson=new Gson();
? ? ? ? java.util.Map<String,String> map = gson.fromJson(msg.text(), typeToken.getType());
? ? ? ? User user = null;
? ? ? ? switch (map.get("type")) {
? ? ? ? ? ? case "msg":
? ? ? ? ? ? ? ? Map<String, String> result = new HashMap<>();
? ? ? ? ? ? ? ? user = session.getUser();
? ? ? ? ? ? ? ? result.put("type", "msg");
? ? ? ? ? ? ? ? result.put("msg", map.get("msg"));
? ? ? ? ? ? ? ? result.put("sendUser", user.getNickname());
? ? ? ? ? ? ? ? SessionGroup.inst().sendToOthers(result, session);
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case "init":
? ? ? ? ? ? ? ? String room = map.get("room");
? ? ? ? ? ? ? ? session.setGroup(room);
? ? ? ? ? ? ? ? String nick = map.get("nick");
? ? ? ? ? ? ? ? user = new User(session.getId(), nick);
? ? ? ? ? ? ? ? session.setUser(user);
? ? ? ? ? ? ? ? SessionGroup.inst().addSession(session);
? ? ? ? ? ? ? ? break;
? ? ? ? }
? ? }

? ? @Override
? ? public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {

? ? ? ? // 是否握手成功,升級為 Websocket 協(xié)議
? ? ? ? if (evt == WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE) {
? ? ? ? ? ? // 握手成功,移除 HttpRequestHandler,因此將不會接收到任何消息
? ? ? ? ? ? // 并把握手成功的 Channel 加入到 ChannelGroup 中
? ? ? ? ? ? new SocketSession(ctx.channel());
? ? ? ? } else if (evt instanceof IdleStateEvent) {
? ? ? ? ? ? IdleStateEvent stateEvent = (IdleStateEvent) evt;
? ? ? ? ? ? if (stateEvent.state() == IdleState.READER_IDLE) {
? ? ? ? ? ? ? ? System.out.println("bb22");
? ? ? ? ? ? }
? ? ? ? } else {
? ? ? ? ? ? super.userEventTriggered(ctx, evt);
? ? ? ? }
? ? }
}

5.WebSocketServer類

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;

import java.util.concurrent.TimeUnit;

public class WebSocketServer {

? ? private static WebSocketServer wbss;

? ? private static final int READ_IDLE_TIME_OUT = 60; // 讀超時(shí)
? ? private static final int WRITE_IDLE_TIME_OUT = 0;// 寫超時(shí)
? ? private static final int ALL_IDLE_TIME_OUT = 0; // 所有超時(shí)

? ? public static WebSocketServer inst() {
? ? ? ? return wbss = new WebSocketServer();
? ? }

? ? public void run(int port) {
? ? ? ? EventLoopGroup bossGroup = new NioEventLoopGroup();
? ? ? ? EventLoopGroup workerGroup = new NioEventLoopGroup();
? ? ? ? ServerBootstrap b = new ServerBootstrap();
? ? ? ? b.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class)
? ? ? ? ? ? ? ? .childHandler(new ChannelInitializer <SocketChannel>() {
? ? ? ? ? ? ? ? ? ? @Override
? ? ? ? ? ? ? ? ? ? protected void initChannel(SocketChannel ch) throws Exception {
? ? ? ? ? ? ? ? ? ? ? ? ChannelPipeline pipeline = ch.pipeline();
? ? ? ? ? ? ? ? ? ? ? ? // Netty自己的http解碼器和編碼器,報(bào)文級別 HTTP請求的解碼和編碼
? ? ? ? ? ? ? ? ? ? ? ? pipeline.addLast(new HttpServerCodec());
? ? ? ? ? ? ? ? ? ? ? ? // ChunkedWriteHandler 是用于大數(shù)據(jù)的分區(qū)傳輸
? ? ? ? ? ? ? ? ? ? ? ? // 主要用于處理大數(shù)據(jù)流,比如一個(gè)1G大小的文件如果你直接傳輸肯定會撐暴jvm內(nèi)存的;
? ? ? ? ? ? ? ? ? ? ? ? // 增加之后就不用考慮這個(gè)問題了
? ? ? ? ? ? ? ? ? ? ? ? pipeline.addLast(new ChunkedWriteHandler());
? ? ? ? ? ? ? ? ? ? ? ? // HttpObjectAggregator 是完全的解析Http消息體請求用的
? ? ? ? ? ? ? ? ? ? ? ? // 把多個(gè)消息轉(zhuǎn)換為一個(gè)單一的完全FullHttpRequest或是FullHttpResponse,
? ? ? ? ? ? ? ? ? ? ? ? // 原因是HTTP解碼器會在每個(gè)HTTP消息中生成多個(gè)消息對象HttpRequest/HttpResponse,HttpContent,LastHttpContent
? ? ? ? ? ? ? ? ? ? ? ? pipeline.addLast(new HttpObjectAggregator(64 * 1024));
? ? ? ? ? ? ? ? ? ? ? ? // WebSocket數(shù)據(jù)壓縮
? ? ? ? ? ? ? ? ? ? ? ? pipeline.addLast(new WebSocketServerCompressionHandler());
? ? ? ? ? ? ? ? ? ? ? ? // WebSocketServerProtocolHandler是配置websocket的監(jiān)聽地址/協(xié)議包長度限制
? ? ? ? ? ? ? ? ? ? ? ? pipeline.addLast(new WebSocketServerProtocolHandler("/ws", null, true, 10 * 1024));

? ? ? ? ? ? ? ? ? ? ? ? // 當(dāng)連接在60秒內(nèi)沒有接收到消息時(shí),就會觸發(fā)一個(gè) IdleStateEvent 事件,
? ? ? ? ? ? ? ? ? ? ? ? // 此事件被 HeartbeatHandler 的 userEventTriggered 方法處理到
? ? ? ? ? ? ? ? ? ? ? ? pipeline.addLast(
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? new IdleStateHandler(READ_IDLE_TIME_OUT, WRITE_IDLE_TIME_OUT, ALL_IDLE_TIME_OUT, TimeUnit.SECONDS));

? ? ? ? ? ? ? ? ? ? ? ? // WebSocketServerHandler、TextWebSocketFrameHandler 是自定義邏輯處理器,
? ? ? ? ? ? ? ? ? ? ? ? pipeline.addLast(new WebSocketTextHandler());
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? });
? ? ? ? Channel ch = b.bind(port).syncUninterruptibly().channel();
? ? ? ? ch.closeFuture().syncUninterruptibly();

? ? ? ? // 返回與當(dāng)前Java應(yīng)用程序關(guān)聯(lián)的運(yùn)行時(shí)對象
? ? ? ? Runtime.getRuntime().addShutdownHook(new Thread() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? SessionGroup.inst().shutdownGracefully();
? ? ? ? ? ? ? ? bossGroup.shutdownGracefully();
? ? ? ? ? ? ? ? workerGroup.shutdownGracefully();
? ? ? ? ? ? }
? ? ? ? });
? ? }
}

6.index.html

<!DOCTYPE HTML>
<html>
<head>
? ? <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
? ? <title>群聊天室</title>
? ? <style type="text/css">
? ? ? ? body {
? ? ? ? ? ? margin-right:50px;
? ? ? ? ? ? margin-left:50px;
? ? ? ? }
? ? ? ? .ddois {
? ? ? ? ? ? position: fixed;
? ? ? ? ? ? left: 120px;
? ? ? ? ? ? bottom: 30px;
? ? ? ? }
? ? </style>
</head>
<body>
群名:<input type="text" id="room" name="group" placeholder="請輸入群">
<br /><br />
昵稱:<input type="text" id="nick" name="name" placeholder="請輸入昵稱">
<br /><br />
<button type="button" onclick="enter()">進(jìn)入聊天群</button>
<br /><br />
<div id="message"></div>
<br /><br />
<div class="ddois">
? ? <textarea name="send" id="text" rows="10" cols="30" placeholder="輸入發(fā)送消息"></textarea>
? ? <br /><br />
? ? <button type="button" onclick="send()">發(fā)送</button>
</div>
<script type="text/javascript">
? ? var webSocket;

? ? if (window.WebSocket) {
? ? ? ? webSocket = new WebSocket("ws://localhost:8088/ws");
? ? } else {
? ? ? ? alert("抱歉,您的瀏覽器不支持WebSocket協(xié)議!");
? ? }

? ? //連通之后的回調(diào)事件
? ? webSocket.onopen = function() {
? ? ? ? console.log("已經(jīng)連通了websocket");
// ? ? ? ? ? ? ? ?setMessageInnerHTML("已經(jīng)連通了websocket");
? ? };
? ? //連接發(fā)生錯(cuò)誤的回調(diào)方法
? ? webSocket.onerror = function(event){
? ? ? ? console.log("出錯(cuò)了");
// ? ? ? ? ? ? ?setMessageInnerHTML("連接失敗");
? ? };

? ? //連接關(guān)閉的回調(diào)方法
? ? webSocket.onclose = function(){
? ? ? ? console.log("連接已關(guān)閉...");

? ? }

? ? //接收到消息的回調(diào)方法
? ? webSocket.onmessage = function(event){
? ? ? ? console.log("bbdds");
? ? ? ? var data = JSON.parse(event.data)
? ? ? ? var msg = data.msg;
? ? ? ? var nick = data.sendUser;
? ? ? ? switch(data.type){
? ? ? ? ? ? case 'init':
? ? ? ? ? ? ? ? console.log("mmll");
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case 'msg':
? ? ? ? ? ? ? ? console.log("bblld");
? ? ? ? ? ? ? ? setMessageInnerHTML(nick+": ?"+msg);
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? default:
? ? ? ? ? ? ? ? break;
? ? ? ? }
? ? }
? ? function enter(){
? ? ? ? var map = new Map();
? ? ? ? var nick=document.getElementById('nick').value;
? ? ? ? var room=document.getElementById('room').value;
? ? ? ? map.set("type","init");
? ? ? ? map.set("nick",nick);
? ? ? ? console.log(room);
? ? ? ? map.set("room",room);
? ? ? ? var message = Map2Json(map);
? ? ? ? webSocket.send(message);
? ? }

? ? function send() {
? ? ? ? var msg = document.getElementById('text').value;
? ? ? ? var nick = document.getElementById('nick').value;
? ? ? ? console.log("1:"+msg);
? ? ? ? if (msg != null && msg != ""){
? ? ? ? ? ? var map = new Map();
? ? ? ? ? ? map.set("type","msg");
? ? ? ? ? ? map.set("msg",msg);
? ? ? ? ? ? var map2json=Map2Json(map);
? ? ? ? ? ? if (map2json.length < 8000){
? ? ? ? ? ? ? ? console.log("4:"+map2json);
? ? ? ? ? ? ? ? webSocket.send(map2json);
? ? ? ? ? ? }else {
? ? ? ? ? ? ? ? console.log("文本太長了,少寫一點(diǎn)吧??");
? ? ? ? ? ? }
? ? ? ? }
? ? }

? ? //將消息顯示在網(wǎng)頁上
? ? function setMessageInnerHTML(innerHTML) {
? ? ? ? document.getElementById("message").innerHTML += innerHTML + "
";
? ? }

? ? function Map2Json(map) {
? ? ? ? var str = "{";
? ? ? ? map.forEach(function (value, key) {
? ? ? ? ? ? str += '"'+key+'"'+':'+ '"'+value+'",';
? ? ? ? })
? ? ? ? str = str.substring(0,str.length-1)
? ? ? ? str +="}";
? ? ? ? return str;
? ? }

</script>

</body>
</html>

二、效果

以上就是SpringBoot+Netty實(shí)現(xiàn)簡單聊天室的示例代碼的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot Netty聊天室的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java集合之同步容器詳解

    Java集合之同步容器詳解

    這篇文章主要為大家詳細(xì)介紹了Java集合之同步容器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • Java排序算法之歸并排序簡單實(shí)現(xiàn)

    Java排序算法之歸并排序簡單實(shí)現(xiàn)

    這篇文章主要介紹了Java排序算法之歸并排序簡單實(shí)現(xiàn),具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • Java實(shí)現(xiàn)文件上傳至服務(wù)器的方法

    Java實(shí)現(xiàn)文件上傳至服務(wù)器的方法

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)文件上傳至服務(wù)器的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • JavaSE學(xué)習(xí)之內(nèi)部類及常用API

    JavaSE學(xué)習(xí)之內(nèi)部類及常用API

    這篇文章主要介紹了JavaSE中的內(nèi)部類和幾個(gè)常用的API,文中的示例代碼介紹詳細(xì),對我們學(xué)習(xí)JavaSEI有一定的幫助,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2021-12-12
  • Java web項(xiàng)目啟動Tomcat報(bào)錯(cuò)解決方案

    Java web項(xiàng)目啟動Tomcat報(bào)錯(cuò)解決方案

    這篇文章主要介紹了Java web項(xiàng)目啟動Tomcat報(bào)錯(cuò)解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Spring?Boot?集成Elasticsearch模塊實(shí)現(xiàn)簡單查詢功能

    Spring?Boot?集成Elasticsearch模塊實(shí)現(xiàn)簡單查詢功能

    本文講解了Spring?Boot集成Elasticsearch采用的是ES模板的方式實(shí)現(xiàn)基礎(chǔ)查詢,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2022-06-06
  • java在網(wǎng)頁上面抓取郵件地址的方法

    java在網(wǎng)頁上面抓取郵件地址的方法

    這篇文章主要介紹了java在網(wǎng)頁上面抓取郵件地址的方法,是比較典型的Java正則匹配應(yīng)用實(shí)例,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2014-11-11
  • java獲取文件擴(kuò)展名的方法小結(jié)【正則與字符串截取】

    java獲取文件擴(kuò)展名的方法小結(jié)【正則與字符串截取】

    這篇文章主要介紹了java獲取文件擴(kuò)展名的方法,結(jié)合實(shí)例形式分析了使用正則與字符串截取兩種獲取擴(kuò)展名的操作技巧,需要的朋友可以參考下
    2017-01-01
  • ThreadPoolExecutor核心線程數(shù)和RocketMQ消費(fèi)線程調(diào)整詳解

    ThreadPoolExecutor核心線程數(shù)和RocketMQ消費(fèi)線程調(diào)整詳解

    這篇文章主要介紹了ThreadPoolExecutor核心線程數(shù)和RocketMQ消費(fèi)線程調(diào)整詳解,Rocketmq 消費(fèi)者在高峰期希望手動減少消費(fèi)線程數(shù),通過DefaultMQPushConsumer.updateCorePoolSize方法可以調(diào)用內(nèi)部的setCorePoolSize設(shè)置多線程核心線程數(shù),需要的朋友可以參考下
    2023-10-10
  • Java反射機(jī)制的學(xué)習(xí)總結(jié)

    Java反射機(jī)制的學(xué)習(xí)總結(jié)

    總的來說,java反射機(jī)制是一個(gè)很好用的東西,用它可以解決很多死的東西,因?yàn)榉瓷錂C(jī)制的靈活行很大,有了他,我們就不要花太多的時(shí)間來寫操做數(shù)據(jù)庫的代碼了,而是方法更多的時(shí)間在項(xiàng)目的邏輯功能上,這個(gè)可以很大的減少開發(fā)時(shí)間,而且代碼的可讀性好
    2013-09-09

最新評論

时尚| 通城县| 昔阳县| 桃园市| 宜城市| 城口县| 曲麻莱县| 登封市| 奉节县| 松江区| 京山县| 商城县| 吉安县| 柳林县| 玉门市| 永昌县| 静宁县| 宁远县| 康平县| 仁布县| 三明市| 屯门区| 韩城市| 鄢陵县| 英吉沙县| 德格县| 漾濞| 繁峙县| 潞城市| 铜鼓县| 云梦县| 保靖县| 南宁市| 新营市| 营口市| 吴桥县| 芮城县| 金坛市| 淮北市| 高雄市| 高台县|