問題引入:
我們通常的系統(tǒng)中僅僅做了Web層訪問權(quán)限控制,因?yàn)榇蠖嘞到y(tǒng)只有Web方式的UI做為人機(jī)交互的接口,不提供其它的客戶端,所以業(yè)務(wù)邏輯訪問控制一般可以不用控制,數(shù)據(jù)訪問方面由于一般系統(tǒng)的要求目前尚未達(dá)到這一權(quán)限控制的必要,也沒有完整的進(jìn)行控制。Web層的URL級(jí)控制通常采用J2EE規(guī)范中的Filter來解決,但由于JSF中的跳轉(zhuǎn)并不會(huì)重寫URL,默認(rèn)采用Forward的方式,一般不會(huì)采用Redirect的方式,而且采用Redirect的時(shí)候,開發(fā)時(shí)會(huì)很不方便,很多Request參數(shù)無法傳遞,所以我們實(shí)際上在Filter中獲得的URI往往都不是真實(shí)的地址。
實(shí)際案例:
我們現(xiàn)在有一個(gè)畫面,假如從菜單中進(jìn)入畫面的URI為“l(fā)ist.jsf”,畫面上有“新增”、“查詢”兩個(gè)Button,當(dāng)點(diǎn)擊“查詢”這個(gè)Button時(shí),查詢結(jié)果并顯示在“l(fā)ist.jsf”這個(gè)頁面上,當(dāng)點(diǎn)擊“新增”這個(gè)Button時(shí),跳轉(zhuǎn)到“add.jsf”這個(gè)頁面,新增畫面中還有一個(gè)“返回”Button。當(dāng)我們點(diǎn)擊“新增”時(shí),在Filter中得到的URI為“l(fā)ist.jsf”,實(shí)際上我們要跳轉(zhuǎn)到“add.jsf”這個(gè)頁面,當(dāng)我們點(diǎn)擊“返回”Button時(shí),F(xiàn)ilter中得到URI的是“add.jsf”,這與我們實(shí)際要跳轉(zhuǎn)到的頁面“l(fā)ist.jsf”又不符。如果我們僅僅在Filter中根據(jù)URI來判斷權(quán)限,那么當(dāng)一個(gè)用戶不具有新增權(quán)限時(shí),就會(huì)出現(xiàn)可以操作新增功能的事情,這樣便未達(dá)到權(quán)限控制的目的。
問題解決:
JSF提供了自定義Application的可能,通過研究JSF的實(shí)現(xiàn)可以發(fā)現(xiàn)JSF控制頁面的跳轉(zhuǎn)都是在NavigationHandler中完成的。那么我們來試著實(shí)現(xiàn)一個(gè)自己的NavigationHandler,解決這一問題。先給出詳細(xì)的實(shí)現(xiàn):
??1
public?class?NavigationHandleWithAuthImpl?extends?NavigationHandler?
{
??2
??3
????/**?*//**
??4
?????*?Field?DEBUGLOG.
??5
?????*/
??6
????private?static?final?Logger?DEBUGLOG?=?Logger.getLogger(Constant.LOG_DEBUG);
??7
??8
????/**?*//**
??9
?????*?Field?ERRORLOG.
?10
?????*/
?11
????private?static?final?Logger?ERRORLOG?=?Logger.getLogger(Constant.LOG_ERROR);
?12
?13
????/**?*//**
?14
?????*?Field?IGNORED_URI.
?15
?????*/
?16
????private?static?final?String?IGNORED_URI?=?"/login.faces;/send.faces;"
?17
????????????+?"/mainlayout.faces;/backForward.faces";
?18
?19
????/**?*//**
?20
?????*?Application?associate?that?contains?navigation?mappings?loaded?from
?21
?????*?configuration?file(s).
?22
?????*/
?23
????private?ApplicationAssociate?associate?=?null;
?24
?25
????/**?*//**
?26
?????*?This?constructor?uses?the?current?<code>Application</code>?instance?to
?27
?????*?obtain?the?navigation?mappings?used?to?make?navigational?decisions.
?28
?????*/
?29
????public?NavigationHandleWithAuthImpl()?
{
?30
????????super();
?31
????????if?(DEBUGLOG.isDebugEnabled())?
{
?32
????????????DEBUGLOG.debug("Created?NavigationHandler?instance?");
?33
????????}
?34
????????//?if?the?user?is?using?the?decorator?pattern,?this?would?cause
?35
????????//?our?ApplicationAssociate?to?be?created,?if?it?isn't?already
?36
????????//?created.
?37
????????ApplicationFactory?aFactory?=?(ApplicationFactory)?FactoryFinder
?38
????????????????.getFactory(FactoryFinder.APPLICATION_FACTORY);
?39
????????aFactory.getApplication();
?40
????????associate?=?ApplicationAssociate.getInstance(ConfigureListener
?41
????????????????.getExternalContextDuringInitialize());
?42
????}
?43
?44
????/**?*//**
?45
?????*?檢查URL權(quán)限
?46
?????*?
?47
?????*?@param?authList
?48
?????*????????????List<FunctionVo>
?49
?????*?@param?uri
?50
?????*????????????String
?51
?????*?@return?boolean
?52
?????*/
?53
????private?boolean?checkURL(List<FunctionVo>?authList,?String?uri)?
{
?54
????????if?(authList?==?null)?
{
?55
????????????return?false;
?56
????????}
?57
????????for?(FunctionVo?vo?:?authList)?
{
?58
????????????String?authUri?=?vo.getUrl();
?59
????????????if?(authUri?!=?null?&&?!authUri.equals(""))?
{
?60
????????????????int?index?=?authUri.indexOf("?");
?61
????????????????if?(index?>=?0)?
{
?62
????????????????????authUri?=?authUri.substring(0,?index);
?63
????????????????}
?64
????????????}
?65
????????????if?(uri.equals("/"?+?authUri))?
{
?66
????????????????return?true;
?67
????????????}
?68
????????}
?69
????????return?false;
?70
????}
?71
?72
????/**?*//**
?73
?????*?Determine?the?next?view?based?on?the?current?view?
?74
?????*?(<code>from-view-id</code>
?75
?????*?stored?in?<code>FacesContext</code>),?<code>fromAction</code>?and
?76
?????*?<code>outcome</code>.
?77
?????*?
?78
?????*?@param?context
?79
?????*????????????The?<code>FacesContext</code>
?80
?????*?@param?fromAction
?81
?????*????????????the?action?reference?string
?82
?????*?@param?outcome
?83
?????*????????????the?outcome?string
?84
?????*/
?85
????public?void?handleNavigation(FacesContext?context,?String?fromAction,
?86
????????????String?outcome)?
{
?87
????????if?(context?==?null)?
{
?88
????????????String?message?=?Util
?89
????????????????????.getExceptionMessageString(Util.
?90
????????????????????????????NULL_PARAMETERS_ERROR_MESSAGE_ID);
?91
????????????message?=?message?+?"?context?"?+?context;
?92
????????????throw?new?NullPointerException(message);
?93
????????}
?94
????????if?(outcome?==?null)?
{
?95
????????????if?(DEBUGLOG.isDebugEnabled())?
{
?96
????????????????DEBUGLOG.debug("No?navigation?rule?found?for?outcome?"
?97
????????????????????????+?outcome?+?"and?viewId?"
?98
????????????????????????+?context.getViewRoot().getViewId()
?99
????????????????????????+?"?Explicitly?remain?on?the?current?view?");
100
????????????}
101
????????????return;?//?Explicitly?remain?on?the?current?view
102
????????}
103
????????CaseStruct?caseStruct?=?getViewId(context,?fromAction,?outcome);
104
????????ExternalContext?extContext?=?context.getExternalContext();
105
????????if?(caseStruct?!=?null)?
{
106
????????????Object?obj?=?context.getExternalContext().getSessionMap().get(
107
????????????????????Constant.LOGIN_INFO_KEY);
108
????????????List?authList?=?null;
109
????????????if?(obj?!=?null)?
{
110
????????????????authList?=?((LoginInfo)?obj).getAuthorityFunctionVoList();
111
????????????}
112
????????????String?uri?=?caseStruct.navCase.getToViewId().replace(".jsp",
113
????????????????????".faces");
114
????????????boolean?flag=true;
115
????????????if?(this.IGNORED_URI.indexOf(uri)?<?0)?
{
116
????????????????if?(authList?!=?null?&&?!this.checkURL(authList,?uri))?
{
117
????????????????????//?URI?is?invalid
118
????????????????????flag=false;
119
????????????????}
120
????????????}
121
122
????????????ViewHandler?viewHandler?=?Util.getViewHandler(context);
123
????????????Util.doAssert(null?!=?viewHandler);
124
125
????????????if?(caseStruct.navCase.hasRedirect())?
{
126
????????????????//?perform?a?302?redirect.
127
????????????????String?newPath?=?viewHandler.getActionURL(context,
128
????????????????????????caseStruct.viewId);
129
130
????????????????try?
{
131
????????????????????if?(DEBUGLOG.isDebugEnabled())?
{
132
????????????????????????DEBUGLOG.debug("Redirecting?to?path?"?+?newPath
133
????????????????????????????????+?"?for?outcome?"?+?outcome?+?"and?viewId?"
134
????????????????????????????????+?caseStruct.viewId);
135
????????????????????}
136
????????????????????extContext.redirect(newPath);
137
????????????????}?catch?(java.io.IOException?ioe)?
{
138
????????????????????String?message?=?"Redirect?to?"?+?newPath?+?"?failed.";
139
????????????????????ERRORLOG.error(message);
140
????????????????????throw?new?FacesException(message,?ioe);
141
????????????????}
142
????????????????context.responseComplete();
143
????????????????if?(DEBUGLOG.isDebugEnabled())?
{
144
????????????????????DEBUGLOG
145
????????????????????????????.debug("Response?complete?for?"?
146
????????????????????????????????????+?caseStruct.viewId);
147
????????????????}
148
????????????}?else?
{
149
????????????????UIViewRoot?newRoot?=?null;
150
????????????????if?(flag)?
{
151
????????????????????newRoot?=?viewHandler
152
????????????????????????.createView(context,?caseStruct.viewId);
153
????????????????}?else?
{
154
????????????????????newRoot?=?viewHandler.createView(context,
155
????????????????????????"/backForward.jsp");
156
????????????????}
157
????????????????context.setViewRoot(newRoot);
158
????????????????if?(DEBUGLOG.isDebugEnabled())?
{
159
????????????????????DEBUGLOG.debug("Set?new?view?in?FacesContext?for?"
160
????????????????????????+?caseStruct.viewId);
161
????????????????}
162
????????????}
163
????????}
164
????}
165
166
????/**?*//**
167
?????*?This?method?uses?helper?methods?to?determine?the?new?<code>view</code>
168
?????*?identifier.?Refer?to?section?7.4.2?of?the?specification?for?more?details.
169
?????*?
170
?????*?@param?context
171
?????*????????????The?Faces?Context
172
?????*?@param?fromAction
173
?????*????????????The?action?reference?string
174
?????*?@param?outcome
175
?????*????????????The?outcome?string
176
?????*?@return?The?<code>view</code>?identifier.
177
?????*/
178
????private?CaseStruct?getViewId(FacesContext?context,?String?fromAction,
179
????????????String?outcome)?
{
180
????????//?String?nextViewId?=?null;
181
????????String?viewId?=?context.getViewRoot().getViewId();
182
????????CaseStruct?caseStruct?=?null;
183
184
????????synchronized?(this)?
{
185
????????????caseStruct?=?findExactMatch(viewId,?fromAction,?outcome);
186
187
????????????if?(caseStruct?==?null)?
{
188
????????????????caseStruct?=?findWildCardMatch(viewId,?fromAction,?outcome);
189
????????????}
190
191
????????????if?(caseStruct?==?null)?
{
192
????????????????caseStruct?=?findDefaultMatch(fromAction,?outcome);
193
????????????}
194
????????}
195
????????return?caseStruct;
196
????}
197
198
????/**?*//**
199
?????*?This?method?finds?the?List?of?cases?for?the?current?<code>view</code>
200
?????*?identifier.?After?the?cases?are?found,?the?<code>from-action</code>?and
201
?????*?<code>from-outcome</code>?values?are?evaluated?to?determine?the?new
202
?????*?<code>view</code>?identifier.?Refer?to?section?7.4.2?of?the
203
?????*?specification?for?more?details.
204
?????*?
205
?????*?@param?viewId
206
?????*????????????The?current?<code>view</code>?identifier.
207
?????*?@param?fromAction
208
?????*????????????The?action?reference?string.
209
?????*?@param?outcome
210
?????*????????????The?outcome?string.
211
?????*?@return?The?<code>view</code>?identifier.
212
?????*/
213
214
????private?synchronized?CaseStruct?findExactMatch(String?viewId,
215
????????????String?fromAction,?String?outcome)?
{
216
????????//?String?returnViewId?=?null;
217
????????//?if?the?user?has?elected?to?replace?the?Application?instance
218
????????//?entirely
219
????????if?(null?==?associate)?
{
220
????????????return?null;
221
????????}
222
????????Map?caseListMap?=?associate.getNavigationCaseListMappings();
223
????????Util.doAssert(null?!=?caseListMap);
224
????????List?caseList?=?(List)?caseListMap.get(viewId);
225
????????if?(caseList?==?null)?
{
226
????????????return?null;
227
????????}
228
????????//?We've?found?an?exact?match?for?the?viewId.?Now?we?need?to?evaluate
229
????????//?from-action/outcome?in?the?following?order:
230
????????//?1)?elements?specifying?both?from-action?and?from-outcome
231
????????//?2)?elements?specifying?only?from-outcome
232
????????//?3)?elements?specifying?only?from-action
233
????????//?4)?elements?where?both?from-action?and?from-outcome?are?null
234
????????return?determineViewFromActionOutcome(caseList,?fromAction,?outcome);
235
????}
236
237
????/**?*//**
238
?????*?This?method?traverses?the?wild?card?match?List?(containing
239
?????*?<code>from-view-id</code>?strings?and?finds?the?List?of?cases?for?each
240
?????*?<code>from-view-id</code>?string.?Refer?to?section?7.4.2?of?the
241
?????*?specification?for?more?details.
242
?????*?
243
?????*?@param?viewId
244
?????*????????????The?current?<code>view</code>?identifier.
245
?????*?@param?fromAction
246
?????*????????????The?action?reference?string.
247
?????*?@param?outcome
248
?????*????????????The?outcome?string.
249
?????*?@return?The?<code>view</code>?identifier.
250
?????*/
251
????private?synchronized?CaseStruct?findWildCardMatch(String?viewId,
252
????????????String?fromAction,?String?outcome)?
{
253
????????CaseStruct?result?=?null;
254
255
????????//?if?the?user?has?elected?to?replace?the?Application?instance
256
????????//?entirely
257
????????if?(null?==?associate)?
{
258
????????????return?null;
259
????????}
260
261
????????Map?caseListMap?=?associate.getNavigationCaseListMappings();
262
????????Util.doAssert(null?!=?caseListMap);
263
????????TreeSet?wildcardMatchList?=?associate.getNavigationWildCardList();
264
????????Util.doAssert(null?!=?wildcardMatchList);
265
266
????????Iterator?iter?=?wildcardMatchList.iterator();
267
????????String?fromViewId;
268
????????List?caseList;
269
????????String?wcFromViewId?=?null;
270
????????while?(iter.hasNext())?
{
271
????????????fromViewId?=?(String)?iter.next();
272
????????????//?See?if?the?entire?wildcard?string?(without?the?trailing?"*"?is
273
????????????//?contained?in?the?incoming?viewId.?Ex:?/foobar?is?contained?with
274
????????????//?/foobarbaz
275
????????????//?If?so,?then?we?have?found?our?largest?pattern?match..
276
????????????//?If?not,?then?continue?on?to?the?next?case;
277
278
????????????if?(viewId.indexOf(fromViewId,?0)?==?-1)?
{
279
????????????????continue;
280
????????????}
281
????????????//?Append?the?trailing?"*"?so?we?can?do?our?map?lookup;
282
????????????wcFromViewId?=?fromViewId?+?"*";
283
????????????caseList?=?(List)?caseListMap.get(wcFromViewId);
284
285
????????????if?(caseList?==?null)?
{
286
????????????????return?null;
287
????????????}
288
289
????????????//?If?we've?found?a?match,?then?we?need?to?evaluate
290
????????????//?from-action/outcome?in?the?following?order:
291
????????????//?1)?elements?specifying?both?from-action?and?from-outcome
292
????????????//?2)?elements?specifying?only?from-outcome
293
????????????//?3)?elements?specifying?only?from-action
294
????????????//?4)?elements?where?both?from-action?and?from-outcome?are?null
295
296
????????????result?=?determineViewFromActionOutcome(caseList,?fromAction,
297
????????????????????outcome);
298
????????????if?(result?!=?null)?
{
299
????????????????break;
300
????????????}
301
????????}
302
????????return?result;
303
????}
304
305
????/**?*//**
306
?????*?This?method?will?extract?the?cases?for?which?a?<code>from-view-id</code>
307
?????*?is?an?asterisk?"*".?Refer?to?section?7.4.2?of?the?specification?for?more
308
?????*?details.
309
?????*?
310
?????*?@param?fromAction
311
?????*????????????The?action?reference?string.
312
?????*?@param?outcome
313
?????*????????????The?outcome?string.
314
?????*?@return?The?<code>view</code>?identifier.
315
?????*/
316
317
????private?synchronized?CaseStruct?findDefaultMatch(String?fromAction,
318
????????????String?outcome)?
{
319
????????//?String?returnViewId?=?null;
320
????????//?if?the?user?has?elected?to?replace?the?Application?instance
321
????????//?entirely
322
????????if?(null?==?associate)?
{
323
????????????return?null;
324
????????}
325
326
????????Map?caseListMap?=?associate.getNavigationCaseListMappings();
327
????????Util.doAssert(null?!=?caseListMap);
328
329
????????List?caseList?=?(List)?caseListMap.get("*");
330
331
????????if?(caseList?==?null)?
{
332
????????????return?null;
333
????????}
334
335
????????//?We?need?to?evaluate?from-action/outcome?in?the?follow
336
????????//?order:?1)elements?specifying?both?from-action?and?from-outcome
337
????????//?2)?elements?specifying?only?from-outcome
338
????????//?3)?elements?specifying?only?from-action
339
????????//?4)?elements?where?both?from-action?and?from-outcome?are?null
340
341
????????return?determineViewFromActionOutcome(caseList,?fromAction,?outcome);
342
????}
343
344
????/**?*//**
345
?????*?This?method?will?attempt?to?find?the?<code>view</code>?identifier?based
346
?????*?on?action?reference?and?outcome.?Refer?to?section?7.4.2?of?the
347
?????*?specification?for?more?details.
348
?????*?
349
?????*?@param?caseList
350
?????*????????????The?list?of?navigation?cases.
351
?????*?@param?fromAction
352
?????*????????????The?action?reference?string.
353
?????*?@param?outcome
354
?????*????????????The?outcome?string.
355
?????*?@return?The?<code>view</code>?identifier.
356
?????*/
357
????private?synchronized?CaseStruct?determineViewFromActionOutcome(
358
????????????List?caseList,?String?fromAction,?String?outcome)?
{
359
360
????????String?cncFromAction?=?null;
361
????????String?fromOutcome?=?null;
362
????????String?toViewId?=?null;
363
????????CaseStruct?result?=?new?CaseStruct();
364
????????int?size=caseList.size();
365
????????ConfigNavigationCase?cnc?=?null;
366
????????for?(int?i?=?0;?i?<?size;?i++)?
{
367
????????????cnc?=?(ConfigNavigationCase)?caseList.get(i);
368
????????????cncFromAction?=?cnc.getFromAction();
369
????????????fromOutcome?=?cnc.getFromOutcome();
370
????????????toViewId?=?cnc.getToViewId();
371
????????????if?((cncFromAction?!=?null)?&&?(fromOutcome?!=?null))?
{
372
????????????????if?((cncFromAction.equals(fromAction))
373
????????????????????????&&?(fromOutcome.equals(outcome)))?
{
374
????????????????????result.viewId?=?toViewId;
375
????????????????????result.navCase?=?cnc;
376
????????????????????return?result;
377
????????????????}
378
????????????}
379
????????}
380
????????for?(int?i?=?0;?i?<?size;?i++)?
{
381
????????????cnc?=?(ConfigNavigationCase)?caseList.get(i);
382
????????????cncFromAction?=?cnc.getFromAction();
383
????????????fromOutcome?=?cnc.getFromOutcome();
384
????????????toViewId?=?cnc.getToViewId();
385
????????????if?((cncFromAction?==?null)?&&?(fromOutcome?!=?null))?
{
386
????????????????if?(fromOutcome.equals(outcome))?
{
387
????????????????????result.viewId?=?toViewId;
388
????????????????????result.navCase?=?cnc;
389
????????????????????return?result;
390
????????????????}
391
????????????}
392
????????}
393
394
????????for?(int?i?=?0;?i?<?size;?i++)?
{
395
????????????cnc?=?(ConfigNavigationCase)?caseList.get(i);
396
????????????cncFromAction?=?cnc.getFromAction();
397
????????????fromOutcome?=?cnc.getFromOutcome();
398
????????????toViewId?=?cnc.getToViewId();
399
????????????if?((cncFromAction?!=?null)?&&?(fromOutcome?==?null))?
{
400
????????????????if?(cncFromAction.equals(fromAction))?
{
401
????????????????????result.viewId?=?toViewId;
402
????????????????????result.navCase?=?cnc;
403
????????????????????return?result;
404
????????????????}
405
????????????}
406
????????}
407
408
????????for?(int?i?=?0;?i?<?size;?i++)?
{
409
????????????cnc?=?(ConfigNavigationCase)?caseList.get(i);
410
????????????cncFromAction?=?cnc.getFromAction();
411
????????????fromOutcome?=?cnc.getFromOutcome();
412
????????????toViewId?=?cnc.getToViewId();
413
????????????if?((cncFromAction?==?null)?&&?(fromOutcome?==?null))?
{
414
????????????????result.viewId?=?toViewId;
415
????????????????result.navCase?=?cnc;
416
????????????????return?result;
417
????????????}
418
????????}
419
420
????????return?null;
421
????}
422
423
????/**?*//**
424
?????*?@author?robin
425
?????*/
426
????class?CaseStruct?
{
427
428
????????/**?*//**
429
?????????*?Field?viewId.
430
?????????*/
431
????????protected?String?viewId;
432
433
????????/**?*//**
434
?????????*?Field?navCase.
435
?????????*/
436
????????protected?ConfigNavigationCase?navCase;
437
????}
438
439
}
440



