<%@ page language="java" import="java.util.*" pageEncoding="utf-8" isELIgnored="false"%> <%@page import="vo.Location" %> <%@taglib prefix="s" uri="/struts-tags" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>菜单树</title> <SCRIPT type="text/javascript" src="/blog_article/js/jquery.js"></SCRIPT> <link href="/blog_article/js/leftmenu.css" rel="stylesheet" type="text/css" /> <SCRIPT type="text/javascript"> $(function(){ }) function getEl(id){ var firstli = $("#_menu2 li:first"); var cruli=$("#a"+id).parent().parent(); var next = cruli.next(), parent = cruli.parent(); firstli.after(cruli); if(next.length === 0){ parent.append(firstli); }else{ next.before(firstli); } var dropdown=$("#a"+id).next(); $(".adropdown").not(dropdown).slideUp('slow'); dropdown.slideToggle('slow'); } </SCRIPT> </head> <body> <table> <tr><td > <h5>菜单树</h5> <ul id="_menu2"> <% List<Location> list = (List<Location>) request .getAttribute("locations"); Location temp = null; Location temp1 = null; for (int i = 0; i < list.size(); i++) { Location l = list.get(i); Location p = l.getParent(); if (p != null && !(p.equals(temp))) { if (i > 0) { %> </ul> </li> </ul> </li> <% } %> <li > <ul> <li id="a<%=p.getId()%>" onclick="getEl(<%=p.getId()%>)"> <% if (null != p) { %> <%=p.getName()%> <% } %> </li> <li > <ul> <% } %> <li > <%=l.getName()%> </li> <% if (i == list.size() - 1) { %> </ul> </li> </ul> </li> <% } %> <% temp = p; temp1 = l; } %> </ul> </td> </tr> </table> </body> </html> 基本结构 <ul> for( <li><ul> <li>一级菜单 <li><ul> <li>二级菜单 重要的地方 <% if (i > 0) { %> </ul> </li> </ul> </li> <%}%> <% if (i == list.size() - 1) { %> </ul> </li> </ul> </li> <% } %> 遍历的时候标签的闭合 点击菜单事件的方法 function getEl(id){ var firstli = $("#_menu2 li:first"); var cruli=$("#a"+id).parent().parent(); var next = cruli.next(),parent = cruli.parent(); firstli.after(cruli); if(next.length === 0){ parent.append(firstli); }else{ next.before(firstli); } var dropdown=$("#a"+id).next(); $(".adropdown").not(dropdown).slideUp('slow'); dropdown.slideToggle('slow'); } 都是知识点
http://redis.cn/commands.html
一、命令
全部(All)
关键字(Keys)
字符串(String)
哈希(Hashs)
列表(Lists)
集合(Sets)
有序集合(Sorted Sets)
发布/订阅(Pub/Sub)
事务(Transactions)
脚本(Scripting)
连接(Connection)
服务(Server)
1、APPEND key value
如果 key 已经存在,并且值为字符串,那么这个命令会把 value 追加到原来值(value)的结尾。 如果 key 不存在,那么它将首先创建一个空字符串的key,再执行追加操作,这种情况 APPEND 将类似于 SET 操作。
redis> EXISTS mykey
(integer) 0
redis> APPEND mykey "Hello"
(integer) 5
redis> APPEND mykey " World"
(integer) 11
redis> GET mykey
"Hello World"
2 AUTH password
验证服务器 为redis服务请求设置一个密码。
3 BGREWRITEAOF
异步重写追加文件
后台保存DB。会立即返回 OK 状态码。 Redis forks, 父进程继续提供服务以供客户端调用,子进程将DB数据保存到磁盘然后退出。如果操作成功,可以通过客户端命令LASTSAVE来检查操作结果。
4 BITCOUNT key [start] [end]
统计字符串指定起始位置的字节数
Count the number of set bits (population counting) in a string.
redis> SET mykey "foobar"
OK
redis> BITCOUNT mykey
(integer) 26
redis> BITCOUNT mykey 0 0
(integer) 4
redis> BITCOUNT mykey 1 1
(integer) 6
5 BITOP operation destkey key [key ...] 支持多个key的按位yuns
Perform bitwise operations between strings
ommand supports four bitwise operations: AND, OR, XOR and NOT
BITOP AND destkey srckey1 srckey2 srckey3 ... srckeyN
BITOP OR destkey srckey1 srckey2 srckey3 ... srckeyN
BITOP XOR destkey srckey1 srckey2 srckey3 ... srckeyN
BITOP NOT destkey srckey
SET key1 "foobar"
OK
redis> SET key2 "abcdef"
OK
redis> BITOP AND dest key1 key2
ERR Don't know what to do for "bitop"
redis> GET dest
(nil)
6 BLPOP key [key ...] timeout
删除,并获得该列表中的第一元素,或阻塞,直到有一个可用
BLPOP 是阻塞式列表的弹出原语。 它是命令 LPOP 的阻塞版本,这是因为当给定列表内没有任何元素可供弹出的时候, 连接将被 BLPOP 命令阻塞。 当给定多个 key 参数时,按参数 key 的先后顺序依次检查各个列表,弹出第一个非空列表的头元素。
当 BLPOP 被调用时,如果给定 key 内至少有一个非空列表,那么弹出遇到的第一个非空列表的头元素,并和被弹出元素所属的列表的名字 key 一起,组成结果返回给调用者。
当存在多个给定 key 时, BLPOP 按给定 key 参数排列的先后顺序,依次检查各个列表。 我们假设 key list1 不存在,而 list2 和 list3 都是非空列表。考虑以下的命令:
BLPOP list1 list2 list3 0
BLPOP 保证返回一个存在于 list2 里的元素(因为它是从 list1 --> list2 --> list3 这个顺序查起的第一个非空列表)。
阻塞行为
如果所有给定 key 都不存在或包含空列表,那么 BLPOP 命令将阻塞连接, 直到有另一个客户端对给定的这些 key 的任意一个执行 LPUSH 或 RPUSH 命令为止。
一旦有新的数据出现在其中一个列表里,那么这个命令会解除阻塞状态,并且返回 key 和弹出的元素值。
当 BLPOP 命令引起客户端阻塞并且设置了一个非零的超时参数 timeout 的时候, 若经过了指定的 timeout 仍没有出现一个针对某一特定 key 的 push 操作,则客户端会解除阻塞状态并且返回一个 nil 的多组合值(multi-bulk value)。
timeout 参数表示的是一个指定阻塞的最大秒数的整型值。当 timeout 为 0 是表示阻塞时间无限制。
7 BRPOP key [key ...] timeout
删除,并获得该列表中的最后一个元素,或阻塞,直到有一个可用
redis> DEL list1 list2
(integer) 0
redis> RPUSH list1 a b c
(integer) 3
redis> BRPOP list1 list2 0
1) "list1"
2) "c"
8 CLIENT KILL ip:port
关闭客户端连接
9 CLIENT LIST
获得客户端连接列表
10 CLIENT GETNAME
获得当前连接名称
11 CLIENT SETNAME connection-name
设置当前连接的名字
12 CONFIG GET parameter
获取配置参数的值
redis> config get *max-*-entries*
1) "hash-max-zipmap-entries"
2) "512"
3) "list-max-ziplist-entries"
4) "512"
5) "set-max-intset-entries"
6) "512"
举例说明,像redis.conf里面的如下配置:
save 900 1
save 300 10
它的意思是:如果900秒内有一个数据发生变化,或者300秒内有10个数据发生变化,那么使用 CONFIG GET 查看时将会看到 "900 1 300 10"。
13 CONFIG SET parameter value
获取配置参数的值
14 CONFIG RESETSTAT
复位再分配使用info命令报告的统计
15 DBSIZE
返回当前数据库里面的keys数量
16 DEBUG OBJECT key
获取一个key的debug信息
17 DEBUG SEGFAULT
使服务器崩溃
18 DECR key
整数原子减1
redis> SET mykey "10"
OK
redis> DECR mykey
(integer) 9
redis> SET mykey "234293482390480948029348230948"
OK
redis> DECR mykey
ERR value is not an integer or out of range
redis>
19 DECRBY key decrement
原子减指定的整数
redis> SET mykey "10"
OK
redis> DECRBY mykey 5
(integer) 5
redis>
20 DEL key [key ...]
删除一个key
redis> SET key1 "Hello"
OK
redis> SET key2 "World"
OK
redis> DEL key1 key2 key3
(integer) 2
redis>
21 DISCARD
丢弃所有 MULTI 之后发的命令
22 DUMP key
导出key的值
序列化给定 key ,并返回被序列化的值,使用 RESTORE 命令可以将这个值反序列化为 Redis 键。
redis> SET mykey 10
OK
redis> DUMP mykey
"\u0000\xC0\n\u0006\u0000\xF8r?\xC5\xFB\xFB_("
redis>
23 ECHO message
回显输入的字符串
24 EVAL script numkeys key [key ...] arg [arg ...]
在服务器端执行 LUA 脚本
25 EVALSHA sha1 numkeys key [key ...] arg [arg ...]
在服务器端执行 LUA 脚本
26 EXEC
执行所有 MULTI 之后发的命令
27 EXISTS key
查询一个key是否存在
28 EXPIRE key seconds
设置一个key的过期的秒数
redis> SET mykey "Hello"
OK
redis> EXPIRE mykey 10
(integer) 1
redis> TTL mykey
(integer) 10
redis> SET mykey "Hello World"
OK
redis> TTL mykey
(integer) -1
redis>
29 FLUSHALL
清空所有数据库
30 FLUSHDB
清空当前的数据库
31 GET key
获取key的值
32 GETBIT key offset
返回位的值存储在关键的字符串值的偏移量。
redis> SETBIT mykey 7 1
(integer) 0
redis> GETBIT mykey 0
(integer) 0
redis> GETBIT mykey 7
(integer) 1
redis> GETBIT mykey 100
(integer) 0
redis>
33 GETRANGE key start end
获取存储在key上的值的一个子字符串
redis> SET mykey "This is a string"
OK
redis> GETRANGE mykey 0 3
"This"
redis> GETRANGE mykey -3 -1
"ing"
redis> GETRANGE mykey 0 -1
"This is a string"
redis> GETRANGE mykey 10 100
"string"
redis>
34 GETSET key value
设置一个key的value,并获取设置前的值
自动将key对应到value并且返回原来key对应的value。
GETSET可以和INCR一起使用实现支持重置的计数功能。举个例子:每当有事件发生的时候,一段程序都会调用INCR给key mycounter加1,但是有时我们需要获取计数器的值,并且自动将其重置为0。这可以通过GETSET mycounter "0"来实现:
redis> INCR mycounter
(integer) 1
redis> GETSET mycounter "0"
"1"
redis> GET mycounter
"0"
redis>
35 HDEL key field [field ...]
删除一个或多个哈希域
从 key 指定的哈希集中移除指定的域。在哈希集中不存在的域将被忽略。如果 key 指定的哈希集不存在,它将被认为是一个空的哈希集,该命令将返回0。
redis> HSET myhash field1 "foo"
(integer) 1
redis> HDEL myhash field1
(integer) 1
redis> HDEL myhash field2
(integer) 0
redis>
36 HEXISTS key field
判断给定域是否存在于哈希集中
redis> HSET myhash field1 "foo"
(integer) 1
redis> HEXISTS myhash field1
(integer) 1
redis> HEXISTS myhash field2
(integer) 0
redis>
37 HGET key field
读取哈希域的的值
redis> HSET myhash field1 "foo"
(integer) 1
redis> HGET myhash field1
"foo"
redis> HGET myhash field2
(nil)
redis>
38 HGETALL key
从哈希集中读取全部的域和值
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HGETALL myhash
1) "field1"
2) "Hello"
3) "field2"
4) "World"
redis>
39 HINCRBY key field increment
将哈希集中指定域的值增加给定的数字
redis> HSET myhash field 5
(integer) 1
redis> HINCRBY myhash field 1
(integer) 6
redis> HINCRBY myhash field -1
(integer) 5
redis> HINCRBY myhash field -10
(integer) -5
redis>
40 HINCRBYFLOAT key field increment
将哈希集中指定域的值增加给定的浮点数
redis> HSET mykey field 10.50
(integer) 1
redis> HINCRBYFLOAT mykey field 0.1
"10.6"
redis> HSET mykey field 5.0e3
(integer) 0
redis> HINCRBYFLOAT mykey field 2.0e2
"5200"
redis>
41 HKEYS key
获取hash的所有字段
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HKEYS myhash
1) "field1"
2) "field2"
redis>
42 HLEN key
获取hash里所有字段的数量
先前我曾经写了一篇“网站的安全登录认证设计”,可能是讲述的不够清楚,有一位读者就留言质疑到,“公钥顾名思义就是公开的啦,只要你愿意,谁都会有你的公钥,何来安全?应该是用网站的公钥加密,传到网站后,网站用自己的私钥解密吧”。
这些密码学的概念容易被搞混淆,的确也情有可原。因为公钥、私钥、加密、认证这些都是较为复杂的问题,其概念不太容易理解,理解不透就容易产生各种似是而非的概念,为了让大家对于密码学有进一步的了解,这里我就详细解说一下公钥和私钥的具体作用和使用方法。
加密和认证
首先我们需要区分加密和认证这两个基本概念。
加密是将数据资料加密,使得非法用户即使取得加密过的资料,也无法获取正确的资料内容,所以数据加密可以保护数据,防止监听攻击。其重点在于数据的安全性。身份认证是用来判断某个身份的真实性,确认身份后,系统才可以依不同的身份给予不同的权限。其重点在于用户的真实性。两者的侧重点是不同的。
公钥和私钥
其次我们还要了解公钥和私钥的概念和作用。
在现代密码体制中加密和解密是采用不同的密钥(公开密钥),也就是非对称密钥密码系统,每个通信方均需要两个密钥,即公钥和私钥,这两把密钥可以互为加解密。公钥是公开的,不需要保密,而私钥是由个人自己持有,并且必须妥善保管和注意保密。
公钥私钥的原则:
非对称密钥密码的主要应用就是公钥加密和公钥认证,而公钥加密的过程和公钥认证的过程是不一样的,下面我就详细讲解一下两者的区别。
基于公开密钥的加密过程
比如有两个用户Alice和Bob,Alice想把一段明文通过双钥加密的技术发送给Bob,Bob有一对公钥和私钥,那么加密解密的过程如下:
上面的过程可以用下图表示,Alice使用Bob的公钥进行加密,Bob用自己的私钥进行解密。
基于公开密钥的认证过程
身份认证和加密就不同了,主要用户鉴别用户的真伪。这里我们只要能够鉴别一个用户的私钥是正确的,就可以鉴别这个用户的真伪。
还是Alice和Bob这两个用户,Alice想让Bob知道自己是真实的Alice,而不是假冒的,因此Alice只要使用公钥密码学对文件签名发送给Bob,Bob使用Alice的公钥对文件进行解密,如果可以解密成功,则证明Alice的私钥是正确的,因而就完成了对Alice的身份鉴别。整个身份认证的过程如下:
上面的过程可以用下图表示,Alice使用自己的私钥加密,Bob用Alice的公钥进行解密。
总结
好了,上面就详细讲述了加密、认证、公钥、私钥这四个概念,明白这些概念后,你就应该对“网站的安全登录认证设计”一文所讲述的概念有了更清晰的了解了。