JAVA socket FTPserver HTTPserver chatting RMI(Remote Method Invocation)

本文主要是介绍JAVA socket FTPserver HTTPserver chatting RMI(Remote Method Invocation),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录(?)[-]

  1. github-httpserverftpserverchattingRoomRMI
  2. RMI Remote Method Invocation
  3. httpserver
    1. 遇到的问题
  4. FTP
    1. 客户端连接到服务器端 c语言伪码Java版见github
    2. 客户端连接到 FTP 服务器接收欢迎信息
    3. 客户端发送用户名和密码登入 FTP 服务器
    4. 让服务器进入被动模式在数据端口监听
    5. 客户端通过被动模式下载文件
      1. 遇到的问题
  5. Chatting功能
    1. 服务器和客户端通信协议
    2. 客户端发送请求数据格式
    3. 服务器响应数据格式
      1. 基于socket的一个简单的android聊天工具
    4. 遇到的问题

  • github-httpserverftpserverchattingRoomRMI
  • RMI Remote Method Invocation
  • httpserver
      • 遇到的问题
  • FTP
    • 客户端连接到服务器端 c语言伪码Java版见github
    • 客户端连接到 FTP 服务器接收欢迎信息
    • 客户端发送用户名和密码登入 FTP 服务器
    • 让服务器进入被动模式在数据端口监听
    • 客户端通过被动模式下载文件
      • 遇到的问题
  • Chatting功能
    • 服务器和客户端通信协议
    • 客户端发送请求数据格式
    • 服务器响应数据格式
        • 基于socket的一个简单的android聊天工具
      • 遇到的问题

github-httpserver/ftpserver/chattingRoom/RMI

RMI Remote Method Invocation

调用不同JVM上的方法

httpserver

这里并不需要解析xml/html, 根据request请求,返回html让浏览器解析

遇到的问题

  • 第一个问题,之前在创建文件的时候程序一直报错,说文件路径不对或者不存在,之后发现在写路径的时候’/’这些元字符是需要转义的。

  • 第二个问题,是服务器运行后,无法在网页上查看图片等信息,同时服务端抛出异常,但是html网页可以正常显示。这个问题最后通过询问同学和查资料,得知我所使用的发送和接收消息的流不对,不能够使用datainputstream和dataoutputstream,并且wirteUTF方法不能用于http服务器中因为这个方法一开始会写入两个字节,即为将要写入的字节数(不是字符串的长度)。后来改成了printstream和bufferedreader就成功了。

  • 第三个问题,是没有意识到浏览器解析html时,对于html内嵌的图片和视频等资源会在解析之后再次送一个get请求。所以通过浏览器访问服务端网页时,服务端不用进行标签解析。

  • 第四个问题,在服务器发送响应体的时候,我发现出现一个奇怪的现象,就是程序运行的时候,总是无法下载完成,打开对应的客户端文件夹发现文件没有下载完成(即为0字节),但是在关闭客户端运行之后,那个文件夹里的文件就下载好了。最后发现,是服务器在发送响应体的时候,最后忘记关闭了文件发送流,所以导致客户端一直在读取服务器的信息,导致失败。后来添加了close,判断-1才能成功,接受所有信息并关闭文件

FTP:

Resume file upload/download after lost connection 
使用 Socket 通信实现 FTP 客户端程序

客户端连接到服务器端 c语言伪码(Java版见github)

客户端连接到服务器端

客户端连接到 FTP 服务器,接收欢迎信息

<code class="language-c hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">SOCKET control_sock;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> hostent *hp;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> sockaddr_in server;
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">memset</span>(&server, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sizeof</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> sockaddr_in));<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 初始化socket */</span>
control_sock = socket(AF_INET, SOCK_STREAM, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>);
hp = gethostbyname(server_name);
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">memcpy</span>(&server.sin_addr, hp->h_addr, hp->h_length);
server.sin_family = AF_INET;
server.sin_port = htons(port);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 连接到服务器端 */</span>
connect(control_sock,(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> sockaddr *)&server, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sizeof</span>(server));
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 客户端接收服务器端的一些欢迎信息 */</span>
read(control_sock, read_buf, read_len);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li></ul>

客户端发送用户名和密码,登入 FTP 服务器