??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



332

333

334

335

336

337

338

339

340

341

342

343

344


345

346

347

348

349

350

351

352

353

354

355

356

357

358



359

360

361

362

363

364

365

366



367

368

369

370

371



372

373



374

375

376

377

378

379

380



381

382

383

384

385



386



387

388

389

390

391

392

393

394



395

396

397

398

399



400



401

402

403

404

405

406

407

408



409

410

411

412

413



414

415

416

417

418

419

420

421

422

423


424

425

426



427

428


429

430

431

432

433


434

435

436

437

438

439

440

來看看其中的關(guān)鍵部分,149行起:















當(dāng)然別忘了在faces-config.xml中加入自定義Application Navigation的配置,如下:
?1
<faces-config>
?2
????<application>
?3
????????<navigation-handler?id="navigationWithAuth">
?4
????????????com.***.framework.NavigationHandleWithAuthImpl
?5
????????</navigation-handler>
?6
????</application>
?7
?8
?9


10
11
</faces-config>

?2

?3

?4

?5

?6

?7

?8

?9



10

11

注意:
在NavigationHandler中,當(dāng)發(fā)現(xiàn)檢查URL權(quán)限未能通過時(shí),千萬不要直接去修改當(dāng)前的那個(gè)CaseStruts,因?yàn)镴SF自己會(huì)緩存整個(gè)跳轉(zhuǎn)的配置,以提高執(zhí)行效率,請(qǐng)使用viewHandler.createView()來創(chuàng)建一個(gè)新CaseStruts,否則會(huì)發(fā)生跳轉(zhuǎn)不正常的情況。