-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsearch.xml
More file actions
331 lines (288 loc) · 56.3 KB
/
search.xml
File metadata and controls
331 lines (288 loc) · 56.3 KB
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>lucene基本使用</title>
<url>/2020/03/30/lucene%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8/</url>
<content><![CDATA[<h3 id="lucene基本使用"><a href="#lucene基本使用" class="headerlink" title="lucene基本使用"></a>lucene基本使用</h3><p>lucene主要用于对非结构化数据的解析,常见的非结构化数据例如:邮件、doc文档、pdf文档等等,lucene技术就是将这些非结构化数据解析整理成具有一定结构化的数据,lucene的基本使用主要分成下面几方面</p>
<ul>
<li>索引库的建立:将非结构化数据分析整理成具有一定结构化的数据,并创建索引库</li>
<li>索引库的内容的增删改查</li>
</ul>
<h4 id="索引库的创建"><a href="#索引库的创建" class="headerlink" title="索引库的创建"></a>索引库的创建</h4><img src="/2020/03/30/lucene%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8/1.png" class="">
<p>创建索引的过程就是将原始文档的内容解析成多个域,例如解析一个word文档,将文档的名称传到文件名称域里面解析成多个关键词,将文档里面的内传到内容域里面解析成多个关键词,解析后的关键词都存储在域里面,然后将这几个域添加到一个文档对象里面,这就是原始文档到文档对象的解析过程。</p>
<img src="/2020/03/30/lucene%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8/2.png" class="">
<p>下面是创建索引库的实现步骤</p>
<p><strong>1、引入依赖</strong></p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"> <span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>junit<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>junit<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>4.13<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span></span><br><span class="line"><span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>org.apache.lucene<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>lucene-core<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>7.4.0<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span></span><br><span class="line"><span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>org.apache.lucene<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>lucene-analyzers-common<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>7.4.0<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span></span><br><span class="line"><span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>commons-io<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>commons-io<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>2.6<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span></span><br></pre></td></tr></table></figure>
<p><strong>2、代码实现</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"> <span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">createIndex</span><span class="params">()</span> <span class="keyword">throws</span> Exception</span>{</span><br><span class="line"> <span class="comment">//1、创建一个Director对象,指定索引库保存的位置,FSDirectory类将索引保存到磁盘中</span></span><br><span class="line"> Directory directory = FSDirectory.open(<span class="keyword">new</span> File(<span class="string">"要创建的索引库的路径"</span>).toPath());</span><br><span class="line"> <span class="comment">//索引也可以储存在内存中,构建时使用RAMDirectory类,但是很少使用该方式</span></span><br><span class="line"> <span class="comment">//Directory directory = new RAMDirectory();</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">//2、基于Directory对象创建一个IndexWriter对象</span></span><br><span class="line"> IndexWriterConfig config = <span class="keyword">new</span> IndexWriterConfig();</span><br><span class="line"> IndexWriter indexWriter = <span class="keyword">new</span> IndexWriter(directory,config);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//3、读取磁盘上的文件,获取每个文件的内容</span></span><br><span class="line"> File[] files = <span class="keyword">new</span> File(<span class="string">"要解析文件的目录的绝对路径"</span>).listFiles();</span><br><span class="line"> <span class="keyword">for</span> (File file : files) {</span><br><span class="line"> <span class="comment">//获取文档路径</span></span><br><span class="line"> String filePath = file.getPath();</span><br><span class="line"> <span class="comment">//获取文档名称</span></span><br><span class="line"> String fileName = file.getName();</span><br><span class="line"> <span class="comment">//获取文档大小</span></span><br><span class="line"> <span class="keyword">long</span> fileSize = FileUtils.sizeOf(file);</span><br><span class="line"> <span class="comment">//获取文档内容</span></span><br><span class="line"> String fileContext = FileUtils.readFileToString(file, <span class="string">"utf-8"</span>);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//4、把获取的文件内容解析到域中</span></span><br><span class="line"> Field filePathField = <span class="keyword">new</span> StringField(<span class="string">"filePath"</span>,filePath,Field.Store.YES);</span><br><span class="line"> Field fileNameField = <span class="keyword">new</span> TextField(<span class="string">"fileName"</span>,fileName,Field.Store.YES);</span><br><span class="line"> Field fileSizeField = <span class="keyword">new</span> LongPoint(<span class="string">"fileSize"</span>,fileSize);</span><br><span class="line"> Field fileContextField = <span class="keyword">new</span> TextField(<span class="string">"fileContext"</span>,fileContext,Field.Store.YES);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//5、创建文档对象,将域添加到文档对象中</span></span><br><span class="line"> <span class="comment">// 此时文档对象就是由多个域构成,多个文档对象可能包含相同的域</span></span><br><span class="line"> Document document = <span class="keyword">new</span> Document();</span><br><span class="line"> document.add(filePathField);</span><br><span class="line"> document.add(fileNameField);</span><br><span class="line"> document.add(fileSizeField);</span><br><span class="line"> document.add(fileContextField);</span><br><span class="line"></span><br><span class="line"> <span class="comment">//6、把文档对象写入索引库</span></span><br><span class="line"> indexWriter.addDocument(document);</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//7、关闭indexwriter对象</span></span><br><span class="line"> indexWriter.close();</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><strong>3、Field域的属性</strong></p>
<p>上述几个用到的几个域的属性详细说明如下</p>
<table>
<thead>
<tr>
<th align="center">Field类</th>
<th align="center">数据类型</th>
<th align="center">Analyzed 是否分析</th>
<th align="center">Indexed 是否索引</th>
<th align="center">Stored 是否存储</th>
<th align="center">说明</th>
</tr>
</thead>
<tbody><tr>
<td align="center">StringField(FieldName, FieldValue,Store.YES))</td>
<td align="center">字符串</td>
<td align="center">N</td>
<td align="center">Y</td>
<td align="center">Y或N</td>
<td align="center">这个Field用来构建一个字符串Field,但是不会进行分析,会将整个串存储在索引中,比如(订单号,姓名等) 是否存储在文档中用Store.YES或Store.NO决定</td>
</tr>
<tr>
<td align="center">LongPoint(String name, long… point)</td>
<td align="center">Long型</td>
<td align="center">Y</td>
<td align="center">Y</td>
<td align="center">N</td>
<td align="center">可以使用LongPoint、IntPoint等类型存储数值类型的数据。让数值类型可以进行索引。但是不能存储数据,如果想存储数据还需要使用StoredField。</td>
</tr>
<tr>
<td align="center">StoredField(FieldName, FieldValue)</td>
<td align="center">重载方法,支持多种类型</td>
<td align="center">N</td>
<td align="center">N</td>
<td align="center">Y</td>
<td align="center">这个Field用来构建不同类型Field 不分析,不索引,但要Field存储在文档中</td>
</tr>
<tr>
<td align="center">TextField(FieldName, FieldValue, Store.NO) 或 TextField(FieldName, reader)</td>
<td align="center">字符串 或 流</td>
<td align="center">Y</td>
<td align="center">Y</td>
<td align="center">Y或N</td>
<td align="center">如果是一个Reader, lucene猜测内容比较多,会采用Unstored的策略.</td>
</tr>
</tbody></table>
<h4 id="查询索引库"><a href="#查询索引库" class="headerlink" title="查询索引库"></a>查询索引库</h4><figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">searchIndex</span><span class="params">()</span> <span class="keyword">throws</span> Exception</span>{</span><br><span class="line"> <span class="comment">//1、创建一个Director对象,指定索引库的位置</span></span><br><span class="line"> Directory directory = FSDirectory.open(<span class="keyword">new</span> File(<span class="string">"索引库地址"</span>).toPath());</span><br><span class="line"> <span class="comment">//2、创建一个IndexReader对象</span></span><br><span class="line"> IndexReader indexReader = DirectoryReader.open(directory);</span><br><span class="line"> <span class="comment">//3、创建一个IndexSearcher对象,构造方法中的参数传入indexReader对象。</span></span><br><span class="line"> IndexSearcher indexSearcher = <span class="keyword">new</span> IndexSearcher(indexReader);</span><br><span class="line"> <span class="comment">//4、创建一个Query对象,Query是一个抽象类,所以使用它的子类TermQuery</span></span><br><span class="line"> <span class="comment">//Term对象传入两个参数,第一个参数是要查询的域,第二个是查询的关键词</span></span><br><span class="line"> Query query = <span class="keyword">new</span> TermQuery(<span class="keyword">new</span> Term(<span class="string">"fileContext"</span>,<span class="string">"spring"</span>));</span><br><span class="line"> <span class="comment">//5、执行查询,得到一个TopDocs对象,search方法第二个参数指定一次最多查询几条数据</span></span><br><span class="line"> TopDocs topDocs = indexSearcher.search(query, <span class="number">10</span>);</span><br><span class="line"> <span class="comment">//6、取查询结果的总记录数</span></span><br><span class="line"> <span class="keyword">long</span> totalHits = topDocs.totalHits;</span><br><span class="line"> System.out.println(<span class="string">"查询总条数:"</span>+totalHits);</span><br><span class="line"> <span class="comment">//7、取文档列表,TopDocs对象的scoreDocs方法返回查询后的所有文档的scoreDoc对象</span></span><br><span class="line"> <span class="keyword">for</span> (ScoreDoc scoreDoc : topDocs.scoreDocs) {</span><br><span class="line"> <span class="comment">//scoreDoc.doc存储了document对象的id,通过id获取到document对象</span></span><br><span class="line"> <span class="comment">//8、打印文档中的内容</span></span><br><span class="line"> Document document = indexSearcher.doc(scoreDoc.doc);</span><br><span class="line"> System.out.println(<span class="string">"文件名称:"</span>+document.get(<span class="string">"fileName"</span>));</span><br><span class="line"> System.out.println(<span class="string">"文件路径:"</span>+document.get(<span class="string">"filePath"</span>));</span><br><span class="line"> System.out.println(<span class="string">"文件大小:"</span>+document.get(<span class="string">"fileSize"</span>));</span><br><span class="line"> System.out.println(<span class="string">"文件内容:"</span>+document.get(<span class="string">"fileContext"</span>));</span><br><span class="line"> System.out.println(<span class="string">"-----------------------------"</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="comment">//9、关闭IndexReader对象</span></span><br><span class="line"> indexReader.close();</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h4 id="删除索引"><a href="#删除索引" class="headerlink" title="删除索引"></a>删除索引</h4><p><strong>1、删除全部索引</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Before</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">init</span><span class="params">()</span> <span class="keyword">throws</span> Exception</span>{</span><br><span class="line"> indexWriter = <span class="keyword">new</span> IndexWriter(FSDirectory.open(<span class="keyword">new</span> File(<span class="string">"索引库路径"</span>).toPath()),<span class="keyword">new</span> IndexWriterConfig(<span class="keyword">new</span> IKAnalyzer()));</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//删除索引库全部索引</span></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">deleteAllIndex</span><span class="params">()</span> <span class="keyword">throws</span> IOException </span>{</span><br><span class="line"> indexWriter.deleteAll();</span><br><span class="line"> indexWriter.close();</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><strong>2、删除指定索引</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Before</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">init</span><span class="params">()</span> <span class="keyword">throws</span> Exception</span>{</span><br><span class="line"> indexWriter = <span class="keyword">new</span> IndexWriter(FSDirectory.open(<span class="keyword">new</span> File(<span class="string">"索引库路径"</span>).toPath()),<span class="keyword">new</span> IndexWriterConfig(<span class="keyword">new</span> IKAnalyzer()));</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">deleteByQuery</span><span class="params">()</span> <span class="keyword">throws</span> Exception</span>{</span><br><span class="line"> <span class="comment">//删除文件名包含apache的文档的索引</span></span><br><span class="line"> <span class="keyword">long</span> num = indexWriter.deleteDocuments(<span class="keyword">new</span> Term(<span class="string">"fileName"</span>, <span class="string">"apache"</span>));</span><br><span class="line"> System.out.println(num);</span><br><span class="line"> indexWriter.close();</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h4 id="增加索引"><a href="#增加索引" class="headerlink" title="增加索引"></a>增加索引</h4><p>新增一条索引的过程跟创建索引库的过程差不多,差别只在于增加索引只需要对一个原始文档进行解析</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Test</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">addDocument</span><span class="params">()</span> <span class="keyword">throws</span> Exception</span>{</span><br><span class="line"> File file = <span class="keyword">new</span> File(<span class="string">"D:\\BaiduNetdiskDownload\\java\\12-lucene\\笔记.txt"</span>);</span><br><span class="line"> Document document = <span class="keyword">new</span> Document();</span><br><span class="line"> document.add(<span class="keyword">new</span> TextField(<span class="string">"fileName"</span>,file.getName(), Field.Store.YES));</span><br><span class="line"> document.add(<span class="keyword">new</span> StringField(<span class="string">"filePath"</span>,file.getPath(), Field.Store.YES));</span><br><span class="line"> document.add(<span class="keyword">new</span> LongPoint(<span class="string">"fileSize"</span>, FileUtils.sizeOf(file)));</span><br><span class="line"> document.add(<span class="keyword">new</span> TextField(<span class="string">"fileName"</span>,file.getName(), Field.Store.YES));</span><br><span class="line"> indexWriter.addDocument(document);</span><br><span class="line"> indexWriter.close();</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h4 id="更新索引"><a href="#更新索引" class="headerlink" title="更新索引"></a>更新索引</h4><p>更新索引的过程就是先删除该文档的原始索引,然后再创建一条该文档的新索引</p>
]]></content>
<categories>
<category>学习随笔</category>
</categories>
<tags>
<tag>lucene</tag>
</tags>
</entry>
<entry>
<title>将jar包手动添加到maven仓库</title>
<url>/2020/03/30/%E5%B0%86jar%E5%8C%85%E6%89%8B%E5%8A%A8%E6%B7%BB%E5%8A%A0%E5%88%B0maven%E4%BB%93%E5%BA%93/</url>
<content><![CDATA[<h3 id="将jar包手动添加到maven仓库"><a href="#将jar包手动添加到maven仓库" class="headerlink" title="将jar包手动添加到maven仓库"></a>将jar包手动添加到maven仓库</h3><p><strong>1、语法</strong></p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">mvn install:install-file -Dfile=jar包的位置 -DgroupId=jar包设置的groupId -DartifactId=jar包设置的artifactId -Dversion=jar包版本 -Dpackaging=jar -DgeneratePom=true</span><br></pre></td></tr></table></figure>
<p><strong>2、示例</strong></p>
<p>例如: 将D盘下的的ojdbc6.jar导入maven仓库,在任意位置打开CMD,然后输入下面的命令</p>
<p><code>注意:</code>网上的ojdbc14、ojdbc6后面的14和6表示的是所需jdk的最低版本,ojdbc6是Oracle11g后才更新的驱动包,比ojdbc14要新,所以下面设置版本的时候我使用的是oracle数据库的版本作为驱动的版本</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">mvn install:install-file -Dfile=D:\ojdbc6.jar -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=11.2.0.1.0 -Dpackaging=jar -DgeneratePom=true</span><br></pre></td></tr></table></figure>
<p>当看到<code>BUILD SUCCESS</code>则表示安装成功</p>
<img src="/2020/03/30/%E5%B0%86jar%E5%8C%85%E6%89%8B%E5%8A%A8%E6%B7%BB%E5%8A%A0%E5%88%B0maven%E4%BB%93%E5%BA%93/1.png" class="">
<p>但从安装路径上看默认是安装到C盘的用户目录下,但通常我们的本地仓库安装在其他的路径,如果想要安装到指定的仓库,只需要修改maven的配置文件,然后重新执行上面的命令即可</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line">#找到maven的安装路径,然后找到conf/settings.xml文件,打开找到<span class="tag"><<span class="name">localRepository</span>></span><span class="tag"></<span class="name">localRepository</span>></span>标签,然后将里面的路径修改成我们指定的仓库路径</span><br><span class="line"><span class="tag"><<span class="name">localRepository</span>></span>D:/devSoftware/maven/apache-maven-3.3.9/repository<span class="tag"></<span class="name">localRepository</span>></span></span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>学习随笔</category>
</categories>
<tags>
<tag>maven</tag>
<tag>工具使用</tag>
</tags>
</entry>
<entry>
<title>AOP的日志获取</title>
<url>/2020/03/25/AOP%E7%9A%84%E6%97%A5%E5%BF%97/</url>
<content><![CDATA[<p>在学习系统权限权限项目时,需要将用户在web层的请求操作的信息提取出来,作为日志信息存储到数据库中,整体的思路就是对web层的所有实例对象的所有方法做一个AOP切面,当Spring MVC前端控制器调用实例对象内的方法时,就会触发切面对应的通知类,并执行里面的通知方法</p>
<p><strong>日志的实体类</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SysLog</span> </span>{</span><br><span class="line"> <span class="keyword">private</span> String id;</span><br><span class="line"> <span class="keyword">private</span> Date visitTime;<span class="comment">//访问的时间</span></span><br><span class="line"> <span class="keyword">private</span> String visitTimeStr;</span><br><span class="line"> <span class="keyword">private</span> String username;<span class="comment">//访问用户名</span></span><br><span class="line"> <span class="keyword">private</span> String ip;<span class="comment">//访问者的IP</span></span><br><span class="line"> <span class="keyword">private</span> String url;<span class="comment">//访问者的url</span></span><br><span class="line"> <span class="keyword">private</span> Long executionTime;<span class="comment">//访问执行的时间</span></span><br><span class="line"> <span class="keyword">private</span> String method;<span class="comment">//访问的方法接口</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><strong>日志AOP通知类</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Controller</span></span><br><span class="line"><span class="meta">@Aspect</span></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">LogAop</span> </span>{</span><br><span class="line"></span><br><span class="line"> <span class="meta">@Autowired</span></span><br><span class="line"> <span class="keyword">private</span> HttpServletRequest request;</span><br><span class="line"> <span class="meta">@Autowired</span></span><br><span class="line"> <span class="keyword">private</span> SysLogService sysLogService;</span><br><span class="line"> <span class="keyword">private</span> Date visitTime;<span class="comment">//访问时间</span></span><br><span class="line"></span><br><span class="line"> <span class="comment">//配置一个切入点</span></span><br><span class="line"> <span class="meta">@Pointcut</span>(<span class="string">"execution(* controller.*.*(..))"</span>)</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">pointcut</span><span class="params">()</span></span>{};</span><br><span class="line"></span><br><span class="line"> <span class="comment">//配置方法执行前操作</span></span><br><span class="line"> <span class="meta">@Before</span>(<span class="string">"pointcut()"</span>)</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">before</span><span class="params">(JoinPoint joinPoint)</span> <span class="keyword">throws</span> NoSuchMethodException </span>{</span><br><span class="line"> <span class="comment">//获取访问时间</span></span><br><span class="line"> visitTime = <span class="keyword">new</span> Date();</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">//配置方法执行后操作,除访问时间,其他操作都放在后置</span></span><br><span class="line"> <span class="meta">@After</span>(<span class="string">"execution(* controller.*.*(..))"</span>)</span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">afterReturning</span><span class="params">(JoinPoint joinPoint)</span></span>{</span><br><span class="line"> <span class="comment">//获取执行的时间</span></span><br><span class="line"> Long executionTime = <span class="keyword">new</span> Date().getTime() - visitTime.getTime();</span><br><span class="line"> <span class="comment">//获取访问用户名</span></span><br><span class="line"> String username = ((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();</span><br><span class="line"> <span class="comment">//获取访问的类路径</span></span><br><span class="line"> Class excutionClass = joinPoint.getTarget().getClass();</span><br><span class="line"> <span class="comment">//获取访问的方法</span></span><br><span class="line"> String methodName = joinPoint.getSignature().getName();</span><br><span class="line"> <span class="comment">//获取访问的IP</span></span><br><span class="line"> String ip = request.getRemoteAddr();</span><br><span class="line"> <span class="comment">//获取访问的url路径</span></span><br><span class="line"> String url = request.getRequestURL().toString();</span><br><span class="line"></span><br><span class="line"> <span class="comment">//将上述的信息存储到SysLog,并存储到数据库</span></span><br><span class="line"> SysLog sysLog = <span class="keyword">new</span> SysLog();</span><br><span class="line"> sysLog.setExecutionTime(executionTime);</span><br><span class="line"> sysLog.setIp(ip);</span><br><span class="line"> sysLog.setMethod(excutionClass.getName()+<span class="string">"."</span>+methodName);</span><br><span class="line"> sysLog.setUrl(url);</span><br><span class="line"> sysLog.setUsername(username);</span><br><span class="line"> sysLog.setVisitTime(visitTime);</span><br><span class="line"> sysLogService.save(sysLog);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>学习随笔</category>
</categories>
<tags>
<tag>spring security</tag>
</tags>
</entry>
<entry>
<title>spring security-方法权限控制</title>
<url>/2020/03/25/spring%20security-%E6%96%B9%E6%B3%95%E6%9D%83%E9%99%90%E6%8E%A7%E5%88%B6/</url>
<content><![CDATA[<h3 id="spring-security-方法权限控制基本使用"><a href="#spring-security-方法权限控制基本使用" class="headerlink" title="spring security-方法权限控制基本使用"></a>spring security-方法权限控制基本使用</h3><p>在服务端中spring security可以使用注解的方式去控制用户访问方法,常见的注解方式有三种:JSR-250注解、@Secured注解、spring El表达式注解方式,三种注解方式默认都是关闭状态,可以在spring-security.xml文件中统一开启</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">security:global-method-security</span> <span class="attr">pre-post-annotations</span>=<span class="string">"enabled"</span> <span class="attr">jsr250-annotations</span>=<span class="string">"enabled"</span> <span class="attr">secured-annotations</span>=<span class="string">"enabled"</span>></span><span class="tag"></<span class="name">security:global-method-security</span>></span></span><br></pre></td></tr></table></figure>
<p>黑马的笔记中有这么一段话:Spring Security默认是禁用注解的,要想开启注解,需要在继承<br>WebSecurityConfigurerAdapter的类上加@EnableGlobalMethodSecurity注解,并在该类中将<br>AuthenticationManager定义为Bean。个人不清楚这句话的实际操作,但在测试中没有执行该操作也能正常实现方法权限控制,下面时三种注解方式的基本使用</p>
<h4 id="JSR-250"><a href="#JSR-250" class="headerlink" title="JSR-250"></a>JSR-250</h4><p><strong>1、引入依赖</strong></p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>javax.annotation<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>jsr250-api<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>1.0<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span></span><br></pre></td></tr></table></figure>
<p><strong>2、在spring-security配置文件中开启注解</strong></p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">security:global-method-security</span> <span class="attr">jsr250-annotations</span>=<span class="string">"enabled"</span>/></span></span><br></pre></td></tr></table></figure>
<p><strong>3、在指定方法中添加注解权限</strong></p>
<p>@RolesAllowed表示访问该方法应该具有的角色</p>
<p>@PermitAll该方法所有角色都能访问</p>
<p>@DenyAll该方法所有角色都不能访问</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@RolesAllowed</span>({<span class="string">"ADMIN"</span>})</span><br><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/findAll"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> ModelAndView <span class="title">findAll</span><span class="params">()</span></span>{</span><br><span class="line"> ModelAndView mav = <span class="keyword">new</span> ModelAndView();</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> mav.addObject(<span class="string">"productList"</span>,productService.findAll());</span><br><span class="line"> } <span class="keyword">catch</span> (Exception e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> mav.setViewName(<span class="string">"product-list"</span>);</span><br><span class="line"> <span class="keyword">return</span> mav;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h4 id="Secured注解"><a href="#Secured注解" class="headerlink" title="@Secured注解"></a>@Secured注解</h4><p><strong>1、在spring-security配置文件中开启注解**</strong></p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">security:global-method-security</span> <span class="attr">secured-annotations</span>=<span class="string">"enabled"</span>/></span></span><br></pre></td></tr></table></figure>
<p><strong>2、在指定方法中添加注释权限</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="meta">@Secured</span>({<span class="string">"ROLE_ADMIN"</span>})</span><br><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/findAll"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> ModelAndView <span class="title">findAll</span><span class="params">()</span></span>{</span><br><span class="line"> ModelAndView mav = <span class="keyword">new</span> ModelAndView();</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> mav.addObject(<span class="string">"productList"</span>,productService.findAll());</span><br><span class="line"> } <span class="keyword">catch</span> (Exception e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> mav.setViewName(<span class="string">"product-list"</span>);</span><br><span class="line"> <span class="keyword">return</span> mav;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h4 id="spring-EL表达式注释"><a href="#spring-EL表达式注释" class="headerlink" title="spring EL表达式注释"></a>spring EL表达式注释</h4><h5 id="服务端的使用"><a href="#服务端的使用" class="headerlink" title="服务端的使用"></a>服务端的使用</h5><p><strong>1、在spring-security配置文件中开启注解**</strong></p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">security:global-method-security</span> <span class="attr">pre-post-annotations</span>=<span class="string">"disabled"</span>/></span></span><br></pre></td></tr></table></figure>
<p><strong>2、在指定方法中添加注释权限</strong></p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//方式一:指定特定的用户</span></span><br><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/findAll"</span>)</span><br><span class="line"><span class="meta">@PreAuthorize</span>(<span class="string">"authentication.principal.username == 'user'"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> ModelAndView <span class="title">findAll</span><span class="params">()</span></span>{</span><br><span class="line"> ModelAndView mav = <span class="keyword">new</span> ModelAndView();</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> mav.addObject(<span class="string">"productList"</span>,productService.findAll());</span><br><span class="line"> } <span class="keyword">catch</span> (Exception e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> mav.setViewName(<span class="string">"product-list"</span>);</span><br><span class="line"> <span class="keyword">return</span> mav;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//方式二:指定用户角色</span></span><br><span class="line"><span class="meta">@RequestMapping</span>(<span class="string">"/findAll"</span>)</span><br><span class="line"><span class="meta">@PreAuthorize</span>(<span class="string">"hasAnyRole('ROLE_ADMIN','ROLE_USER')"</span>)</span><br><span class="line"><span class="function"><span class="keyword">public</span> ModelAndView <span class="title">findAll</span><span class="params">()</span></span>{</span><br><span class="line"> ModelAndView mav = <span class="keyword">new</span> ModelAndView();</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> mav.addObject(<span class="string">"productList"</span>,productService.findAll());</span><br><span class="line"> } <span class="keyword">catch</span> (Exception e) {</span><br><span class="line"> e.printStackTrace();</span><br><span class="line"> }</span><br><span class="line"> mav.setViewName(<span class="string">"product-list"</span>);</span><br><span class="line"> <span class="keyword">return</span> mav;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><strong>403页面配置</strong></p>
<p>对于没有访问权限的角色,访问方法时会报403错误,此时可以配置一个自定义的403错误页面,只需在web.xml文件加入以下配置</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line">//下面配置表示,出现403错误代码时,重定向到自定义的页面</span><br><span class="line"><span class="tag"><<span class="name">error-page</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">error-code</span>></span>403<span class="tag"></<span class="name">error-code</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">location</span>></span>/403.jsp<span class="tag"></<span class="name">location</span>></span></span><br><span class="line"><span class="tag"></<span class="name">error-page</span>></span></span><br></pre></td></tr></table></figure>
<h5 id="在页面端的使用"><a href="#在页面端的使用" class="headerlink" title="在页面端的使用"></a>在页面端的使用</h5><p><strong>1、引入依赖</strong></p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>org.springframework.security<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>spring-security-taglibs<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>5.0.2.RELEASE<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span></span><br></pre></td></tr></table></figure>
<p><strong>2、在页面中使用y</strong></p>
<figure class="highlight"><table><tr><td class="code"><pre><span class="line"><span class="comment">//1、先在jsp页面中导入</span></span><br><span class="line"><%<span class="meta">@taglib</span> prefix=<span class="string">"security"</span> uri=<span class="string">"http://www.springframework.org/security/tags"</span> %></span><br><span class="line"></span><br><span class="line"><span class="comment">//在页面中获取用户名</span></span><br><span class="line"><security:authentication property="principal.username"></security:authentication></span><br><span class="line"></span><br><span class="line"><span class="comment">//根据权限显示菜单,只有匹配ROLE_ADMIN角色才显示xxx内容</span></span><br><span class="line"><security:authorize access=<span class="string">"hasAnyRole('ROLE_ADMIN')"</span>></span><br><span class="line"> xxx</span><br><span class="line"></security:authorize></span><br></pre></td></tr></table></figure>
<h5 id="PreAuthorize注解的其他使用"><a href="#PreAuthorize注解的其他使用" class="headerlink" title="@PreAuthorize注解的其他使用"></a>@PreAuthorize注解的其他使用</h5><p>Spring Security允许我们在定义URL访问或方法访问所应有的权限时使用Spring EL表达式,在定义所需的访问权限时如果对应的表达式返回结果为true则表示拥有对应的权限,反之则无。Spring Security可用表达式对象的基类是SecurityExpressionRoot,其为我们提供了如下在使用Spring EL表达式对URL或方法进行权限控制时通用的内置表达式</p>
<table>
<thead>
<tr>
<th><strong>表达式</strong></th>
<th><strong>描述</strong></th>
</tr>
</thead>
<tbody><tr>
<td>hasRole([role])</td>
<td>当前用户是否拥有指定角色。</td>
</tr>
<tr>
<td>hasAnyRole([role1,role2])</td>
<td>多个角色是一个以逗号进行分隔的字符串。如果当前用户拥有指定角色中的任意一个则返回true。</td>
</tr>
<tr>
<td>hasAuthority([auth])</td>
<td>等同于hasRole</td>
</tr>
<tr>
<td>hasAnyAuthority([auth1,auth2])</td>
<td>等同于hasAnyRole</td>
</tr>
<tr>
<td>Principle</td>
<td>代表当前用户的principle对象</td>
</tr>
<tr>
<td>authentication</td>
<td>直接从SecurityContext获取的当前Authentication对象</td>
</tr>
<tr>
<td>permitAll</td>
<td>总是返回true,表示允许所有的</td>
</tr>
<tr>
<td>denyAll</td>
<td>总是返回false,表示拒绝所有的</td>
</tr>
<tr>
<td>isAnonymous()</td>
<td>当前用户是否是一个匿名用户</td>
</tr>
<tr>
<td>isRememberMe()</td>
<td>表示当前用户是否是通过Remember-Me自动登录的</td>
</tr>
<tr>
<td>isAuthenticated()</td>
<td>表示当前用户是否已经登录认证成功了。</td>
</tr>
<tr>
<td>isFullyAuthenticated()</td>
<td>如果当前用户既不是一个匿名用户,同时又不是通过Remember-Me自动登录的,则返回true。</td>
</tr>
</tbody></table>
]]></content>
<categories>
<category>学习随笔</category>
</categories>
<tags>
<tag>spring security</tag>
<tag>权限控制</tag>
</tags>
</entry>
<entry>
<title>redis的安装</title>
<url>/2020/03/20/redis%E7%9A%84%E5%AE%89%E8%A3%85/</url>
<content><![CDATA[<p><strong>1. 获取下载链接</strong></p>
<p>rides文档:<a href="https://www.redis.net.cn/tutorial/3501.html" target="_blank" rel="noopener">https://www.redis.net.cn/tutorial/3501.html</a></p>
<p>下载链接:<a href="https://www.redis.net.cn/download/" target="_blank" rel="noopener">https://www.redis.net.cn/download/</a></p>
<img src="/2020/03/20/redis%E7%9A%84%E5%AE%89%E8%A3%85/1.png" class="">
<p><strong>2.下载、解压、编译</strong></p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">cd /usr/local</span><br><span class="line">wget http://download.redis.io/releases/redis-5.0.4.tar.gz</span><br><span class="line">tar xzf redis-5.0.4.tar.gz</span><br><span class="line">cd redis-5.0.4</span><br><span class="line">make</span><br></pre></td></tr></table></figure>
<p>注意:如果执行make失败可能是因为没有安装gcc,redis的C实现的,需要使用gcc来编译</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash">执行make失败则安装下面软件后在尝试</span></span><br><span class="line">yum install cpp</span><br><span class="line">yum install binutils</span><br><span class="line">yum install glibc</span><br><span class="line">yum install glibc-kernheaders</span><br><span class="line">yum install glibc-common</span><br><span class="line">yum install glibc-devel</span><br><span class="line">yum install gcc</span><br><span class="line">yum install make</span><br></pre></td></tr></table></figure>
<p><strong>3.测试启动服务器</strong></p>
<p>二进制文件是编译完成后在<code>src</code>目录下,进入该目录启动数据库服务</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">cd src</span><br><span class="line">./redis-server</span><br></pre></td></tr></table></figure>
<p>重新打开一个窗口,启动客户端</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">cd /usr/local/redis-5.0.4/src</span><br><span class="line">./redis-cli</span><br></pre></td></tr></table></figure>
<p>客户端启动后输入<code>info</code>命令可查看数据库信息</p>
<p><strong>4. 开启数据库后台运行及远程访问</strong></p>
<p>打开redis.conf配置文件,配置文件一般存在于安装目录下</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">cd /usr/local/redis-5.0.4</span><br><span class="line">vim redis.conf</span><br></pre></td></tr></table></figure>
<p>按<code>i</code>进行文件修改</p>
<p>开启后台运行</p>
<img src="/2020/03/20/redis%E7%9A%84%E5%AE%89%E8%A3%85/2.png" class="">
<p>开启远程访问</p>
<img src="/2020/03/20/redis%E7%9A%84%E5%AE%89%E8%A3%85/3.png" class="">
<img src="/2020/03/20/redis%E7%9A%84%E5%AE%89%E8%A3%85/4.png" class="">
<p>然后按<code>Esc</code>键输入 <code>:wq</code>保存退出</p>
<p>最后重新启动数据库服务</p>
<figure class="highlight shell"><table><tr><td class="code"><pre><span class="line">src/redis-server ./redis.conf</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>数据库</category>
</categories>
<tags>
<tag>redis</tag>
</tags>
</entry>
<entry>
<title>Token认证实现</title>
<url>/2020/03/20/Token%E8%AE%A4%E8%AF%81%E5%AE%9E%E7%8E%B0/</url>
<content><![CDATA[<h3 id="JWT-Token认证实现"><a href="#JWT-Token认证实现" class="headerlink" title="JWT Token认证实现"></a>JWT Token认证实现</h3><h4 id="简单说明"><a href="#简单说明" class="headerlink" title="简单说明"></a>简单说明</h4><p>JWT Token是Token Auth认证的一种实现方式,当用户将用户名和密码发送到服务器认证且认证通过后,服务器会将认证后的一些信息 例如:认证过期时间、用户名、用户的访问权限等,将这些信息加密成一个字符串(即token)后返回给客户端,返回的形式可以是Cookie形式也可以是json格式返回。每次用户请求新页面时只需把该字符串携带上即可。</p>
<p>JWT Token在加密认证后的信息时,会使用加密算法+密钥的形式生成一个token字符串,token字符串上有一段加密后的签名字符串,用户请求资源时 服务端会先使用密钥验证token的签名字符串,由于密钥是服务器上私有的,只有服务器自己知道,所以确保了验证的安全性,当使用密钥验证签名失败时,则认证该用户认证失败</p>
<img src="/2020/03/20/Token%E8%AE%A4%E8%AF%81%E5%AE%9E%E7%8E%B0/1.png" class="">
<h4 id="JWT-token的组成和生成过程"><a href="#JWT-token的组成和生成过程" class="headerlink" title="JWT token的组成和生成过程"></a>JWT token的组成和生成过程</h4><p>一个JWT token字符串由三部分组成:头部(header)、载荷(payload)、签名(signature)</p>
<p>形成一个JWT token字符串的步骤,sign()是生成token的方法:</p>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">private</span> String <span class="title">sign</span><span class="params">()</span> <span class="keyword">throws</span> SignatureGenerationException </span>{</span><br><span class="line"> <span class="comment">//1.使用Base64加密头部(header)信息形成字符串</span></span><br><span class="line"> String header = Base64.encodeBase64URLSafeString(<span class="keyword">this</span>.headerJson.getBytes(StandardCharsets.UTF_8));</span><br><span class="line"> <span class="comment">//2.使用Base64加密载荷(payload)信息形成字符串</span></span><br><span class="line"> String payload = Base64.encodeBase64URLSafeString(<span class="keyword">this</span>.payloadJson.getBytes(StandardCharsets.UTF_8));</span><br><span class="line"> <span class="comment">//3.将头部字符串和载荷字符串用 点号 连接形成一个新的字符串</span></span><br><span class="line"> String content = String.format(<span class="string">"%s.%s"</span>, header, payload);</span><br><span class="line"> <span class="comment">//4.获取使用密钥加密后的签名</span></span><br><span class="line"> <span class="keyword">byte</span>[] signatureBytes = <span class="keyword">this</span>.algorithm.sign(content.getBytes(StandardCharsets.UTF_8));</span><br><span class="line"> <span class="comment">//5.使用Base64加密签名(signature)信息形成字符串</span></span><br><span class="line"> String signature = Base64.encodeBase64URLSafeString(signatureBytes);</span><br><span class="line"> <span class="comment">//将加密后的字符串连接后返回</span></span><br><span class="line"> <span class="keyword">return</span> String.format(<span class="string">"%s.%s"</span>, content, signature);</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h5 id="头部(header)"><a href="#头部(header)" class="headerlink" title="头部(header)"></a>头部(header)</h5><p>JWT有一个头部,头部用于描述JWT的基本信息,一共有两个属性</p>
<ul>
<li>typ:用于描述token字符串的类型,默认会填入“JWT”</li>
<li>alg:签发时使用的签名或算法</li>
</ul>
<h5 id="载荷(payload)"><a href="#载荷(payload)" class="headerlink" title="载荷(payload)"></a>载荷(payload)</h5><p>载荷有固定的部分,也可以传入自定义的属性,自定义的内容可以是用户名、用户权限等,下面是固定的属性</p>
<ul>
<li>iss:该JWT签发的主体,即谁生成了这个JWT</li>
<li>sub:该JWT的所有人,可以看成是客户端</li>
<li>aud:该JWT的接收对象</li>
<li>iat:一个时间戳,表示该JWT的签发时间</li>
<li>nbf:一个时间戳,表示该JWT的生效时间</li>
<li>exp:一个时间戳,表示该JWT的过期时间</li>
<li>jti:JWT的唯一标识符</li>
</ul>
<h5 id="签名(signature)"><a href="#签名(signature)" class="headerlink" title="签名(signature)"></a>签名(signature)</h5><p>签名没有属性值,但是在形成签名时需要传入密钥</p>
<h4 id="JWT-Token实现"><a href="#JWT-Token实现" class="headerlink" title="JWT Token实现"></a>JWT Token实现</h4><p>引入依赖</p>
<figure class="highlight xml"><table><tr><td class="code"><pre><span class="line"><span class="tag"><<span class="name">dependency</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">groupId</span>></span>com.auth0<span class="tag"></<span class="name">groupId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">artifactId</span>></span>java-jwt<span class="tag"></<span class="name">artifactId</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">version</span>></span>3.2.0<span class="tag"></<span class="name">version</span>></span></span><br><span class="line"><span class="tag"></<span class="name">dependency</span>></span></span><br></pre></td></tr></table></figure>
<figure class="highlight java"><table><tr><td class="code"><pre><span class="line"><span class="comment">//获取指定过期时期和自定义载荷的token</span></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">*</span></span><br><span class="line"><span class="comment">* <span class="doctag">@param</span> expiryTime token存活时间,毫秒</span></span><br><span class="line"><span class="comment">* <span class="doctag">@param</span> payloadClaims 传入的自定义键值对</span></span><br><span class="line"><span class="comment">* <span class="doctag">@return</span></span></span><br><span class="line"><span class="comment">* <span class="doctag">@throws</span> UnsupportedEncodingException</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> String <span class="title">getToken</span><span class="params">(<span class="keyword">long</span> expiryTime,Map<String,String> payloadClaims)</span> <span class="keyword">throws</span> UnsupportedEncodingException </span>{</span><br><span class="line"> <span class="comment">//获取生成的时间</span></span><br><span class="line"> <span class="keyword">long</span> currentTime = System.currentTimeMillis();</span><br><span class="line"> Date iat = <span class="keyword">new</span> Date(currentTime);</span><br><span class="line"> <span class="comment">//获取过期时间</span></span><br><span class="line"> Date exp = <span class="keyword">new</span> Date(currentTime + expiryTime);</span><br><span class="line"> JWTCreator.Builder builder = JWT.create()</span><br><span class="line"> .withIssuer(iss)<span class="comment">//设置签发主体</span></span><br><span class="line"> .withIssuedAt(iat)<span class="comment">//设置生成时间</span></span><br><span class="line"> .withExpiresAt(exp);<span class="comment">//设置过期时间</span></span><br><span class="line"> <span class="comment">//设置自定义参数</span></span><br><span class="line"> Set<Map.Entry<String, String>> entries = payloadClaims.entrySet();</span><br><span class="line"> <span class="keyword">for</span> (Map.Entry<String, String> entry : entries) {</span><br><span class="line"> builder.withClaim(entry.getKey(),entry.getValue());</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> builder.sign(Algorithm.HMAC256(secret));</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">//解析字符串</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> Map<String, Claim> <span class="title">verify</span><span class="params">(String token)</span> <span class="keyword">throws</span> UnsupportedEncodingException </span>{</span><br><span class="line"> JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(secret)).withIssuer(iss).build();</span><br><span class="line"> DecodedJWT jwt = jwtVerifier.verify(token);</span><br><span class="line"> Map<String, Claim> claims = jwt.getClaims();</span><br><span class="line"> <span class="keyword">return</span> claims;</span><br><span class="line"> <span class="comment">//Map集合的值是Claim类型,若值是String则使用asString方法输出,日期类型使用asDate方法,以此类推</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>开发经验</category>
</categories>
<tags>
<tag>用户认证</tag>
</tags>
</entry>
</search>