0%

文章字数:60,阅读全文大约需要1分钟

报错 No operator matches the given name and argument type(s). You might need to add explicit type casts.
operator does not exist: character varying = integer.

传入的值和数据库类型不匹配

错误查询语句:

1
SELECT count(0) FROM TBNAME t WHERE  t.TABLE_TYPE = 1

原因:table_type的类型是字符串类型,1数值类型

修改后:

1
SELECT count(0) FROM TBNAME t WHERE  t.TABLE_TYPE = '1'

或者:

1
SELECT count(0) FROM TBNAME t WHERE  t.TABLE_TYPE =1::varchar

文章字数:474,阅读全文大约需要1分钟

在编写ssl相关代码的时候遇到了很多新的名词,这里梳理一下它们直接的关系。

一、X.690

  • X.690ITU-T标准,规定了若干ASN.1编码格式
  • 所谓的编码格式就是将具体对象怎么转换成二进制的规范,标准。比如字符编码UTF-8也是一种字符的编码格式
  • ASN.1编码格式
  1. Basic Encoding Rules (BER)
  2. Canonical Encoding Rules (CER)
  3. Distinguished Encoding Rules (DER)
  • 其中,DER被广泛使用,它是BER的子级,除了删除了一个发送者选项外,其它和BER一样。CERDER也类似。
  • X.509公钥证书格式标准使用的就是DER编码

二、PEM(Privacy-Enhanced Mail)

  • 也是一种编码格式,最初是一种文件格式,但是原始的标准没被广泛使用,反而是编码方式流行起来了

  • DER不一样的是PEM文件内采用的是Base64编码,可以在只能传输ASCII的系统中使用

  • 一下为PEM文件的格式,xxx是具体存储的消息类型,例如CERTIFICATEPRIVATE KEY

1
2
3
4
5
-----BEGIN xxx -----

base64内容

-----END xxx -----
  • .pem .cer .crt .key等后缀都可能是PEM格式的

三、PKCS (Public Key Cryptography Standards)

  • 对于秘钥加密的标准

  • 常见的标准有

  1. PKCS #1,是RSA加密算法标准


文章字数:180,阅读全文大约需要1分钟

mutex

  • synchtonized膨胀为重量级锁时使用mutex实现的
  • 操作系统提供的互斥锁
  • mutex是重量级锁,线程获取不到锁之后就会进入休眠状态,CPU会转换到内核态,而代码的运行区在用户态。切换会导致性能降低,所以是重量级。
  • spin_locklinux提供的自旋锁

锁膨胀

  • 偏向锁,使用CAS判断对象头线程标记是不是本身,性能最好,不会进行用户态和内核态的切换
  • 轻量锁,使用CAS设置当前线程为对象头的标记
  • 重量锁,使用mutex的互斥,需要用户态和内核态切换,消耗资源。

文章字数:256,阅读全文大约需要1分钟

tcp是传输层协议,基于网络层协议ip。如果连接对象是url,要先通过dns获取到ip地址才能进行连接。

建立连接(三次握手)

  1. 客户端发送SYN包syn=j到服务器,并进入SYN_SEND状态,等待服务器确认。
  2. 服务器收到SYN包,向客户端返回ACKack=j+1,同事也发送一个自己的SYN包syn=k,即ACK包+SYN包。
  3. 客户端收到服务器的确认ACK以及服务器的等待包SYN,发送确认包给服务器ACK(ack=k+1)
  4. 服务器接收到ACK包后就完成了三次握手,进入ESTABLISHED状态,双方可以开始传输数据了。

断开连接(四次挥手)

  1. 客户端发送FIN包,用于关闭客户端到服务器的数据传送
  2. 服务器收到FIN后返回ACK
  3. 服务器关闭连接,发送一个FIN给客户端
  4. 客户端返回ACK给服务端

文章字数:293,阅读全文大约需要1分钟

session cookie

赋值

1
2
3
4
// 赋值(当前作用域)
Session::set('name','thinkphp');
// 赋值think作用域
Session::set('name','thinkphp','think');

是否存在

1
2
3
4
// 判断(当前作用域)是否赋值
Session::has('name');
// 判断think作用域下面是否赋值
Session::has('name','think');

取值

1
2
3
4
// 取值(当前作用域)
Session::get('name');
// 取值think作用域
Session::get('name','think');

删除

1
2
3
4
// 删除(当前作用域)
Session::delete('name');
// 删除think作用域下面的值
Session::delete('name','think');

取值并删除

1
2
// 取值并删除
Session::pull('name');

清空

1
2
3
4
// 清除session(当前作用域)
Session::clear();
// 清除think作用域
Session::clear('think');

作用域

1
2
// 指定当前作用域
Session::prefix('think');

