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)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/850290

相关文章

springboot集成easypoi导出word换行处理过程

《springboot集成easypoi导出word换行处理过程》SpringBoot集成Easypoi导出Word时,换行符n失效显示为空格,解决方法包括生成段落或替换模板中n为回车,同时需确... 目录项目场景问题描述解决方案第一种:生成段落的方式第二种:替换模板的情况,换行符替换成回车总结项目场景s

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

SpringBoot中@Value注入静态变量方式

《SpringBoot中@Value注入静态变量方式》SpringBoot中静态变量无法直接用@Value注入,需通过setter方法,@Value(${})从属性文件获取值,@Value(#{})用... 目录项目场景解决方案注解说明1、@Value("${}")使用示例2、@Value("#{}"php

SpringBoot分段处理List集合多线程批量插入数据方式

《SpringBoot分段处理List集合多线程批量插入数据方式》文章介绍如何处理大数据量List批量插入数据库的优化方案:通过拆分List并分配独立线程处理,结合Spring线程池与异步方法提升效率... 目录项目场景解决方案1.实体类2.Mapper3.spring容器注入线程池bejsan对象4.创建

线上Java OOM问题定位与解决方案超详细解析

《线上JavaOOM问题定位与解决方案超详细解析》OOM是JVM抛出的错误,表示内存分配失败,:本文主要介绍线上JavaOOM问题定位与解决方案的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录一、OOM问题核心认知1.1 OOM定义与技术定位1.2 OOM常见类型及技术特征二、OOM问题定位工具

基于 Cursor 开发 Spring Boot 项目详细攻略

《基于Cursor开发SpringBoot项目详细攻略》Cursor是集成GPT4、Claude3.5等LLM的VSCode类AI编程工具,支持SpringBoot项目开发全流程,涵盖环境配... 目录cursor是什么?基于 Cursor 开发 Spring Boot 项目完整指南1. 环境准备2. 创建

Spring Security简介、使用与最佳实践

《SpringSecurity简介、使用与最佳实践》SpringSecurity是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架,本文给大家介绍SpringSec... 目录一、如何理解 Spring Security?—— 核心思想二、如何在 Java 项目中使用?——

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

springboot中使用okhttp3的小结

《springboot中使用okhttp3的小结》OkHttp3是一个JavaHTTP客户端,可以处理各种请求类型,比如GET、POST、PUT等,并且支持高效的HTTP连接池、请求和响应缓存、以及异... 在 Spring Boot 项目中使用 OkHttp3 进行 HTTP 请求是一个高效且流行的方式。

java.sql.SQLTransientConnectionException连接超时异常原因及解决方案

《java.sql.SQLTransientConnectionException连接超时异常原因及解决方案》:本文主要介绍java.sql.SQLTransientConnectionExcep... 目录一、引言二、异常信息分析三、可能的原因3.1 连接池配置不合理3.2 数据库负载过高3.3 连接泄漏