<code class="language-c hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 命令 ”USER username\r\n” */</span>
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">sprintf</span>(send_buf,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"USER %s\r\n"</span>,username);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*客户端发送用户名到服务器端 */</span>
write(control_sock, send_buf, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">strlen</span>(send_buf));
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 客户端接收服务器的响应码和信息,正常为 ”331 User name okay, need password.” */</span>
read(control_sock, read_buf, read_len);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 命令 ”PASS password\r\n” */</span>
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">sprintf</span>(send_buf,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"PASS %s\r\n"</span>,password);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 客户端发送密码到服务器端 */</span>
write(control_sock, send_buf, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">strlen</span>(send_buf));
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 客户端接收服务器的响应码和信息,正常为 ”230 User logged in, proceed.” */</span>
read(control_sock, read_buf, read_len);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li></ul>

让服务器进入被动模式,在数据端口监听

<code class="language-c hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 命令 ”PASV\r\n” */</span>
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">sprintf</span>(send_buf,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"PASV\r\n"</span>);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 客户端告诉服务器用被动模式 */</span>
write(control_sock, send_buf, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">strlen</span>(send_buf));
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/*客户端接收服务器的响应码和新开的端口号,
* 正常为 ”227 Entering passive mode (<h1,h2,h3,h4,p1,p2>)” */</span>
read(control_sock, read_buf, read_len);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li></ul>

客户端通过被动模式下载文件

<code class="language-c hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 连接服务器新开的数据端口 */</span>
connect(data_sock,(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">struct</span> sockaddr *)&server, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">sizeof</span>(server));
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 命令 ”CWD dirname\r\n” */</span>
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">sprintf</span>(send_buf,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"CWD %s\r\n"</span>, dirname);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 客户端发送命令改变工作目录 */</span>
write(control_sock, send_buf, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">strlen</span>(send_buf));
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 客户端接收服务器的响应码和信息,正常为 ”250 Command okay.” */</span>
read(control_sock, read_buf, read_len);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 命令 ”SIZE filename\r\n” */</span>
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">sprintf</span>(send_buf,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"SIZE %s\r\n"</span>,filename);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 客户端发送命令从服务器端得到下载文件的大小 */</span>
write(control_sock, send_buf, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">strlen</span>(send_buf));
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 客户端接收服务器的响应码和信息,正常为 ”213 <size>” */</span>
read(control_sock, read_buf, read_len);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 命令 ”RETR filename\r\n” */</span>
<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">sprintf</span>(send_buf,<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"RETR %s\r\n"</span>,filename);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 客户端发送命令从服务器端下载文件 */</span>
write(control_sock, send_buf, <span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">strlen</span>(send_buf));
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 客户端接收服务器的响应码和信息,正常为 ”150 Opening data connection.” */</span>
read(control_sock, read_buf, read_len);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 客户端创建文件 */</span>
file_handle = open(disk_name, CRFLAGS, RWXALL);
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">for</span>( ; ; ) {
... ...
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 客户端通过数据连接 从服务器接收文件内容 */</span>
read(data_sock, read_buf, read_len);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 客户端写文件 */</span>
write(file_handle, read_buf, read_len);
... ... 
}
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/* 客户端关闭文件 */</span>
rc = close(file_handle);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li></ul>

遇到的问题

  • 第一个问题是很迷茫,应为是第一个做的实验,不知道如何进行文件上传和下载。后来在网上查询,明白了可以分成两部分,第一部分把文件从硬盘里读取到内存中,再把数据从内存中发送到另一端,由另一端读取到内存,再从内存写入到文件。其中使用了一个字节数组当做一个缓冲,就像一辆运输车一样,一趟一趟的运送货物,直到最后read()==-1就读完了。

  • 第二个问题是下载文件夹。逻辑较为复杂,首先要使用isDirectory方法判断是否是文件夹,然后在本地判断是否存在同名文件夹,通过file.list方法获得文件列表,进而得到文件个数,然后对每个文件进行下载即可,此处隐含了list,cwd,retr等指令,较为复杂,并且dos dis使用后要及时flush和关闭。

  • 第三个问题是阻塞方法的调用。多线程间的协作和socket通信容易混淆,了解到相关原则是尽量少开线程,并时刻注意线程同步异步问题,如上传文件时,服务端使用线程同步(synchronized)的方法,即一个线程访问该方法时,他就获得了该object的对象锁,另一个线程对该object的访问将被暂时阻塞, 保证只存在一个同名文件且后上传的不会覆盖之前的。由于实验末尾才稍微了解了java并发的锁机制,所以所有实验都可以用线程锁等java并发编程知识进行优化,这也是下一步的改进方向

Chatting功能:

登录
发送文件、表情、信息
多人同时聊天
离线发送消息(上线后就能看到)

服务器和客户端通信协议

客户端登录,客户端取得用户列表,以及客户端和客户端的通信都必须跟服务器交互,我们约定客户端和服务器端的通信协议如下: 
请求数据格式

客户端发送请求数据格式:

请求码 请求数据

请求码: 
101 用户登录 
102 取得用户列表 
103 发送消息

如登录请求,客户端向服务器发送的请求数据为: 
101|用户名,密码

如取得用户列表,客户端向服务器发送的请求数据为: 
102|

如发送消息,客户端向服务器发送的请求数据为: 
103|消息发送方,消息接收方,消息内容 
响应数据格式

服务器响应数据格式:

响应码 响应数据

响应码: 
1 响应成功 
0 响应失败

如登录请求,服务器端的响应数据为: 
1| 或者 0|

如取得用户列表,服务器端的响应数据为: 
1|消息类型(102)@消息发送方(Server)@用户1,用户2,用户3@消息发送时间

如服务器给客户端发送消息 
1|消息类型(103)@消息发送方@消息内容@消息发送时间 
服务器消息队列格式

服务器端接收到客户的请求后(取得用户列表和用户信息)将请求结果放在消息队列中,发送消息的线程用队列中取消息,发送给客户端,

我们约定消息队列中消息的格式如下: 
消息发送方 消息接收方 内容 发送时间 消息类别 
Server tom Tom,jack,luly,lily 2016-1-29 11:11:11 102 
Jack tom How are you doing? 2016-1-29 12:12:12 103

基于socket的一个简单的android聊天工具

socket采用TCP/IP时,应有可自由分配的IP(内外网)。对于蓝牙协议,上层接口无法得到IP,所以与wifi组成网络时比较困难,需修改底层框架结构。

遇到的问题

  • 第一个问题是对该设计模式的理解。这个模型类似于生产-消费者模型,将该模型的订阅模式和p2p模式结合,就实现了即能群聊,又能单独聊天的功能。一开始看通信流程图,认为是每个用户一个消息信道,直到想明白生产-消费者模型,才开始正确的实验过程。网上相关资料实现了jms接口进行开发,这也是可以进一步改进的方向

  • 第二个问题是初始化用户列表的时机,后来发现了问题,添加了构造函数,初始化了用户列表。但是主线程里并没有初始化任何一个用户包对象,仅仅是调用了一个静态方法,所以我在服务器建立伊始就初始化了一个用户包对象,虽然这个对象没有被使用,但是成功初始化了用户列表。同样的,消息列表类(MessageDAO)我也使用了此种方法,只不过不在建立服务器时,是在用户登录成功过后。

这篇关于JAVA socket FTPserver HTTPserver chatting RMI(Remote Method Invocation)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:https://blog.csdn.net/a925907195/article/details/52006365
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/850290

相关文章

java中long的一些常见用法

《java中long的一些常见用法》在Java中,long是一种基本数据类型,用于表示长整型数值,接下来通过本文给大家介绍java中long的一些常见用法,感兴趣的朋友一起看看吧... 在Java中,long是一种基本数据类型,用于表示长整型数值。它的取值范围比int更大,从-922337203685477

java Long 与long之间的转换流程

《javaLong与long之间的转换流程》Long类提供了一些方法,用于在long和其他数据类型(如String)之间进行转换,本文将详细介绍如何在Java中实现Long和long之间的转换,感... 目录概述流程步骤1:将long转换为Long对象步骤2:将Longhttp://www.cppcns.c

SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程

《SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程》LiteFlow是一款专注于逻辑驱动流程编排的轻量级框架,它以组件化方式快速构建和执行业务流程,有效解耦复杂业务逻辑,下面给大... 目录一、基础概念1.1 组件(Component)1.2 规则(Rule)1.3 上下文(Conte

SpringBoot服务获取Pod当前IP的两种方案

《SpringBoot服务获取Pod当前IP的两种方案》在Kubernetes集群中,SpringBoot服务获取Pod当前IP的方案主要有两种,通过环境变量注入或通过Java代码动态获取网络接口IP... 目录方案一:通过 Kubernetes Downward API 注入环境变量原理步骤方案二:通过

Springboot整合Redis主从实践

《Springboot整合Redis主从实践》:本文主要介绍Springboot整合Redis主从的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言原配置现配置测试LettuceConnectionFactory.setShareNativeConnect

Java中Map.Entry()含义及方法使用代码

《Java中Map.Entry()含义及方法使用代码》:本文主要介绍Java中Map.Entry()含义及方法使用的相关资料,Map.Entry是Java中Map的静态内部接口,用于表示键值对,其... 目录前言 Map.Entry作用核心方法常见使用场景1. 遍历 Map 的所有键值对2. 直接修改 Ma

Java中实现线程的创建和启动的方法

《Java中实现线程的创建和启动的方法》在Java中,实现线程的创建和启动是两个不同但紧密相关的概念,理解为什么要启动线程(调用start()方法)而非直接调用run()方法,是掌握多线程编程的关键,... 目录1. 线程的生命周期2. start() vs run() 的本质区别3. 为什么必须通过 st

关于跨域无效的问题及解决(java后端方案)

《关于跨域无效的问题及解决(java后端方案)》:本文主要介绍关于跨域无效的问题及解决(java后端方案),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录通用后端跨域方法1、@CrossOrigin 注解2、springboot2.0 实现WebMvcConfig

Java SWT库详解与安装指南(最新推荐)

《JavaSWT库详解与安装指南(最新推荐)》:本文主要介绍JavaSWT库详解与安装指南,在本章中,我们介绍了如何下载、安装SWTJAR包,并详述了在Eclipse以及命令行环境中配置Java... 目录1. Java SWT类库概述2. SWT与AWT和Swing的区别2.1 历史背景与设计理念2.1.

使用SpringBoot整合Sharding Sphere实现数据脱敏的示例

《使用SpringBoot整合ShardingSphere实现数据脱敏的示例》ApacheShardingSphere数据脱敏模块,通过SQL拦截与改写实现敏感信息加密存储,解决手动处理繁琐及系统改... 目录痛点一:痛点二:脱敏配置Quick Start——Spring 显示配置:1.引入依赖2.创建脱敏