cookie

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 设置Cookie 有效期为 3600秒
Cookie::set('name','value',3600);
// 设置cookie 前缀为think_
Cookie::set('name','value',['prefix'=>'think_','expire'=>3600]);
// 支持数组
Cookie::set('name',[1,2,3]);
判断
Cookie

Cookie::has('name');
// 判断指定前缀的cookie值是否存在
Cookie::has('name','think_');
获取
Cookie::get('name');
// 获取指定前缀的cookie值
Cookie::get('name','think_');
删除
删除cookie
Cookie::delete('name');
// 删除指定前缀的cookie
Cookie::delete('name','think_');
清空
// 清空指定前缀的cookie
Cookie::clear('think_');

文章字数:548,阅读全文大约需要2分钟

目录结构

  • bin内部包含.sh.bat分别是linuxwindows的执行文件
  • lib依赖的jar
  • conf
  1. catalina.policy 权限相关配置
  2. server.xml 具体配置文件
    1
    2
    3
    Server节点
    - Executor 线程池
    - Connector 连接器,管理对外的连接配置端口之类的。如果使用了线程池,这里的最大线程无效
  3. web.xml
1
2
3
4
5
Servlet
- DefaultServlet 默认的,加载静态文件,图片,html,js等
- JspServlet 处理jsp的
mime-mapping Tomcat处理的文件类型
welcome-file-list 首页
  • logs 日志
  1. catalina.x.log 启动日志
  2. localhost_access_log 接收到的请求日志

部署

  • 隐式部署, war包放到webapps里(一般不推荐,程序和部署工具应该隔离)
  • server.xml配置 Host
1
2
3
4
<Host name="localhost" appBean="webapps" unpackWARs="true" auto Deploy="true">
<!-- reloadable热加载 -->
<Context path="/myUrl" docBase="d:/Demo" reloadable="true"> </Context>
...
  • 创建xml conf/Catalina/localhost/my.xml

my.xml

1
2
<?xml version="1.0" encoding="UTF-8">
<Context path="/myUrl" docBase="d:/Demo" reloadable="true"> </Context>

然后就可以直接访问/my路径进入程序

结构

结构

Service(通过配置多个service和connector可以监听多个端口) -> engine(引擎) –> Host(虚拟主机,域名)–> Context(应用)–>wrapper(servlet)

  • Bootstarp 入口类
  • Catalina 启动类
  • server 服务器,代表整个tomcat(StandardServer是标准实现 )
  • Service 逻辑功能层,可以有多个
  • Connector连接器,负责Tomcat与客户端通讯 (多个)
  • Container Service 的核心组件,按照层级有Engine,Host,Context,Wrapper四种,一个service只有一个Engine
  1. Connector发送RequestContainer
  2. Container返回Reponse
  • Jasper jsp引擎

连接器

  • NIO模式,
  1. ChannelSelector注册连接,读写IO事件
  2. Selector轮询selectKey集合
  3. 通过key找到对应的channel通过绑定的buffer进行读写
  • 流程解析
  1. ProtocolHandler 协议解析
  2. Endpoint Socker网络连接处理
  3. Processor 处理Socker封装成Request
  4. Adapter适配器将Request包装成ServletRequest

容器,责任链

Engine => Host => Context => Wrapper
Catalina.start()启动tomcat start

启动

增加VM参数

1
2
# 设置环境变量
-Dcatalina.home="D:\tomcat\build"

文章字数:618,阅读全文大约需要2分钟

来自原文

1、双方都通过UDP与服务器通讯后,网关默认就是做了一个外网IP和端口号 与你内网IP与端口号的映射,这个无需设置的,服务器也不需要知道客户的真正内网IP

2、用户A先通过服务器知道用户B的外网地址与端口

3、用户A向用户B的外网地址与端口发送消息,

4、在这一次发送中,用户B的网关会拒收这条消息,因为它的映射中并没有这条规则。

5、但是用户A的网关就会增加了一条允许规则,允许接收从B发送过来的消息

6、服务器要求用户B发送一个消息到用户A的外网IP与端口号

7、用户B发送一条消息,这时用户A就可以接收到B的消息,而且网关B也增加了允许规则

8、之后,由于网关A与网关B都增加了允许规则,所以A与B都可以向对方的外网IP和端口号发送消息。


文章字数:257,阅读全文大约需要1分钟

js的表单验证工具validate,设置了debug:true(仅验证不提交)和submitHandler(处理提交的函数)结果还是提交了,并且验证失败也会提交

错误代码

1
2
3
4
5
<form action="/xxx" id='submitId'>
<input name="name" name="name" type="txt">
</form>
...
<button onclick="javascript:document.getElementById('submitId').submit()">ok<button/>

