首页
友链
关于
免责声明
Search
1
王者营地战绩数据王者荣耀查询网页源码
6,255 阅读
2
群晖Active Backup for Business套件备份Linux服务器教程
4,387 阅读
3
影视分享
4,317 阅读
4
(亲测)Jrebel激活破解方式2019-08-21
4,293 阅读
5
centos7 安装及卸载 jekenis
3,576 阅读
日常
文章
后端
前端
Linux
异常
Flutter
分享
群辉
登录
Search
标签搜索
docker
springboot
Spring Boot
java
linux
Shiro
Graphics2D
图片
游戏账号交易
Mybatis
Spring Cloud
centos
脚本
Web Station
群辉
王者营地
战绩查询
平台对接
Spring Cloud Alibaba
nacos
绿林寻猫
累计撰写
249
篇文章
累计收到
26
条评论
首页
栏目
日常
文章
后端
前端
Linux
异常
Flutter
分享
群辉
页面
友链
关于
免责声明
搜索到
237
篇与
文章
的结果
2021-12-08
网络协议篇
(一)网络基础知识1)Http和Https的区别?答:Http协议运行在TCP之上,明文传输,客户端与服务器端都无法验证对方的身份;Https是身披SSL(Secure Socket Layer)外壳的Http,运行于SSL上,SSL运行于TCP之上,是添加了加密和认证机制的HTTP。二者之间存在如下不同: 端口不同:Http与Http使用不同的连接方式,用的端口也不一样,前者是80,后者是443; 资源消耗:和HTTP通信相比,Https通信会由于加减密处理消耗更多的CPU和内存资源; 开销:Https通信需要证书,而证书一般需要向认证机构购买; Https的加密机制是一种共享密钥加密和公开密钥加密并用的混合加密机制。2)对称加密与非对称加密答:对称密钥加密是指加密和解密使用同一个密钥的方式,这种方式存在的最大问题就是密钥发送问题,即如何安全地将密钥发给对方;而非对称加密是指使用一对非对称密钥,即公钥和私钥,公钥可以随意发布,但私钥只有自己知道。发送密文的一方使用对方的公钥进行加密处理,对方接收到加密信息后,使用自己的私钥进行解密。由于非对称加密的方式不需要发送用来解密的私钥,所以可以保证安全性;但是和对称加密比起来,它非常的慢,所以我们还是要用对称加密来传送消息,但对称加密所使用的密钥我们可以通过非对称加密的方式发送出去。3)三次握手与四次挥手答:(1). 三次握手(我要和你建立链接,你真的要和我建立链接么,我真的要和你建立链接,成功) 第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。 第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。 第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。 (2). 四次挥手(我要和你断开链接;好的,断吧。我也要和你断开链接;好的,断吧): 第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。 第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。此时TCP链接处于半关闭状态,即客户端已经没有要发送的数据了,但服务端若发送数据,则客户端仍要接收。 第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。 第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。 (3). 通俗一点的理解就是: 4)为什么 TCP 链接需要三次握手,两次不可以么?答:“三次握手” 的目的是为了防止已失效的链接请求报文突然又传送到了服务端,因而产生错误。 正常的情况:A 发出连接请求,但因连接请求报文丢失而未收到确认,于是 A 再重传一次连接请求。后来收到了确认,建立了连接。数据传输完毕后,就释放了连接。A 共发送了两个连接请求报文段,其中第一个丢失,第二个到达了 B。没有 “已失效的连接请求报文段”。 现假定出现了一种异常情况:即 A 发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达 B。本来这是一个早已失效的报文段。但 B 收到此失效的连接请求报文段后,就误认为是 A 再次发出的一个新的连接请求。于是就向 A 发出确认报文段,同意建立连接。 假设不采用“三次握手”,那么只要 B 发出确认,新的连接就建立了。由于现在 A 并没有发出建立连接的请求,因此不会理睬 B 的确认,也不会向 B 发送数据。但 B 却以为新的运输连接已经建立,并一直等待 A 发来数据。这样,B 的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。5)为什么要四次挥手?答:TCP 协议是一种面向连接的、可靠的、基于字节流的运输层通信协议。TCP 是全双工模式,这就意味着,当 A 向 B 发出 FIN 报文段时,只是表示 A 已经没有数据要发送了,而此时 A 还是能够接受到来自 B 发出的数据;B 向 A 发出 ACK 报文段也只是告诉 A ,它自己知道 A 没有数据要发了,但 B 还是能够向 A 发送数据。所以想要愉快的结束这次对话就需要四次挥手。6)TCP 协议如何来保证传输的可靠性答:TCP 提供一种面向连接的、可靠的字节流服务。其中,面向连接意味着两个使用 TCP 的应用(通常是一个客户和一个服务器)在彼此交换数据之前必须先建立一个 TCP 连接。在一个 TCP 连接中,仅有两方进行彼此通信;而字节流服务意味着两个应用程序通过 TCP 链接交换 8 bit 字节构成的字节流,TCP 不在字节流中插入记录标识符。对于可靠性,TCP通过以下方式进行保证: 数据包校验:目的是检测数据在传输过程中的任何变化,若校验出包有错,则丢弃报文段并且不给出响应,这时TCP发送数据端超时后会重发数据; 对失序数据包重排序:既然TCP报文段作为IP数据报来传输,而IP数据报的到达可能会失序,因此TCP报文段的到达也可能会失序。TCP将对失序数据进行重新排序,然后才交给应用层; 丢弃重复数据:对于重复数据,能够丢弃重复数据; 应答机制:当TCP收到发自TCP连接另一端的数据,它将发送一个确认。这个确认不是立即发送,通常将推迟几分之一秒; 超时重发:当TCP发出一个段后,它启动一个定时器,等待目的端确认收到这个报文段。如果不能及时收到一个确认,将重发这个报文段; 流量控制:TCP连接的每一方都有固定大小的缓冲空间。TCP的接收端只允许另一端发送接收端缓冲区所能接纳的数据,这可以防止较快主机致使较慢主机的缓冲区溢出,这就是流量控制。TCP使用的流量控制协议是可变大小的滑动窗口协议。 7)客户端不断进行请求链接会怎样?DDos(Distributed Denial of Service)攻击?答:服务器端会为每个请求创建一个链接,并向其发送确认报文,然后等待客户端进行确认(1). DDos 攻击: 客户端向服务端发送请求链接数据包 服务端向客户端发送确认数据包 客户端不向服务端发送确认数据包,服务器一直等待来自客户端的确认 (2). DDos 预防:(没有彻底根治的办法,除非不使用TCP) 限制同时打开SYN半链接的数目 缩短SYN半链接的Time out 时间 关闭不必要的服务 8)GET 与 POST 的区别?答:GET与POST是我们常用的两种HTTP Method,二者之间的区别主要包括如下五个方面:(1). 从功能上讲,GET一般用来从服务器上获取资源,POST一般用来更新服务器上的资源;(2). 从REST服务角度上说,GET是幂等的,即读取同一个资源,总是得到相同的数据,而POST不是幂等的,因为每次请求对资源的改变并不是相同的;进一步地,GET不会改变服务器上的资源,而POST会对服务器资源进行改变;(3). 从请求参数形式上看,GET请求的数据会附在URL之后,即将请求数据放置在HTTP报文的 请求头 中,以?分割URL和传输数据,参数之间以&相连。特别地,如果数据是英文字母/数字,原样发送;否则,会将其编码为 application/x-www-form-urlencoded MIME 字符串(如果是空格,转换为+,如果是中文/其他字符,则直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII);而POST请求会把提交的数据则放置在是HTTP请求报文的 请求体 中。(4). 就安全性而言,POST的安全性要比GET的安全性高,因为GET请求提交的数据将明文出现在URL上,而且POST请求参数则被包装到请求体中,相对更安全。(5). 从请求的大小看,GET请求的长度受限于浏览器或服务器对URL长度的限制,允许发送的数据量比较小,而POST请求则是没有大小限制的。为什么在GET请求中会对URL进行编码?我们知道,在GET请求中会对URL中非西文字符进行编码,这样做的目的就是为了 避免歧义。看下面的例子,针对 “name1=value1&name2=value2” 的例子,我们来谈一下数据从客户端到服务端的解析过程。首先,上述字符串在计算机中用ASCII吗表示为: 6E616D6531 3D 76616C756531 26 6E616D6532 3D 76616C756532 6E616D6531:name1 3D:= 76616C756531:value1 26:& 6E616D6532:name2 3D:= 76616C756532:value2 服务端在接收到该数据后就可以遍历该字节流,一个字节一个字节的吃,当吃到3D这字节后,服务端就知道前面吃得字节表示一个key,再往后吃,如果遇到26,说明从刚才吃的3D到26子节之间的是上一个key的value,以此类推就可以解析出客户端传过来的参数。现在考虑这样一个问题,如果我们的参数值中就包含=或&这种特殊字符的时候该怎么办?比如,“name1=value1”,其中value1的值是“va&lu=e1”字符串,那么实际在传输过程中就会变成这样“name1=va&lu=e1”。这样,我们的本意是只有一个键值对,但是服务端却会解析成两个键值对,这样就产生了歧义。那么,如何解决上述问题带来的歧义呢?解决的办法就是对参数进行URL编码:例如,我们对上述会产生歧义的字符进行URL编码后结果:“name1=va%26lu%3D”,这样服务端会把紧跟在“%”后的字节当成普通的字节,就是不会把它当成各个参数或键值对的分隔符。9)TCP与UDP的区别答:TCP (Transmission Control Protocol)和UDP(User Datagram Protocol)协议属于传输层协议,它们之间的区别包括: TCP是面向连接的,UDP是无连接的; TCP是可靠的,UDP是不可靠的; TCP只支持点对点通信,UDP支持一对一、一对多、多对一、多对多的通信模式; TCP是面向字节流的,UDP是面向报文的; TCP有拥塞控制机制;UDP没有拥塞控制,适合媒体通信; TCP首部开销(20个字节)比UDP的首部开销(8个字节)要大; 10)TCP和UDP分别对应的常见应用层协议答:(1). TCP 对应的应用层协议: FTP:定义了文件传输协议,使用21端口。常说某某计算机开了FTP服务便是启动了文件传输服务。下载文件,上传主页,都要用到FTP服务。 Telnet:它是一种用于远程登陆的端口,用户可以以自己的身份远程连接到计算机上,通过这种端口可以提供一种基于DOS模式下的通信服务。如以前的BBS是-纯字符界面的,支持BBS的服务器将23端口打开,对外提供服务。 SMTP:定义了简单邮件传送协议,现在很多邮件服务器都用的是这个协议,用于发送邮件。如常见的免费邮件服务中用的就是这个邮件服务端口,所以在电子邮件设置-中常看到有这么SMTP端口设置这个栏,服务器开放的是25号端口。 POP3:它是和SMTP对应,POP3用于接收邮件。通常情况下,POP3协议所用的是110端口。也是说,只要你有相应的使用POP3协议的程序(例如Fo-xmail或Outlook),就可以不以Web方式登陆进邮箱界面,直接用邮件程序就可以收到邮件(如是163邮箱就没有必要先进入网易网站,再进入自己的邮-箱来收信)。 HTTP:从Web服务器传输超文本到本地浏览器的传送协议。 (2). UDP 对应的应用层协议: DNS:用于域名解析服务,将域名地址转换为IP地址。DNS用的是53号端口。 SNMP:简单网络管理协议,使用161号端口,是用来管理网络设备的。由于网络设备很多,无连接的服务就体现出其优势。 TFTP(Trival File Transfer Protocal):简单文件传输协议,该协议在熟知端口69上使用UDP服务 (3). 图示: 11)TCP 的拥塞避免机制答:拥塞:对资源的需求超过了可用的资源。若网络中许多资源同时供应不足,网络的性能就要明显变坏,整个网络的吞吐量随之负荷的增大而下降。拥塞控制:防止过多的数据注入到网络中,使得网络中的路由器或链路不致过载。拥塞控制的方法:(1). 慢启动 + 拥塞避免:慢启动:不要一开始就发送大量的数据,先探测一下网络的拥塞程度,也就是说由小到大逐渐增加拥塞窗口的大小;拥塞避免:拥塞避免算法让拥塞窗口缓慢增长,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,而不是加倍,这样拥塞窗口按线性规律缓慢增长。 (2). 快重传 + 快恢复:快重传:快重传要求接收方在收到一个 失序的报文段 后就立即发出 重复确认(为的是使发送方及早知道有报文段没有到达对方)而不要等到自己发送数据时捎带确认。快重传算法规定,发送方只要一连收到三个重复确认就应当立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。 快恢复:快重传配合使用的还有快恢复算法,当发送方连续收到三个重复确认时,就执行“乘法减小”算法,把ssthresh门限减半,但是接下去并不执行慢开始算法:因为如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞。所以此时不执行慢开始算法,而是将cwnd设置为ssthresh的大小,然后执行拥塞避免算法。 12)浏览器中输入:“www.xxx.com” 之后都发生了什么?请详细阐述。解析:经典的网络协议问题。答: 由域名→IP地址 寻找IP地址的过程依次经过了浏览器缓存、系统缓存、hosts文件、路由器缓存、 递归搜索根域名服务器。 建立TCP/IP连接(三次握手具体过程) 由浏览器发送一个HTTP请求 经过路由器的转发,通过服务器的防火墙,该HTTP请求到达了服务器 服务器处理该HTTP请求,返回一个HTML文件 浏览器解析该HTML文件,并且显示在浏览器端 这里需要注意: HTTP协议是一种基于TCP/IP的应用层协议,进行HTTP数据请求必须先建立TCP/IP连接 可以这样理解:HTTP是轿车,提供了封装或者显示数据的具体形式;Socket是发动机,提供了网络通信的能力。 两个计算机之间的交流无非是两个端口之间的数据通信,具体的数据会以什么样的形式展现是以不同的应用层协议来定义的。 13)什么是 HTTP 协议无状态协议?怎么解决Http协议无状态协议?答:HTTP 是一个无状态的协议,也就是没有记忆力,这意味着每一次的请求都是独立的,缺少状态意味着如果后续处理需要前面的信息,则它必须要重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就很快。HTTP 的这种特性有优点也有缺点: 优点:解放了服务器,每一次的请求“点到为止”,不会造成不必要的连接占用 缺点:每次请求会传输大量重复的内容信息,并且,在请求之间无法实现数据的共享 解决方案: 使用参数传递机制:将参数拼接在请求的 URL 后面,实现数据的传递(GET方式),例如:/param/list?username=wmyskxz问题:可以解决数据共享的问题,但是这种方式一不安全,二数据允许传输量只有1kb 使用 Cookie 技术 使用 Session 技术 14)Session、Cookie 与 Application答:Cookie和Session都是客户端与服务器之间保持状态的解决方案,具体来说,cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。(1). Cookie 及其相关 API :Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie,而客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器,服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。 (2). Session 及其相关 API:同样地,会话状态也可以保存在服务器端。客户端请求服务器,如果服务器记录该用户状态,就获取Session来保存状态,这时,如果服务器已经为此客户端创建过session,服务器就按照sessionid把这个session检索出来使用;如果客户端请求不包含sessionid,则为此客户端创建一个session并且生成一个与此session相关联的sessionid,并将这个sessionid在本次响应中返回给客户端保存。保存这个sessionid的方式可以采用 cookie机制 ,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器;若浏览器禁用Cookie的话,可以通过 URL重写机制 将sessionid传回服务器。 (3). Session 与 Cookie 的对比: 实现机制:Session的实现常常依赖于Cookie机制,通过Cookie机制回传SessionID; 大小限制:Cookie有大小限制并且浏览器对每个站点也有cookie的个数限制,Session没有大小限制,理论上只与服务器的内存大小有关; 安全性:Cookie存在安全隐患,通过拦截或本地文件找得到cookie后可以进行攻击,而Session由于保存在服务器端,相对更加安全; 服务器资源消耗:Session是保存在服务器端上会存在一段时间才会消失,如果session过多会增加服务器的压力。 (4). Application:Application(ServletContext):与一个Web应用程序相对应,为应用程序提供了一个全局的状态,所有客户都可以使用该状态。15)滑动窗口机制答:由发送方和接收方在三次握手阶段,互相将自己的最大可接收的数据量告诉对方。也就是自己的数据接收缓冲池的大小。这样对方可以根据已发送的数据量来计算是否可以接着发送。在处理过程中,当接收缓冲池的大小发生变化时,要给对方发送更新窗口大小的通知。这就实现了流量的控制。16)常用的HTTP方法有哪些?答: GET: 用于请求访问已经被URI(统一资源标识符)识别的资源,可以通过URL传参给服务器 POST:用于传输信息给服务器,主要功能与GET方法类似,但一般推荐使用POST方式。 PUT: 传输文件,报文主体中包含文件内容,保存到对应URI位置。 HEAD: 获得报文首部,与GET方法类似,只是不返回报文主体,一般用于验证URI是否有效。 DELETE:删除文件,与PUT方法相反,删除对应URI位置的文件。 OPTIONS:查询相应URI支持的HTTP方法。 17)常见HTTP状态码答: 1xx(临时响应) 2xx(成功) 3xx(重定向):表示要完成请求需要进一步操作 4xx(错误):表示请求可能出错,妨碍了服务器的处理 5xx(服务器错误):表示服务器在尝试处理请求时发生内部错误 常见状态码: 200(成功) 304(未修改):自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容 401(未授权):请求要求身份验证 403(禁止):服务器拒绝请求 404(未找到):服务器找不到请求的网页 18)SQL 注入答:SQL注入就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。(1).SQL注入攻击的总体思路: 寻找到SQL注入的位置 判断服务器类型和后台数据库类型 针对不通的服务器和数据库特点进行SQL注入攻击 (2). SQL注入攻击实例:比如,在一个登录界面,要求输入用户名和密码,可以这样输入实现免帐号登录:用户名: ‘or 1 = 1 -- 密 码: 用户一旦点击登录,如若没有做特殊处理,那么这个非法用户就很得意的登陆进去了。这是为什么呢?下面我们分析一下:从理论上说,后台认证程序中会有如下的SQL语句:String sql = “select * from user_table where username=’ “+userName+” ’ and password=’ “+password+” ‘”;因此,当输入了上面的用户名和密码,上面的SQL语句变成:SELECT * FROM user_table WHERE username=’’or 1 = 1 – and password=’’分析上述SQL语句我们知道,username=‘ or 1=1 这个语句一定会成功;然后后面加两个-,这意味着注释,它将后面的语句注释,让他们不起作用。这样,上述语句永远都能正确执行,用户轻易骗过系统,获取合法身份。(3). 应对方法:1.参数绑定:使用预编译手段,绑定参数是最好的防SQL注入的方法。目前许多的ORM框架及JDBC等都实现了SQL预编译和参数绑定功能,攻击者的恶意SQL会被当做SQL的参数而不是SQL命令被执行。在mybatis的mapper文件中,对于传递的参数我们一般是使用#和$来获取参数值。当使用#时,变量是占位符,就是一般我们使用javajdbc的PrepareStatement时的占位符,所有可以防止sql注入;当使用$时,变量就是直接追加在sql中,一般会有sql注入问题。2.使用正则表达式过滤传入的参数19)XSS 攻击答:XSS是一种经常出现在web应用中的计算机安全漏洞,与SQL注入一起成为web中最主流的攻击方式。XSS是指恶意攻击者利用网站没有对用户提交数据进行转义处理或者过滤不足的缺点,进而添加一些脚本代码嵌入到web页面中去,使别的用户访问都会执行相应的嵌入代码,从而盗取用户资料、利用用户身份进行某种动作或者对访问者进行病毒侵害的一种攻击方式。(1). XSS攻击的危害: 盗取各类用户帐号,如机器登录帐号、用户网银帐号、各类管理员帐号 控制企业数据,包括读取、篡改、添加、删除企业敏感数据的能力 盗窃企业重要的具有商业价值的资料 非法转账 强制发送电子邮件 网站挂马 控制受害者机器向其它网站发起攻击 (2). 原因解析: 主要原因:过于信任客户端提交的数据! 解决办法:不信任任何客户端提交的数据,只要是客户端提交的数据就应该先进行相应的过滤处理然后方可进行下一步的操作。 进一步分析细节:客户端提交的数据本来就是应用所需要的,但是恶意攻击者利用网站对客户端提交数据的信任,在数据中插入一些符号以及javascript代码,那么这些数据将会成为应用代码中的一部分了,那么攻击者就可以肆无忌惮地展开攻击啦,因此我们绝不可以信任任何客户端提交的数据!!! (3). XSS 攻击分类: 反射性 XSS 攻击(非持久性 XSS 攻击): 漏洞产生的原因是攻击者注入的数据反映在响应中。一个典型的非持久性XSS攻击包含一个带XSS攻击向量的链接(即每次攻击需要用户的点击),例如,正常发送消息:http://www.test.com/message.php?send=Hello,World! 接收者将会接收信息并显示Hello,World;但是,非正常发送消息:http://www.test.com/message.php?send=<script>alert(‘foolish!’)</script>! 接收者接收消息显示的时候将会弹出警告窗口! 持久性XSS攻击 (留言板场景): XSS攻击向量(一般指XSS攻击代码)存储在网站数据库,当一个页面被用户打开的时候执行。也就是说,每当用户使用浏览器打开指定页面时,脚本便执行。与非持久性XSS攻击相比,持久性XSS攻击危害性更大。从名字就可以了解到,持久性XSS攻击就是将攻击代码存入数据库中,然后客户端打开时就执行这些攻击代码。例如,留言板表单中的表单域:<input type=“text” name=“content” value=“这里是用户填写的数据”> 正常操作流程是:用户是提交相应留言信息 —— 将数据存储到数据库 —— 其他用户访问留言板,应用去数据并显示;而非正常操作流程是攻击者在value填写:<script>alert(‘foolish!’);</script> <!--或者html其他标签(破坏样式)、一段攻击型代码--> 并将数据提交、存储到数据库中;当其他用户取出数据显示的时候,将会执行这些攻击性代码。(4). 修复漏洞方针:漏洞产生的根本原因是 太相信用户提交的数据,对用户所提交的数据过滤不足所导致的,因此解决方案也应该从这个方面入手,具体方案包括: 将重要的cookie标记为http only, 这样的话Javascript 中的document.cookie语句就不能获取到cookie了(如果在cookie中设置了HttpOnly属性,那么通过js脚本将无法读取到cookie信息,这样能有效的防止XSS攻击); 表单数据规定值的类型,例如:年龄应为只能为int、name只能为字母数字组合。。。。 对数据进行Html Encode 处理 过滤或移除特殊的Html标签,例如: <script>, <iframe> , < for <, > for>, " for 过滤JavaScript 事件的标签,例如 “οnclick=”, “onfocus” 等等。 需要注意的是,在有些应用中是允许html标签出现的,甚至是javascript代码出现。因此,我们在过滤数据的时候需要仔细分析哪些数据是有特殊要求(例如输出需要html代码、javascript代码拼接、或者此表单直接允许使用等等),然后区别处理!20)OSI 网络体系结构与 TCP/IP 协议模型答:OSI 是一个理论上的网络通信模型,而 TCP/IP 则是实际上的网络通信标准。但是,它们的初衷是一样的,都是为了使得两台计算机能够像两个知心朋友那样能够互相准确理解对方的意思并做出优雅的回应。现在,我们对 OSI 七层模型的各层进行简要的介绍: 1). 物理层参考模型的最低层,也是OSI模型的第一层,实现了相邻计算机节点之间比特流的透明传送,并尽可能地屏蔽掉具体传输介质和物理设备的差异,使其上层(数据链路层)不必关心网络的具体传输介质。2). 数据链路层(data link layer)接收来自物理层的位流形式的数据,并封装成帧,传送到上一层;同样,也将来自上层的数据帧,拆装为位流形式的数据转发到物理层。这一层在物理层提供的比特流的基础上,通过差错控制、流量控制方法,使有差错的物理线路变为无差错的数据链路,即提供可靠的通过物理介质传输数据的方法。3). 网络层将网络地址翻译成对应的物理地址,并通过路由选择算法为分组通过通信子网选择最适当的路径。 4). 传输层(transport layer)在源端与目的端之间提供可靠的透明数据传输,使上层服务用户不必关系通信子网的实现细节。在协议栈中,传输层位于网络层之上,传输层协议为不同主机上运行的进程提供逻辑通信,而网络层协议为不同主机提供逻辑通信,如下图所示。 实际上,网络层可以看作是传输层的一部分,其为传输层提供服务。但对于终端系统而言,网络层对它们而言是透明的,它们知道传输层的存在,也就是说,在逻辑上它们认为是传输层为它们提供了端对端的通信,这也是分层思想的妙处。5). 会话层(Session Layer)会话层是OSI模型的第五层,是用户应用程序和网络之间的接口,负责在网络中的两节点之间建立、维持和终止通信。6). 表示层(Presentation Layer):数据的编码,压缩和解压缩,数据的加密和解密表示层是OSI模型的第六层,它对来自应用层的命令和数据进行解释,以确保一个系统的应用层所发送的信息可以被另一个系统的应用层读取。7). 应用层(Application layer):为用户的应用进程提供网络通信服务21)网络层的 ARP 协议工作原理?答:地址解析协议(ARP) 是通过解析网路层地址来找寻数据链路层地址的一个在网络协议包中极其重要的网络传输协议。网络层的ARP协议完成了IP地址与物理地址的映射。首先,每台主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址的对应关系。当源主机需要将一个数据包要发送到目的主机时,会首先检查自己ARP列表中是否存在该IP地址对应的MAC地址:如果有,就直接将数据包发送到这个MAC地址;如果没有,就向本地网段发起一个ARP请求的广播包,查询此目的主机对应的MAC地址。此ARP请求数据包里包括源主机的IP地址、硬件地址、以及目的主机的IP地址。网络中所有的主机收到这个ARP请求后,会检查数据包中的目的IP是否和自己的IP地址一致。如果不相同就忽略此数据包;如果相同,该主机首先将发送端的MAC地址和IP地址添加到自己的ARP列表中,如果ARP表中已经存在该IP的信息,则将其覆盖,然后给源主机发送一个ARP响应数据包,告诉对方自己是它需要查找的MAC地址;源主机收到这个ARP响应数据包后,将得到的目的主机的IP地址和MAC地址添加到自己的ARP列表中,并利用此信息开始数据的传输。如果源主机一直没有收到ARP响应数据包,表示ARP查询失败。22)IP地址的分类答:整个的因特网就是一个单一的、抽象的网络。IP 地址就是给因特网上的每一个主机(或路由器)的每一个接口分配一个在全世界范围是唯一的 32 位标识符,它是一个逻辑地址,用以屏蔽掉物理地址的差异。IP地址编址方案将IP地址空间划分为A、B、C、D、E五类,其中A、B、C是基本类,D、E类作为多播和保留使用,为特殊地址。每个IP地址包括两个标识码(ID),即网络ID和主机ID。同一个物理网络上的所有主机都使用同一个网络ID,网络上的一个主机(包括网络上工作站,服务器和路由器等)有一个主机ID与其对应。A~E类地址的特点如下: A类地址:以0开头,第一个字节范围:0~127; B类地址:以10开头,第一个字节范围:128~191; C类地址:以110开头,第一个字节范围:192~223; D类地址:以1110开头,第一个字节范围为224~239; E类地址:以1111开头,保留地址 1). A类地址:1字节的网络地址 + 3字节主机地址,网络地址的最高位必须是“0”一个A类IP地址是指, 在IP地址的四段号码中,第一段号码为网络号码,剩下的三段号码为本地计算机的号码。如果用二进制表示IP地址的话,A类IP地址就由1字节的网络地址和3字节主机地址组成,网络地址的最高位必须是“0”。A类IP地址中网络的标识长度为8位,主机标识的长度为24位,A类网络地址数量较少,有126个网络,每个网络可以容纳主机数达1600多万台。A类IP地址的地址范围1.0.0.0到127.255.255.255(二进制表示为:00000001 00000000 00000000 00000000 - 01111110 11111111 11111111 11111111),最后一个是广播地址。A类IP地址的子网掩码为255.0.0.0,每个网络支持的最大主机数为256的3次方-2=16777214台。2). B类地址: 2字节的网络地址 + 2字节主机地址,网络地址的最高位必须是“10”一个B类IP地址是指,在IP地址的四段号码中,前两段号码为网络号码。如果用二进制表示IP地址的话,B类IP地址就由2字节的网络地址和2字节主机地址组成,网络地址的最高位必须是“10”。B类IP地址中网络的标识长度为16位,主机标识的长度为16位,B类网络地址适用于中等规模的网络,有16384个网络,每个网络所能容纳的计算机数为6万多台。B类IP地址地址范围128.0.0.0-191.255.255.255(二进制表示为:10000000 00000000 00000000 00000000—-10111111 11111111 11111111 11111111),最后一个是广播地址。B类IP地址的子网掩码为255.255.0.0,每个网络支持的最大主机数为256的2次方-2=65534台。3). C类地址: 3字节的网络地址 + 1字节主机地址,网络地址的最高位必须是“110”一个C类IP地址是指,在IP地址的四段号码中,前三段号码为网络号码,剩下的一段号码为本地计算机的号码。如果用二进制表示IP地址的话,C类IP地址就由3字节的网络地址和1字节主机地址组成,网络地址的最高位必须是“110”。C类IP地址中网络的标识长度为24位,主机标识的长度为8位,C类网络地址数量较多,有209万余个网络。适用于小规模的局域网络,每个网络最多只能包含254台计算机。C类IP地址范围192.0.0.0-223.255.255.255(二进制表示为: 11000000 00000000 00000000 00000000 - 11011111 11111111 11111111 11111111)。C类IP地址的子网掩码为255.255.255.0,每个网络支持的最大主机数为256-2=254台。4). D类地址:多播地址,用于1对多通信,最高位必须是“1110”D类IP地址在历史上被叫做多播地址(multicast address),即组播地址。在以太网中,多播地址命名了一组应该在这个网络中应用接收到一个分组的站点。多播地址的最高位必须是“1110”,范围从224.0.0.0到239.255.255.255。5). E类地址:为保留地址,最高位必须是“1111”23)IP地址与物理地址答:物理地址是数据链路层和物理层使用的地址,IP地址是网络层和以上各层使用的地址,是一种逻辑地址,其中ARP协议用于IP地址与物理地址的对应。24)影响网络传输的因素有哪些?答:将一份数据从一个地方正确地传输到另一个地方所需要的时间我们称之为响应时间。影响这个响应时间的因素有很多。 网络带宽:所谓带宽就是一条物理链路在 1s 内能够传输的最大比特数,注意这里是比特(bit)而不是字节数,也就是 b/s 。网络带宽肯定是影响数据传输的一个关键环节,因为在当前的网络环境中,平均网络带宽只有 1.7 MB/s 左右。 传输距离:也就是数据在光纤中要走的距离,虽然光的传播速度很快,但也是有时间的,由于数据在光纤中的移动并不是走直线的,会有一个折射率,所以大概是光的 2/3,这个时间也就是我们通常所说的传输延时。传输延时是一个无法避免的问题,例如,你要给在杭州和青岛的两个机房的一个数据库进行同步数据操作,那么必定会存在约 30ms 的一个延时。 TCP 拥塞控制:我们知道 TCP 传输是一个 “停-等-停-等” 的协议,传输方和接受方的步调要一致,要达到步调一致就要通过拥塞控制来调节。TCP 在传输时会设定一个 “窗口”,这个窗口的大小是由带宽和 RTT(Round-Trip Time,数据在两端的来回时间,也就是响应时间)决定的。计算的公式是带宽(b/s)xRTT(s)。通过这个值就可以得出理论上最优的 TCP 缓冲区的大小。Linux 2.4 已经可以自动地调整发送端的缓冲区的大小,而到 Linux 2.6.7 时接收端也可以自动调整了。 本文转自https://www.cnblogs.com/bokeyuanlongbin/p/9072399.html
2021年12月08日
182 阅读
0 评论
0 点赞
2021-12-08
WebService(一)
Web Service——也叫XML Web Service WebService,是一种跨编程语言和跨操作系统平台的远程调用技术。各个应用程序之间的交流就需要Web Service来作为相互交流的桥梁。Web Service是:通过SOAP在Web上提供的软件服务,使用WSDL文件进行说明,并通过UDDI进行注册。XML:(Extensible Markup Language)扩展型可标记语言。面向短期的临时数据处理、面向万维网络,是Soap的基础。Soap:(Simple Object Access Protocol)简单对象存取协议。是XML Web Service 的通信协议。当用户通过UDDI找到你的WSDL描述文档后,他通过可以SOAP调用你建立的Web服务中的一个或多个操作。SOAP是XML文档形式的调用方法的规范,它可以支持不同的底层接口,像HTTP(S)或者SMTP。基本的 Web services 平台是 XML + HTTP。WSDL:(Web Services Description Language) WSDL 文件是一个 XML 文档,用于说明一组 SOAP 消息以及如何交换这些消息。大多数情况下由软件自动生成和使用。WSDL 是基于 XML 的用于描述 Web Services 以及如何访问 Web Services 的语言。UDDI:UDDI 是一种目录服务,通过它,企业可注册并搜索 Web services。XML+XSD、SOAP和WSDL就是构成WebService平台的三大技术。 所谓跨编程语言和跨操作平台,就是说服务端程序采用java编写,客户端程序则可以采用其他编程语言编写,反之亦然!跨操作系统平台则是指服务端程序和客户端程序可以在不同的操作系统上运行。所谓远程调用,就是一台计算机a上的一个程序可以调用到另外一台计算机b上的一个对象的方法,譬如,天气预报系统,淘宝网,校内网,百度等把自己的系统服务以Web Service服务的形式暴露出来,让第三方网站和程序可以调用这些服务功能,这样扩展了自己系统的市场占有率。 Web Service开发可以分两方面服务端开发:把公司内部系统的业务方法发布成Web Service服务,供远程合作单位和个人调用。客户端开发:调用别人发布的Web Service服务,大多数人从事的开发都属于这个方面。例如,调用天气预报Web Service服务。 JAVA使用jdk开发WebService服务器端(注:使用jdk开发时,jdk版本为1.6及以上) 第一步:创建Java工程 ,创建相应的包(服务端)第二步:创建一个公开的接口,写方法(注:使用@WebService注解标注接口,使用WebMethod注解标注接口中的方法) package Test; import javax.jws.WebMethod; import javax.jws.WebService; /** * @ClassName: Test_WebSweviceI * @Description: TODO(webservice终端) * @author Uncle * @date 2018年9月18日 下午6:05:44 * */ @WebService public interface Test_WebSweviceI { /** * * @Title: getUserById * @Description: 通过uid得到用户信息 * @param uid * @return String * @author Uncle * @date 2018年9月18日下午6:32:12 */ @WebMethod public String getUserById(int uid); } 第三步:编写接口的实现类,使用@WebService注解标注实现类,并实现接口所有方法:package Test; import javax.jws.WebService; /** * @ClassName: Test_WebService * @Description: TODO(webservice实现类) * @author Uncle * @date 2018年9月18日 下午6:05:12 * */ @WebService public class Test_WebServiceImpl implements Test_WebSweviceI{ /* (非 Javadoc) * <p>Title: getUserById</p> * <p>Description: </p> * @param uid * @return * @see Test.Test_WebSweviceI#getUserById(int) */ public String getUserById(int uid) { // TODO Auto-generated method stub //通过这个方法拿取的数据 String str = "哈哈哈哈哈哈"; return str; } } 第四步:写发布类,使用Endponit(终端)类发布(注:发布服务:通过Endpoint类提供的publish()方法发布,发布时要保证使用的端口号没有被其他应用程序占用,Endpoint类是端点类,用来标识网络地址,IP地址是本机动态地址。)package Test; import javax.xml.ws.Endpoint; /** * @ClassName: Publish * @Description: TODO(发布) * @author Uncle * @date 2018年9月18日 下午6:10:10 * */ public class Publish { public static void main(String[] args) { String url="http://本地ip地址:1999/web/webservice"; Endpoint.publish(url, new Test_WebServiceImpl()); System.out.println("ok"); } } 第五步:使用Eclipse自带的工具测试服务端1.选择Luanch the Web Service Explorer2.选择WSDL Page,打开WSDL3.测试方法 打开浏览器也可通过http://本地ip地址:1999/web/webservice?wsdl 查看 客户端(终端)访问WebService访问别人提供的方法,在http://www.webxml.com.cn网站上有很多公开的方法我们就来测试一个天气的WEB服务 可以看到公开了很多可使用的方法,我们就拿getWeather测试1.点击更多点击选中的为wsdl结尾的链接可以得到对应的xml,我个人一般情况下都是把此文件保存到本地再通过命令生成代码,因为某些情况下可能需要改此xml文件在打开的页面:ctrl+s 保存到文件夹 可以看到文件已经保存下来 此时我们跑到Eclipse工作空间,找到对应的项目,下的文件夹中按住shift点击右键打开命令窗口在cmd命令窗口执行下述命令生成客户端代码: wsimport -keep -d D:\WorkSpace\Hibernate\Web_Service1\target\test-classes\Test -s D:\WorkSpace\Hibernate\Web_Service1\src\test\java -verbose d:/WeatherWS.xml -keep:是否生成java源文件-d:指定.class文件的输出目录-s:指定.java文件的输出目录-p:定义生成类的包名,不定义的话有默认包名-verbose:在控制台显示输出信息-b:指定jaxws/jaxb绑定文件或额外的schemas-extension:使用扩展来支持SOAP1.2 解析当中可能会报错:(根据错误提示删除xml对应的信息再解析)再次解析可以看见文件已生成 --------------测试------------package Test; import java.util.List; import cn.com.webxml.ArrayOfString; import cn.com.webxml.WeatherWS; import cn.com.webxml.WeatherWSSoap; /** * @Title: Test.java * @Package Test * @Description: TODO(用一句话描述该文件做什么) * @author Uncle * @date 2018年9月18日 下午9:56:57 * @version V1.0 */ public class Test { public static void main(String[] args) { //找到xml中wsdl:service <wsdl:service name="WeatherWS"> //获得服务 WeatherWS ws = new WeatherWS(); //SOAP 指简易对象访问协议 WeatherWSSoap soap = ws.getWeatherWSSoap(); //soap.getWeather("长沙", "")的返回类型是ArrayOfString 用getString()转成list List<String> list = soap.getWeather("长沙", "").getString(); for (String s : list) { System.out.println(s); } } } 结果:可以看到控制台根据查询输出了对应信息---------------------------------------------------------------------------以上就是使用JDK开发WebService及客户端(终端)访问WebService,下次再写使用Axis2框架开发
2021年12月08日
265 阅读
0 评论
0 点赞
2021-12-08
Exception in thread "main" redis.clients.jedis.exceptions.JedisDataException
1.进入redis的src目录下 输入:./redis-cli将受保护模式选项设置为“no”,为了让服务器开始从外部接受连接输入:config set protected-mode "no"
2021年12月08日
278 阅读
0 评论
0 点赞
2021-12-08
Intellij IDEA使用破解补丁激活(最新)
首先下载IDEA:https://www.jetbrains.com/idea/下载破解补丁: https://pan.baidu.com/s/1C_YTnx2BZGI-0BOKivQW0g 提取码: w6mt 把下载的jar包导入进IDEA安装路径在idea.exe.vmoptions和idea64.exe.vmoptions两个文件最后一行添加:-javaagent:C:\software\ideaIU-2018.2.4.win\bin\JetbrainsCrack-3.1-release-enc.jar 修改Activation Code选择:添加:ThisCrackLicenseId-{ "licenseId":"ThisCrackLicenseId", "licenseeName":"(这里填你的名称→)Uncle", "assigneeName":"", "assigneeEmail":"(这里随便填一个游戏→)idea@163.com", "licenseRestriction":"For This Crack, Only Test! Please support genuine!!!", "checkConcurrentUse":false, "products":[ {"code":"II","paidUpTo":"3000-12-31"}, {"code":"DM","paidUpTo":"3000-12-31"}, {"code":"AC","paidUpTo":"3000-12-31"}, {"code":"RS0","paidUpTo":"3000-12-31"}, {"code":"WS","paidUpTo":"3000-12-31"}, {"code":"DPN","paidUpTo":"3000-12-31"}, {"code":"RC","paidUpTo":"3000-12-31"}, {"code":"PS","paidUpTo":"3000-12-31"}, {"code":"DC","paidUpTo":"3000-12-31"}, {"code":"RM","paidUpTo":"3000-12-31"}, {"code":"CL","paidUpTo":"3000-12-31"}, {"code":"PC","paidUpTo":"3000-12-31"} ], "hash":"2911276/0", "gracePeriodDays":7, "autoProlongated":false}确认之后,重启IDEA,查看: 至此激活成功
2021年12月08日
97 阅读
0 评论
0 点赞
2021-12-08
Mybatis介绍
MyBatis简介MyBatis是一个支持普通SQL查询、存储过程和高级映射的持久层框架。MyBatis可以使用简单的XML或注解进行配置和原始映射,以将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库的记录。ORM 对象/关系映射ORM(Object/Relation Mapping)即对象/关系映射。当使用面向对象开发时,从项目一开始就采用的是面向对象分析、面向对象设计、面向对象编程等,但到了持久层数据访问时,又必须重返关系数据库的访问方式,这是一种非常糟糕的感觉。于是人们需要一种工具,它可以把关系数据库包装成面向对象的模型,这个工具就是ORM。 注意:采用ORM框架之后,应用程序不再直接访问底层数据库,而是以面向对象的方式操作持久化对象(例如创建、修改、删除等),而ORM框架则将这些面向对象的操作转换成底层的SQL操作。基本映射方式ORM工具提供了持久化类和数据库之间的映射关系,通过这种映射关系,程序员可以很方便地通过持久化类实现对数据表的操作。数据表映射类持久化类被映射到一个数据表。程序使用这个持久化类来创建实例,修改属性,删除实例时,系统自动转换为对这个表进行CURD操作。通俗讲:在应用程序中操作实体类,就是操作数据表。 流行的ORM框架JPA:JPA本身只是一种ORM规范,并不是ORM产品。相对于其他开源ORM框架,JPA最大优势在于它是官方标准,因此具有通用性。 Hibernate:流行的开源ORM框架,被选为JBoss的持久层解决方案,已属于JBoss,而JBoss则加入了Red Hat组织,因此Hibernate属于Red Hat的一部分。 MyBatis(早期名称是iBATIS):Apache软件基金组织的子项目,它是一种“SQL Mapper”框架,它是一种“半自动化”的ORM的实现。 MyBatis与Hibernate的区别Hibernate:是一个标准ORM框架,入门门槛较高,不需要程序写SQL语句(会自动生成)。对SQL语句进行优化、修改比较困难。应用场景:适用于需求变化不多的中小型项目,比如:后台管理、ERP、ORM、OA... MyBatis:专注于SQL本身,需要程序员自己编写SQL语句,SQL优化、修改比较方便。MyBatis是一个不完全的ORM框架,也可实现映射(输入映射、输出映射)。应用场景:适用于需求变化较多的项目,比如:互联网项目 JDBC与Hibernate、MyBatis:JDBC目前极少用到,因为需要提供太多的代码,操作太多的对象,麻烦不说,还极其容易出错。Hibernate的缺陷也十分明显,多表关联复杂SQL,数据系统权限限制,根据条件变化的SQL。Hibernate适用场景不太复杂,要求性能不太苛刻的时候使用。MyBatis几乎可以取代JDBC,拥有动态列、动态表名,存储过程都支持,缺陷是需要程序员提供映射规则和SQL,所以工作量比Hibernate略大一些。
2021年12月08日
127 阅读
0 评论
0 点赞
2021-12-08
Mybatis基本配置及 一对一的测试
基本配置在pom.xml中引入依赖 <!--单元测试--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!--mybatis依赖--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.5</version> </dependency> <!--mysql数据库依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.41</version> </dependency> </dependencies> <!--注意:加载src/main/java下所有的xml文件--><build><finalName>mybatis_1</finalName><resources><resource> <!--指定xml文件所在路径,以下表示src/main/java包下所有的.xml,包括子包--> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes></resource></resources></build> 注意:添加上述代码是为了在编译时,将实体包中的映射文件生成到项目下面,否则会报找不到Mapper映射文件的错误。 创建配置文件:db.properties在resources或src下创建外部配置文件:db.properties # mysql数据库连接 db.driver=com.mysql.jdbc.Driver db.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull db.user=root db.pwd=l838061522 创建核心配置文件:mybatis-config.xml在resources或src下创建核心配置文件:mybatis-config.xml<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <properties resource="db.properties"></properties> <settings> <setting name="lazyLoadingEnabled" value="true"></setting> <setting name="aggressiveLazyLoading" value="false"></setting> <setting name="mapUnderscoreToCamelCase" value="true"></setting> </settings> <!--1. 配置数据库环境,默认使用development数据库构建环境--> <environments default="development"> <!--配置环境变量--> <environment id="development"> <!--配置事务管理器类别--> <transactionManager type="JDBC" /> <!--配置数据源--> <dataSource type="POOLED"> <property name="driver" value="${db.driver}" /> <property name="url" value="${db.url}" /> <property name="username" value="${db.user}" /> <property name="password" value="${db.pwd}" /> </dataSource> </environment> </environments> <!-- <!–2. 加载映射器:实体类对象/关系映射文件–> --> <!-- <mappers> --> <!-- </mapper>--> </mappers> </configuration> 创建表 CREATE TABLE card(c_id INT PRIMARY KEY AUTO_INCREMENT COMMENT "id",code VARCHAR(18) UNIQUE NOT NULL COMMENT "身份证号码")COMMENT="身份证表" CREATE TABLE person(p_id INT PRIMARY KEY AUTO_INCREMENT COMMENT "pid",p_name VARCHAR(10) NOT NULL COMMENT "姓名",p_sex VARCHAR(2) NOT NULL COMMENT "性别" CHECK (p_sex="男" OR p_sex="女") ,p_age int not null COMMENT "年龄",c_id INT not null COMMENT "card的cid外键",CONSTRAINT FK_CID FOREIGN KEY (c_id) REFERENCES card(c_id))COMMENT="人员信息表" 封装类 packageclub.lygangdai.pojo;importjava.io.Serializable;/** * @ClassName:card * @Description: TODO(类说明:身份证表 ) * @author Uncle liu * @date 2018-10-11 19:16:13 */ public classCardimplementsSerializable{ private static final longserialVersionUID =1L; privateIntegercId; //id privateStringcode; //身份证号码 //封装属性、构造方法} packageclub.lygangdai.pojo;importjava.io.Serializable;/** * @ClassName:person * @Description: TODO(类说明:人员信息表 ) * @author Uncle liu * @date 2018-10-11 19:16:13 */ public classPersonimplementsSerializable{ private static final longserialVersionUID =1L; privateIntegerpId; //pid privateStringpName; //姓名 privateStringpSex; //性别 privateIntegerpAge; //年龄 privateCardcard;//身份证对象//封装属性、构造方法} 创建接口代理 packageclub.lygangdai.dao;importclub.lygangdai.pojo.Card;importclub.lygangdai.pojo.Person;public interfacePersonDao { /* * @Author Uncle Liu * @Description //TODO 根据id查询Person * @Date 19:17 2018/10/11 * @Param cid * @return Card **/ publicPerson selectPersonById(Integer pid); /* * @Author Uncle Liu * @Description //TODO 添加Person * @Date 19:19 2018/10/11 * @Param person * @return **/ public voidaddPerson(Person person); /* * @Author Uncle Liu * @Description //TODO 修改Person * @Date 19:58 2018/10/11 * @Param Person * @return **/ public voideditPerson(Person person); /* * @Author Uncle Liu * @Description //TODO 根据id删除Card * @Date 19:59 2018/10/11 * @Param * @return **/ public voiddeletePersonById(Integer pid);} packageclub.lygangdai.dao;importclub.lygangdai.pojo.Card;public interfaceCardDao { /* * @Author Uncle Liu * @Description //TODO 根据id查询Card * @Date 19:17 2018/10/11 * @Param cid * @return Card **/ publicCard selectCardById(Integer cid); /* * @Author Uncle Liu * @Description //TODO 添加Card * @Date 19:19 2018/10/11 * @Param * @return **/ public voidaddCard(Card card); /* * @Author Uncle Liu * @Description //TODO 修改Card * @Date 19:58 2018/10/11 * @Param card * @return **/ public voideditCard(Card card); /* * @Author Uncle Liu * @Description //TODO 根据id删除Card * @Date 19:59 2018/10/11 * @Param * @return **/ public voiddeleteCardById(Integer cid);} 对象/关系映射 配置*mapper.xmlCardMapper.xml <?xml version="1.0"encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mappernamespace="club.lygangdai.dao.CardDao"> <selectid="selectCardById"parameterType="Integer"resultType="club.lygangdai.pojo.Card"> SELECT* FROM card WHERE c_id=#{cId} </select> <insertid="addCard"parameterType="club.lygangdai.pojo.Card"keyProperty="cId"useGeneratedKeys="true"keyColumn="c_id"> insert into card(code) values(#{code}) <selectKeykeyProperty="cId"resultType="int"order="AFTER"> SELECT LAST_INSERT_ID() </selectKey> </insert> <deleteid="deleteCardById"parameterType="Integer"> DELETE FROM card WHERE c_id=#{cId} </delete> <updateid="editCard"parameterType="club.lygangdai.pojo.Card"> UPDATE card SET code=#{code} WHERE c_id=#{cId} </update></mapper> PersonMapper.xml <?xml version="1.0"encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mappernamespace="club.lygangdai.dao.PersonDao"> <!--映射Person对象的resultMap(结果映射集)--> <resultMapid="personMapper"type="club.lygangdai.pojo.Person"> <idproperty="pId"column="p_id"/> <resultproperty="pName"column="p_name"/> <resultproperty="pSex"column="p_sex"/> <resultproperty="pAge"column="p_age"/> <associationproperty="card"column="c_id"select="club.lygangdai.dao.CardDao.selectCardById"></association> </resultMap> <selectid="selectPersonById"parameterType="Integer"resultMap="personMapper"> select* from person where p_id=#{pId} </select> <insertid="addPerson"parameterType="club.lygangdai.pojo.Person"keyProperty="pId"useGeneratedKeys="true"keyColumn="p_id"> insert into person(p_name,p_sex,p_age,c_id) values(#{pName},#{pSex},#{pAge},#{card.cId}) <selectKeykeyProperty="pId"resultType="int"order="AFTER"> SELECT LAST_INSERT_ID() </selectKey> </insert> <deleteid="deletePersonById"parameterType="Integer"> DELETE FROM person WHERE p_id=#{pId} </delete> <updateid="editPerson"parameterType="club.lygangdai.pojo.Person"> UPDATE person SET p_name=#{pName},p_age=#{pAge},p_sex=#{pSex} WHERE p_id=#{pId} </update></mapper> 在mybatis-config.xml中配置mapper映射文件 <mappers><mapperresource="club/lygangdai/mapping/PersonMapper.xml"></mapper><mapperresource="club/lygangdai/mapping/CardMapper.xml"></mapper></mappers> 测试 @org.junit.Test public voidtest(){ try{ //通过Resources类加载核心配置文件,得到文件的输入流 InputStream inputStream = Resources.getResourceAsStream("mybatisconfig.xml"); //创建会话工厂,编译配置文件流,获得sqlsessionfactory SqlSessionFactory sqlSessionFactory =newSqlSessionFactoryBuilder().build(inputStream); //通过sqlSessionFactory得到sqlsession对象 SqlSession sqlSession =sqlSessionFactory.openSession(); //一对一 oneTOone(sqlSession); oneTOoneSelect(sqlSession); oneTOoneEdit(sqlSession); oneTOoneDelete(sqlSession); }catch(Exception e){ e.printStackTrace(); } }------方法 /* * @Author Uncle Liu * @Description //TODO 一对一添加测试 * @Date 19:34 2018/10/11 * @Param * @return **/ public voidoneTOone(SqlSession sqlSession){ try{ CardDao cardDao = sqlSession.getMapper(CardDao.class); PersonDao personDao = sqlSession.getMapper(PersonDao.class); Card card =newCard(); card.setCode("4305111111111"); //添加完Card,根据配置会把主键值返回给card对象// <selectKey keyProperty="cId" resultType="int" order="AFTER">// SELECT LAST_INSERT_ID()// </selectKey> cardDao.addCard(card); System.out.println(card); Person person =newPerson(); person.setCard(card); person.setPAge(12); person.setPName("张三"); person.setPSex("男"); //添加完Person,根据配置会把主键值返回给person对象 personDao.addPerson(person); System.out.println(person); //提交 sqlSession.commit(); }catch(Exception e){ //回滚 sqlSession.rollback(); System.out.println(e); }finally{ //关闭 sqlSession.close(); } } /* * @Author Uncle Liu * @Description //TODO 一对一查询 * @Date 19:52 2018/10/11 * @Param * @return **/ public voidoneTOoneSelect(SqlSession sqlSession){ PersonDao personDao = sqlSession.getMapper(PersonDao.class); Person person = personDao.selectPersonById(2); System.out.println(person); System.out.println(person.getCard()); } /* * @Author Uncle Liu * @Description //TODO 一对一修改 * @Date 19:52 2018/10/11 * @Param * @return **/ public voidoneTOoneEdit(SqlSession sqlSession){ try{ PersonDao personDao = sqlSession.getMapper(PersonDao.class); Person person = personDao.selectPersonById(2); person.setPName("李四"); personDao.editPerson(person); sqlSession.commit(); }catch(Exception e){ //回滚 sqlSession.rollback(); System.out.println(e); }finally{ //关闭 sqlSession.close(); } } /* * @Author Uncle Liu * @Description //TODO 一对一删除 * @Date 19:52 2018/10/11 * @Param * @return **/ public voidoneTOoneDelete(SqlSession sqlSession){ try{ PersonDao personDao = sqlSession.getMapper(PersonDao.class); Person person = personDao.selectPersonById(2); personDao.deletePersonById(person.getPId()); CardDao cardDao = sqlSession.getMapper(CardDao.class); cardDao.deleteCardById(person.getCard().getCId()); sqlSession.commit(); }catch(Exception e){ //回滚 sqlSession.rollback(); System.out.println(e); }finally{ //关闭 sqlSession.close(); } }
2021年12月08日
88 阅读
0 评论
0 点赞
2021-12-08
ssm不执行sql,不报错且程序接着运行
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: Error evaluating expression 'programa.pId != null'. Cause: org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null, "pId")------------------------------------------------------SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@68a32861] was not registered for synchronization because synchronization is not active------------------------------------------------------Caused by: org.apache.ibatis.builder.BuilderException: Error evaluating expression 'programa.pId != null'. Cause: org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null, "pId") 最开始删除的方法没有try不知道错在哪里也没抛异常 动态拼接的时候最开始用的只是根据programa.pId做条件删除,所有本身Article对象的aId属性是为空的,删除的时候没有问题。<if test="aId != null ">and a_id=#{aId} </if> <if test="programa.pId != null" > and p_id=#{programa.pId} </if>当我根据aId来删除的时候,条件还是↓↓↓↓<if test="aId != null ">and a_id=#{aId} </if> <if test="programa.pId != null" > and p_id=#{programa.pId} </if>到这里的时候就怎么也不执行删除的sql,代码还是接着运行,发现是因为没有判断对象属性不为空一次泪奔的总结┭┮﹏┭┮
2021年12月08日
184 阅读
0 评论
0 点赞
2021-12-08
删除CSDN自己上传的资源
打开自己资源页面: 如 https://download.csdn.net/download/qq_40369944/17777777删除修改请求为: http://download.csdn.net/index.php/user_console/del_my_source/17777777删除成功返回 {"succ":1,"msg":""}删除失败返回 {"succ":0,"msg":"\u4f60\u6ca1\u6709\u6743\u9650\u64cd\u4f5c"} 即:{"succ":0,"msg":"你没有权限操作"}--------------------- 作者:绿林寻猫 来源:CSDN 原文:https://blog.csdn.net/qq_40369944/article/details/80208358 版权声明:本文为博主原创文章,转载请附上博文链接!
2021年12月08日
92 阅读
0 评论
0 点赞
2021-12-08
利用Redis锁解决并发问题
转发 https://blog.csdn.net/fuyifang/article/details/83008884用redis处理高并发是个很常见的方式,因为redis的访问效率很高(直接访问内存),一般我们会用来处理网站一瞬间的并发量。那如果要使用redis来进行高并发问题的解决的话,应注意以下几点:1、首先我们要先知道,我们在存储时,应使用redis的setnx方法,不应该使用set方法,因为setnx拥有原子操作命令(正确点说法应该是使用setnx,根据其属性可以保证共享资源的原子性操作),当资源锁存在不能设置值,则返回0,而当锁不存在,则设置锁,返回1; 但如果使用set方法,则会出现在高并发情况下,进程同时获取锁状态为null,同时设置,锁之间相互覆盖,但是俩进程仍在并发执行业务代码的情况。2、为了防止死锁,我们不应直接使用jedis.setnx(lock, 1) 来进行简单的加锁,这样会导致当进程执行出现问题,锁未释放,则其他进程永远处于阻塞状态,出现死锁。 为了避免死锁,我们在加锁时带上时间戳,setnx(lock, 时间戳+超时时间),当发现锁超时了,便可以对锁进行重置,避免死锁。接下来,实际操作!设置锁://其中currentTimeMullis为当前时间、valideTime为超时时间,key为资源//对该资源进行锁获取,如果存在锁则会返回false,不存在则设置值并返回trueboolean lock = redisService.setnx(key, currentTimeMullis+valideTime);//如果不存在并设置了值,则可以直接返回,因为已经获取资源锁成功//否则,则代表存在这个锁,则进行锁是否超时的判断。获取该资源的锁时间,用于判断是否超时了String keyTime = redisService.get(key);if((Long.valueOf(currentTimeMullis)-Long.valueOf(keyTime))>valideTime){ //该判断代表该资源锁已经超时,那么便进行资源锁的重置,也就是进行资源锁的重新设置(删除并重新设置)//重新设置成功后也返回,因为获取锁成功,可以进行操作啦。}//如果以上操作都没有成功,则返回失败,代表获取锁失败,不可以进行操作。释放锁:当对资源处理结束后,则调用释放方法释放锁资源(经提醒,我发现我这里少了个判断逻辑…)//在删除前,应该先对该资源锁进行获取,判断值与此时释放锁的线程所携带的值是否相等,也就是我们上面创建时用的currentTimeMullis+valideTime。String keyLockTime = redisService.get(key);if(keyLockTime!=null&&keyLockTime.equals(currentTimeMullis+valideTime)){ //此时锁还由当前线程保持则释放锁redisService.del(key);}else{ //此时说明该资源锁被其他线程重置或释放,已不再拥有锁的释放权//结束}
2021年12月08日
274 阅读
0 评论
0 点赞
2021-12-08
web开发性能优化---代码优化篇
原文:https://blog.csdn.net/fuyifang/article/details/40519421 1、合理使用缓存使用提高性能最好最快的办法当然是通过缓存来改善,对于任何一个web开发者都应该善用缓存。Asp.net下的缓存机制十分强大,用好缓存机制可以让我们极大的改善web应用的性能。1.页面缓存 2.部分页面缓存3.使用DataSource缓存4.Cache对象2、避免数据库频繁连接1.能采用SQL或直接存储过程一次执行的尽量不要用代码多次执行2.及时关闭数据库连接3.适当采取配置文件文件存频繁使用文件4.对不经常更改并且数据量小的可采用xml或者配置文件设置4、资源文件上传大小验证1.严格验证上传图片大小2.严格控制上传Flash动画和视频大小5、尽量避开访问高峰期,进行数据作业和数据服务1.执行定时任务尽量避开访问高峰期2.对应固定报表2可以采取预定格式,避开高峰自动提取6、数据查询采用真分页1.需要多少数据取多少数据7、建设页面跳转覆盖1.尽量采取弹框或切换选项方式展示数据,避免来回刷新列表重新获大量数据8、取数据不要查询全部字段1.查询数据尽量不要SELECT *
2021年12月08日
137 阅读
0 评论
0 点赞
1
...
7
8
9
...
24