为了样式好调,我用form.submit()提交了表单,这样的操作似乎跳过了验证阶段。

修改后

1
2
3
4
5
6
<form action="/xxx" id='submitId'>
<input name="name" name="name" type="txt">
<input type="submit" style="display:none" id="submit" />
</form>
...
<button onclick="javascript:document.getElementById('submit').click()">ok<button/>

修改成点击input提交就可以了

其它注意点

  1. 多次提交
    1
    2
    3
    4
    //通过id选中表单并提交
    submitHandler:function (form) {
    $("#submitId").submit();
    }
    这样会一直提交表单,造成stack溢出

修改点

1
2
3
4
//直接用入参提交表单
submitHandler:function (form) {
form.submit();
}

文章字数:547,阅读全文大约需要2分钟

一、命令模式

  • 命令模式是输入基本命令的地方,此状态下敲击的任何按键都会被当做是命令。
  • 命令模式下方会显示文件名,类似"fileName.txt" [New File]

1.1 进入命令模式

  • vim fileName进入文件后就处于命令模式
  • 输入模式下按ESC键,从输入模式退出到命令模式。
  • 底线模式输入回车结束命令,则退回命令模式。

1.2 常用命令

  • 移动光标:箭头的上下左右或者 j(下)k(上)h(左)l(右)
  • 移动一页:PageUpPage Down或者Ctrl + d(上)Ctrl + f(下)
  • 移动半页:Ctrl + u(上)Ctrl + d(下)
  • 行首行尾:HomeEnd
  • 移动到具体行数:nG指定行数、gg第一行(等于1g)、G最后一行
  • 光标向下移动具体行数:n<Enter>
  • 查找:/word光标之上查找、?word光标之下查找、n按钮代表重复上一个操作、N代表相反位置查找,即上一次向上查找,本次向下查找。
  • 复制行:yy
  • 粘贴行:p粘贴在下一行、P粘贴在上一行
  • 删除行:dd

二、输入模式

  • 输入模式即输入文本内容的模式,ESC可退出。
  • 输入模式下方会有--INSERT--

2.1进入命令模式

  • i从目前光标所在处输入
  • I从目前所在行的第一个非空格符处开始输入
  • a从目前光标所在的下一个字符处输入
  • A从光标所在行最后一个字符处输入
  • o光标所在行下一行输入新行
  • O光标所在行上一行输入新行
  • r取代光标所在的字符一次
  • R一直取代光标所在的文字,直到ESC

三、底线命令模式

  • 可以输入单个/多个字符的命令

3.1 进入底线命令模式

  • 命令模式下输入:进入底线命令模式

3.2常用命令

  • :w保存
  • :q!强制退出不保存
  • :wq保存并退出

文章字数:1129,阅读全文大约需要4分钟

网上找到一个配置讲解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Sample Application</display-name>
<description>This is a sample application</description>
<filter>
<!–过滤器名,可以随便取,当web应用中有多个过滤器时不允许重名.–>
<filter-name>SampleFilter</filter-name>
<!–具体的过滤器的类的完整的包名+类名。注意:不能写错了。否则容器不能正确的实例化过滤器–>
<filter-class>mypack.SampleFilter</filter-class>
<init-param>
<!– 参数名 –>
<param-name>initParam1</param-name>
<!– 参数值 –>
<param-value>2</param-value>
</init-param>
</filter>
<!– Define the SampleFilter Mapping –>
<filter-mapping>
<!–过滤器名,注意要和上面的<filter-name>里的名字一样。–>
<filter-name>SampleFilter</filter-name>
<!– 指定过滤器负责过滤的URL。这里指定了*.jsp表示在访问任何一个jsp页面时都会先使用mypack.SampleFilter过滤器进行过滤。如果写成login.jsp.则只有在访问login.jsp时才会调用该过滤器进行过滤。–>
<url-pattern>*.jsp</url-pattern>
</filter-mapping>
<servlet>
<!– Servlet名字,可以随便取,有多个Servlet时不允许重名–>
<servlet-name>SampleServlet</servlet-name>
<!–指定实现这个Servlet的类。完整的包名+类名–>
<servlet-class>mypack.SampleServlet</servlet-class>
<!–定义Servlet的初始化参数(包括参数名和参数值)一个<servlet>元素里可以有多个<init-param>元素。在Servlet类中通过ServletConfig类的来访问这些参数。
–>
<init-param>
<!– 参数名 –>
<param-name>initParam1</param-name>
<!– 参数值 –>
<param-value>2</param-value>
</init-param>
<!–指定当前Web应用启动时装载Servlet的次序。当这个数>=0时,容器会按数值从小到大依次加载。如果数值<0或没有指定,容器将载Web客户首次访问这个Servlet时加载。–>
<load-on-startup>1</load-on-startup>
</servlet>
<!– Define the SampleServlet Mapping –>
<servlet-mapping>
<!–必须和<servlet>里的<servlet-name>内容一样–>
<servlet-name>SampleServlet</servlet-name>
<!–指定访问这个Servlet的URL。这里给出的是对于整个Web应用的相对URL路径。–>
<url-pattern>/sample</url-pattern>
</servlet-mapping>
<session-config>
<!–设 定HttpSession的生命周期。这里以分钟计算。下面的设定指明Session在最长不活动时间为10分钟。过了这个时间,Servlet容器将它 作为无效处理。注意这里和程序里指定的计数单位不同,程序里是以秒为单位。<session-config>只有<session- timeout>这个元素–>
<session-timeout>10</session-timeout>
</session-config>
<!— 配置会话侦听器,class表示一个HttpSessionListenerHttpSessionActivationListenerHttpSessionAttributeListenerHttpSessionBindingListener的实现类。该节点允许多个 –>
<listener>
<listener-class>com.cn.SessionListenerImpl</listener-class>
</listener>
<!– 在 用户访问Web应用时,如果仅给出Web应用的根访问URL,没有指定具体的文件名,容器会调用<weblcome-file- list> 元素里指定的文件清单。<welcome-file-list>里允许有多个<welcome-file>元 素,每个元素代表一个文件。容器会先找第一文文件件是否存在,如果存在这把这个文件返回个客户,不再进行其他文件的查找。如果不存在则找第二个文件,依次 类推。如果所有文件都不存在,则跑出404错误–>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
<welcome-file>index.htm</welcome-file>
</welcome-file-list>
<!– 设置Web应用引用的自定义标签库。下面的代码定义了一个/mytaglib标签库,它对应的TLD文件为/WEB-INF/mytaglib.tld –>
<taglib>
<taglib-uri>/mytaglib</taglib-uri>
<taglib-location>/WEB-INF/mytaglib.tld</taglib-location>
</taglib>
<!– 如果Web应用访问了由Servlet容器管理的某个JNDI Resource必须在这里声明对JNDI Resource的引用 –>
<resource-ref>
<!– 对应用资源的说明 –>
<description>DB Connection</description>
<!– 指定所引用资源的JNDI名字 –>
<res-ref-name>jdbc/sampleDb</res-ref-name>
<!– 指定所引用资源的类名字 –>
<res-type>javax.sql.DataSource</res-type>
<!– 指定管理所引用资源的Manager, 它有两个可选值:ContainerApplication.Container表示由容器来创建和管理ResourceApplication表示由Web应用来管理和创建Resource –>
<res-auth>Container</res-auth>
</resource-ref>
<security-constraint>
<web-resource-collection>
<!– 这个名字是必须的,由工具使用,别的地方不使用 –>
<web-resource-name>my application</web-resource-name>
<!– 指定要受约束的资源,至少有一个。可以有多个. –>
<uri-pattern>/*</uri-pattern>
<!– 描 述了度可与URL模式指定的资源哪些方法是受约束的,如果没有<http-method>元素,表示任何角色的人都无法访问任何http的方 法 。这里放置了GET方法,表示只有GET方法是受约束的。其他任何角色的人可以访问POST和其他的方法。但不能访问GET方法。–>
<http-method>GET</http-method>
</web-resource-collection>
<!– 如果没有<auth-constraint>表示所有角色都能访问GET方法,如果是<auth-constraint/>表示任何角色都不能访问GET方法 –>
<auth-constraint>
<!– 可选的。表示哪些角色能够在指定的资源上调用受约束的方法。这里表示只有拥有AdminMember角色的人能够访问GET方法
<security-role>>里的<role-name>值一样 –>
<role-name>Admin</role-name>
<role-name>Member</role-name>
</auth-constraint>
</security-constraint>
<!– 将指定的角色映射到web.xml里 –>
<security-role>
<description>The role that is required to log into the my Application
</description>
<!– 以下的角色和tomcat-users.xml里的<tomcat-users>里的<role rolename=""/>里的rolename属性值对应 –>
<role-name>Guest</role-name>
<role-name>Admin</role-name>
<role-name>Member</role-name>
</security-role>
<!– 如果要想进行认证,必须有<login-config>–>
<login-config>
<!– 认证方式。有4种:BASIC:基本。 DIGEST:摘要。CLIENT-CERT:客户证书(能提供最高强度的认证)。FORM:表单 –>
<auth-method>FORM</auth-method>
<realm-name>
Tomcat Servet Configuraton Form-Based Authentication Area
</realm-name>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/error.jsp</form-error-page>
</form-login-config>
</login-config>
</web-app>