This repository has been archived by the owner on Mar 20, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathwhats-new-in-jsf23.html
2564 lines (1929 loc) · 122 KB
/
whats-new-in-jsf23.html
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
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
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html xml:lang="en" lang="en">
<head>
<meta charset="UTF-8" />
<title>Mojarra JavaServer Faces</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="" />
<meta http-equiv="content-language" content="en" />
<link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.2/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.2/css/bootstrap-responsive.min.css" rel="stylesheet" />
<link href="css/docs.css" rel="stylesheet" />
<link href="css/site.css" rel="stylesheet" />
<style> a { color: #555555; } </style>
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<!-- Syntax highlighting for source code -->
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' type='text/javascript'></script>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'></script>
<script language='javascript'>
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.config.clipboardSwf = 'http://alexgorbatchev.com/pub/sh/current/scripts/clipboard.swf';
SyntaxHighlighter.all();
</script>
</head>
<body class="page-index project-gfmvnsite" data-spy="scroll" data-offset="60" data-target="#toc-scroll-target">
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<div class="brand">
<a href="https://javaee.github.io/javaserverfaces-spec">
<img src="images/jsf-logo-no-text-32.png"><span style="color:#E88A43;font-size:18px;padding-left:11px;;padding-top:15px;font-weight:bold;">Mojarra JavaServer Faces</span> - <span style="font-size:18px;">Oracle's open source implementation of the JSF standard</span>
</a>
</div>
<div class="nav-collapse">
<ul class="nav pull-right">
<li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown">Related Projects<b class="caret"></b></a><ul class="dropdown-menu"><li><a href="https://github.com/javaee/glassfish" title="GlassFish">GlassFish</a></li><li><a href="https://jersey.github.io" title="Jersey">Jersey</a></li><li><a href="https://github.com/tyrus-project/tyrus" title="Tyrus">Tyrus</a></li><li><a href="https://javaee.github.io/grizzly" title="Grizzly">Grizzly</a></li><li><a href="https://javaee.github.io/openmq" title="Open MQ">Open MQ</a></li></ul></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</div>
</div>
<div class="container">
<div class="main-body">
<br>
<h3 class='post-title entry-title'>
What's new in JSF 2.3?
</h3>
<div class='post-header'>
<div class='post-header-line-1'></div>
</div>
<div>
<p>
The process of developing JSF 2.3 started late september 2014, which is approximately 1.5 half year after JSF 2.2 was finalized.
JSF 2.3 went final in the beginning of 2017.
<p>
The following text describes the new features of JSF 2.3. Compiled by JSF 2.3 EG member Arjan Tijms.
<a name="new"></a>
<h3> JSF 2.3 new features </h3>
<ul>
<li> <a href="#cdi">CDI alignment</a>
<ul>
<li><a href="#1316">Injection and EL resolving of JSF artifacts</a> </li>
<li><a href="#1316b">Injection in more JSF artifacts</a> </li>
<li><a href="#1417">Native managed beans annotations deprecated</a> </li>
<li><a href="#1418">CDI compatible @ManagedProperty</a> </li>
</ul>
</li>
<li> <a href="#lifecycle">Lifecycle</a>
<ul>
<li><a href="#1135">System event published after view rendered</a></li>
</ul>
</li>
<li> <a href="#networking">Networking / AJAX</a>
<ul>
<li><a href="#1396">WebSocket integration</a></li>
<li><a href="#613">Ajax method invocation</a></li>
<li><a href="#1412">Execute javascript from server at completion of AJAX response</a></li>
<li><a href="#790">Updating multiple forms via AJAX</a></li>
</ul>
</li>
<li> <a href="#conversion-validation">Conversion / Validation</a>
<ul>
<li><a href="#1">Class level bean validation</a></li>
<li><a href="#1370">JDK 8 time support in f:convertDateTime</a></li>
</ul>
</li>
<li> <a href="#java">Java API</a>
<ul>
<li><a href="#1103">Support for the Iterable interface in UIData and UIRepeat</a></li>
</ul>
<ul>
<li><a href="#1364">Support for the Map interface in UIData and UIRepeat</a></li>
</ul>
<ul>
<li><a href="#1078">Support for custom types in UIData and UIRepeat</a></li>
</ul>
<ul>
<li><a href="#1429">Default getWrapped method for FacesWrapper implementations</a></li>
</ul>
</li>
<li> <a href="#components">Components</a>
<ul>
<li><a href="#1238">Component Search Expression framework</a></li>
</ul>
<ul>
<li><a href="#329">Freely placeable radio button component</a></li>
</ul>
<ul>
<li><a href="#217">styleClass attribute on h:column</a></li>
</ul>
<ul>
<li><a href="#217_2">rowClass attribute on h:dataTable</a></li>
</ul>
<ul>
<li><a href="#1102">Iteration in UIRepeat without backing model</a></li>
</ul>
<ul>
<li><a href="#1422">Automatic conversion in UISelectMany for Collection</a></li>
</ul>
<ul>
<li><a href="#1424">Importing constants into EL namespace</a></li>
</ul>
<ul>
<li><a href="#1007">Official spec recognition for dynamic component tree manipulation</a></li>
</ul>
</li>
<li> <a href="#resources">Views and Resources</a>
<ul>
<li><a href="#1260">Basic support for exact mapping (extensionless URLs)</a></li>
</ul>
<ul>
<li><a href="#1435">Obtaining list of all view resources</a></li>
</ul>
<ul>
<li><a href="#1404">Standardised resource rendered tracking</a></li>
</ul>
<ul>
<li><a href="#1423">Resource loading for components dynamically added via ajax</a></li>
</ul>
</li>
<li> <a href="#type-safety">Type-safety</a>
<ul>
<li><a href="#1382">Generics for ExternalContext#getInitParamterMap</a></li>
</ul>
<ul>
<li><a href="#1355">Generics for Converter and Validator interfaces</a></li>
</ul>
<ul>
<li><a href="#1428">Constants for "jsf.js", "javax.faces" and postback parameters</a></li>
</ul>
<li> <a href="#configuration">Configuration</a>
<ul>
<li><a href="#936">Facelets default to non-hot reload in production</a></li>
</ul>
<ul>
<li><a href="#1434">.xhtml added to default mappings</a></li>
</ul>
</li>
</ul>
<a name="cdi"></a>
<h3> CDI </h3>
<p>
<a name="1316"></a>
<strong>Injection and EL resolving of JSF artifacts</strong> (<a href="https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1316">spec issue 1316</a>) <small>(partially)</small>
<p>
JSF has traditionally used static entry methods and chaining to let the user obtain the various artifacts that it provides, such as the FacesContext, session map, external context, etc. The following gives a few examples of this:
<pre class="brush: java;">
FacesContext facesContext = FacesContext.getCurrentInstance()
ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
Map<String, Object> cookieMap = FacesContext.getCurrentInstance().getExternalContext().getRequestCookieMap();
Map<String, Object> viewMap = FacesContext.getCurrentInstance().getViewRoot().getViewMap();
// etc
</pre>
<p>
Especially the artefacts that have to be obtained by deep chaining can be problematic. Not only makes this the code verbose and hard to read, it can also be unclear to users that the view map has to be obtained via the view root but the cookie map via the external context as shown above.
<p>
Furthermore, the pattern makes it hard to override what is returned by the runtime. In JSF it IS possible to influence this by providing/setting a custom FacesContext, but especially for the deeper chained artefacts multiple levels or wrapping are then required, which is not always trivial to implement. The problem there is clearly that the abstraction is at the wrong level; providing an alternative view map requires a custom faces context, which provides a wrapped view root, which then finally provides the view map we wanted to provide.
<p>
A more modern approach in Java EE is to inject artefacts in order to obtain them (essentially flattening the lookup) and to provide alternative producers for those when the need to override them arises.
<p>
JSF 2.3 will therefore provide default producers for the most important artefacts, which at the moment being:
<table border="1" style="font-size: 100%;">
<tr style="background-color:LightGray;">
<th>Artefact</th> <th>EL name</th> <th>Qualifier</th> <th>Type</th>
</tr>
<tr>
<td>Application</td> <td>#{application}</td> <td>-</td> <td><small>java.lang.Object (javax.servlet.ServletContext)</small></td>
</tr>
<tr>
<td>ApplicationMap</td> <td>#{applicationScope}</td> <td>@ApplicationMap</td> <td><small>java.util.Map<String, Object></small></td>
</tr>
<tr>
<td>CompositeComponent</td> <td>#{cc}</td> <td><small><i>(Not injectable)</i></small></td> <td><small>javax.faces.component.UIComponent</small></td>
</tr>
<tr>
<td>Component</td> <td>#{component}</td> <td><small><i>(Not injectable)</i></small></td> <td><small>javax.faces.component.UIComponent</small></td>
</tr>
<tr>
<td>RequestCookieMap</td> <td>#{cookie}</td> <td>@RequestCookieMap</td> <td><small>java.util.Map<String, Object></small></td>
</tr>
<tr>
<td>FacesContext</td> <td>#{facesContext}</td> <td>-</td> <td><small>javax.faces.context.FacesContext</small></td>
</tr>
<tr>
<td>Flash</td> <td>#{flash}</td> <td>-</td> <td><small>javax.faces.context.Flash</small></td>
</tr>
<tr>
<td>FlowMap</td> <td>#{flowScope}</td> <td>@FlowMap</td> <td><small>java.util.Map<Object, Object></small></td>
</tr>
<tr>
<td>HeaderMap</td> <td>#{header}</td> <td>@HeaderMap</td> <td><small>java.util.Map<String, String></small></td>
</tr>
<tr>
<td>HeaderValuesMap</td> <td>#{headerValues}</td> <td>@HeaderValuesMap</td> <td><small>java.util.Map<String, String[]></small></td>
</tr>
<tr>
<td>InitParameterMap</td> <td>#{initParam}</td> <td>@InitParameterMap</td> <td><small>java.util.Map<String, String></small></td>
</tr>
<tr>
<td>RequestParameterMap</td> <td>#{param}</td> <td>@RequestParameterMap</td> <td><small>java.util.Map<String, String></small></td>
</tr>
<tr>
<td>RequestParameterValuesMap</td> <td>#{paramValues}</td> <td>@RequestParameterValuesMap</td> <td><small>java.util.Map<String, String[]></small></td>
</tr>
<tr>
<td>Request</td> <td>#{request}</td> <td><small><i>(Not injectable)</i></small></td> <td><small>java.lang.Object (javax.servlet.http.HttpServletRequest)</small></td>
</tr>
<tr>
<td>RequestMap</td> <td>#{requestScope}</td> <td>@RequestMap</td> <td><small>java.util.Map<String, Object></small></td>
</tr>
<tr>
<td>ResourceHandler</td> <td>#{"resource"}</td> <td>-</td> <td><small>javax.faces.application.ResourceHandler</small></td>
</tr>
<tr>
<td>Session</td> <td>#{session}</td> <td><small><i>(Not injectable)</i></small></td> <td><small>java.lang.Object (javax.servlet.http.HttpSession)</small></td>
</tr>
<tr>
<td>SessionMap</td> <td>#{sessionScope}</td> <td>@SessionMap</td> <td><small>java.util.Map<String, Object></small></td>
</tr>
<tr>
<td>View</td> <td>#{view}</td> <td>-</td> <td><small>javax.faces.component.UIViewRoot</small></td>
</tr>
<tr>
<td>ViewMap</td> <td>#{viewScope}</td> <td>@ViewMap</td> <td><small>java.util.Map<String, Object></small></td>
</tr>
<tr>
<td>ExternalContext </td> <td>#{externalContext} (new)</td> <td>-</td> <td><small>javax.faces.context.ExternalContext</small></td>
</tr>
</table>
<p>
The general types, in this case the maps, need an extra qualifier to avoid clashing with other producers. The JSF specific types however don't need such qualifier since JSF is the sole owner of these types.
<p>
Obtaining the JSF artefacts is therefore as easy as can be; one only needs to know the type of the artefact one wants. For example:
<pre class="brush: java;">
@Inject
private ExternalContext context;
</pre>
<p>
For the ones that do need a qualifier, this qualifier has to be looked-up of course, but that's essentially a flat lookup. For example:
<pre class="brush: xml;">
@Inject
@ApplicationMap
private Map<String, Object> applicationMap;
</pre>
Furthermore, somewhat as a side-effect of <a href="#1316b">Injection in more JSF artifacts</a>, user created instances of the following artefacts are also injectable:
<ul>
<li> Converter
<li> Validator
<li> Behavior
</ul>
This list is somewhat different, as we're not talking about say -the- <em>Converter</em> instance within the current scope, but about a specific named custom converter in the user's application. E.g.
<pre class="brush: java;">
@Inject
@FacesConverter(value = "myConverter", managed = true)
private Converter myConverter;
</pre>
Note that this particular injection pattern is possible, but not entirely how things are normally done in CDI.
<p>
As far as the implementation side is concerned, there's a CDI Bean<T> instance (aka "default bean") provided for every artefact. Since the term "bean" already has a meaning in JSF and CDI is not profoundly clear about this term either, the RI implementation code calls them "dynamic producer", or just "producer". Maybe "factory" would be better, but that term has a bit of a history itself and we wanted to avoid using that one.
<p>
The following shows an example of a Bean<T>/dynamic producer for the HeaderValues artefact:
<pre class="brush: java;">
public class HeaderValuesMapProducer extends CdiProducer<Map<String, String[]>> {
public HeaderValuesMapProducer() {
super.name("headerValues")
.scope(RequestScoped.class)
.qualifiers(new HeaderValuesMapAnnotationLiteral())
.types(
new ParameterizedTypeImpl(Map.class, new Type[]{String.class, String[].class}),
Map.class,
Object.class)
.beanClass(Map.class)
.create(e -> FacesContext.getCurrentInstance().getExternalContext().getRequestHeaderValuesMap());
}
}
</pre>
<p>
<br />
<p>
<a name="1316b"></a>
<strong>Injection in more JSF artifacts</strong> (<a href="https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1316">spec issue 1316</a>) <small>(partially)</small>
<p>
In JSF 2.1 very few JSF artifacts were injection targets. In JSF 2.2 injection was made possible in a <a href="http://arjan-tijms.omnifaces.org/p/jsf-22.html#763" title="Injection in most JSF artifacts" target="_blank">huge amount of additional artefacts</a> but the very ones where injection actually matters most, converters and validators, were mysteriously left in the cold.
<p>
In JSF 2.3 this has now finally been taken care of as the following artefacts have been added to the list of injection targets:
<ul>
<li> javax.faces.convert.Converter
<li> javax.faces.validator.Validator
<li> javax.faces.component.behavior.Behavior
</ul>
<p>
However, in contrast to the artefacts already on this list these new 3 are not automatically injection targets. They will only become so when a new attribute called "managed" on the corresponding annotations <em>@FacesConverter</em>, <em>@FacesValidator</em> and <em>@Behavior</em> is set to true. Furthermore all these 3 annotations have been upgraded to being CDI qualifiers by adding the @Qualified annotation to their definition.
<p>
The existing attributes of <em>@FacesConverter</em>, <em>@FacesValidator</em> and <em>@Behavior</em> have not been modified, meaning they are all *binding*, as is the new attribute "managed".
<p>
What happens behind the scenes now is that when JSF needs a converter it simply asks the CDI bean manager for a bean that implements <em>Converter</em> with a qualifier <em>@FacesValidator</em> that has the "managed" attribute set to true and the <em>value</em> (coverterId) or <em>forClass</em> attribute set to the right value (which is why it's important that these attributes are all binding).
<p>
It then wraps the bean returned by CDI in a delegating converter instance. This wrapper then delegates to the bean returned by CDI. This wrapper can be state-saved, but since the CDI bean is stored in a transient field it won't save&restore that. Instead, it will only save&restore the <em>converterId</em> or <em>forClass</em>. The restored wrapper will then use the JSF Application instance to ask for a converter with said <em>converterId</em> or <em>forClass</em> (which will go to CDI again, and will do the wrapping again, so we have a double wrapped converter at this point).
<p>
In effect the mechanism is essentially quite like the age old workaround of using <a href="http://balusc.blogspot.com/2011/09/communication-in-jsf-20.html#ConvertingAndValidatingGETRequestParameters" title="Converting and validating GET request parameters" target="_blank">an EL expression pointing to a managed bean</a> for a converter or validator.
<p>
An example of a JSF 2.3 converter in which injection can take place:
<pre class="brush: java;">
@FacesConverter(value = "myConverter", managed = true)
public class MyConverter implements Converter {
@Inject
private MyService service;
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value) {
// Convert string to Object here
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value) {
// Convert Object to String here
}
}
</pre>
<p>
Note that this new style converter must have a constructor as defined by CDI (a no-args one here) and the <a href="http://stackoverflow.com/questions/19304827/facesconverter-inject-workaround-constructor-alternative" title="FacesConverter Inject workaround - constructor alternative" target="_blank">alternative constructor</a> is not supported here.
<p>
<p>
<br />
<p>
<a name="1417"></a>
<strong>Native managed beans annotations deprecated</strong> (<a href="https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1417">spec issue 1417 </a>)
<p>
With JSF 2.0 <a href="https://andyschwartz.wordpress.com/2009/07/31/whats-new-in-jsf-2/#configuration-managed-bean-annotations">annotations were introduced</a> for the JSF managed bean facility. These annotations were however <a href="https://community.oracle.com/blogs/cayhorstmann/2009/12/23/javaxfacesbeanmanagedbean-dead-arrival">controversial from the start</a>. At approximately the same time as they were being designed, there was a parallel effort started to provide a universal managed bean specification.
<p>
Because of that, the package that the JSF managed beans annotations lived in contained the following disclaimer:
<blockquote>
<i>At the time of this writing, a forthcoming JCP effort is being
planned to extract the specification for managed beans from JSF and
place it into its own specification. To account for this effort and to
avoid introducing classes into JSF 2.0 that would have to be deprecated
when this effort is complete, implementations of JSF 2.0 are not
required to implement the “Faces Managed Bean Annotation
Specification for Containers Conforming to Servlet 2.5”. However,
JSF implementations are strongly encouraged to implement this
specification, as it provides significant improvements in ease of
use.</i>
</blockquote>
<p>
Of course we all know the name of this effort now; CDI.
<p>
Although effectively deprecated from day one, the now called "native" managed beans annotations from JSF had one advantage over their CDI versions and that's that they could use the important view scope (which incidentally was <a href="https://andyschwartz.wordpress.com/2009/07/31/whats-new-in-jsf-2/#scopes-view">also introduced in JSF 2.0</a>). It would take <a href="http://arjan-tijms.omnifaces.org/p/jsf-22.html#1087">until JSF 2.2</a> for an official CDI version of that scope.
<p>
With the CDI based view scope introduced in JSF 2.2, JSF's own native bean facility could have been deprecated, but for some reason it wasn't. Now in JSF 2.3 the package containing the annotations for this facility has finally been deprecated.
<p>
The importance of this is that developers will hopefully be less confused which annotation to use (most IDEs will warn about using a deprecated type), and that JSF can take the next step; propose the entire managed bean facility for pruning. Just as EJB entity beans had no use in EJB anymore with JPA available and thus were actually removed ("pruned"), there's simply no need for JSF anymore to be in the managed bean business. JSF is already a very large spec, so removing(*) a large and now unnecessary part of it may help bringing down its size to somewhat more manageable proportions.
<p>
<small><i>(* technically the pruned part of the spec will remain in existence and vendors are free to optionally implement it. The RI will always keep implementing it. So pruned does not mean "totally gone".)</i></small>
<p>
<p>
<br />
<p>
<a name="1418"></a>
<strong>CDI compatible @ManagedProperty</strong> (<a href="https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1417">spec issue 1418 </a>)
<p>
<p>
With JSF 2.3 <a href="#1417">deprecating</a> the native managed beans annotations in favour of CDI, there was one useful feature left that didn't had a full CDI compatible replacement; <a href="http://docs.oracle.com/javaee/7/api/javax/faces/bean/ManagedProperty.html">@ManagedProperty</a>.
<p>
JSF co-spec lead Manfred Riem provided a simple example for a <a href="http://manorrock.com/blog/2013/11/01/jsf_tip_31_migrate_your_managedproperty_annotations.html">String based CDI compatible version</a>, of which JSF 2.3 will incorporate a variant that supports basically all data types. Just like the native version type checking is delayed till runtime.
<p>
Because of the delayed type checking it not rarely makes more sense to use regular CDI injection (with optionally qualifiers if needed), but for migrating existing code or for those situations where an EL expression really is more convenient the new <i>@ManagedProperty</i> from the <i>javax.faces.annotation</i> package can be used in CDI beans.
<p>
The following shows an example:
<pre class="brush: java;">
import javax.enterprise.context.RequestScoped;
import javax.faces.annotation.ManagedProperty;
import javax.inject.Inject;
import javax.inject.Named;
@Named
@RequestScoped
public class MyBean {
@Inject @ManagedProperty("#{someBean.someProperty}")
private Integer injectedInteger1;
}
</pre>
<p>
<p>
<br />
<p>
<a name="lifecycle"></a>
<h3> Lifecycle </h3>
<p>
<a name="1135"></a>
<strong>System event published after view rendered</strong> (<a href="http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1135">spec issue 1135</a>)
<p>
JSF 2 introduced the concept of <a href="http://javaserverfaces.java.net/nonav/docs/2.1/javadocs/javax/faces/event/SystemEvent.html" title="SystemEvent (JavaServer Faces API (2.1))">system events</a>, which are events that can be fired by arbitrary objects at arbitrary points during the request processing lifecycle.
<p>
In JSF 2.2 there are some 20 events defined, e.g. <em>PostAddToViewEvent</em>, <em>PostConstructViewMapEvent</em>, <em>PreValidateEvent</em>, and specifically <em>PreRenderViewEvent</em>.
<p>
However, while there's a <em>PreRenderViewEvent</em> that's published right before a view is rendered, there's no event published right after. Such event can be useful for a variety of things, such as per view clean-ups, post rendering view processing, state handling, etc.
<p>
For these reasons and simply to be more consistent JSF 2.3 will add a new event called the <em>PostRenderViewEvent</em>, which as its name implies is published immediately after a view is rendered.
<pre class="brush: xml;">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:body>
<f:event type="postRenderView" listener="#{myBean.doPostProcessing}" />
<!-- Rest of view here -->
</h:body>
</html>
</pre>
<p>
<br />
<p>
<a name="networking"></a>
<h3> Networking / AJAX</h3>
<p>
<a name="1396"></a>
<strong>WebSocket integration</strong> (<a href="http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1396">spec issue 1396</a>)
<p>
WebSocket support for JSF has been talked about <a href="http://slideshare.net/mwessendorf/jsf-meets-websockets">for quite some time</a>, and there are <a href="http://blog.primefaces.org/?p=3066">fairly advanced implementations</a> available by now.
<p>
Still, just as with the <a href="https://andyschwartz.wordpress.com/2009/07/31/whats-new-in-jsf-2/#ajax">AJAX support</a> that was added in JSF 2.0 and was available in proprietary component libraries before that, WebSocket support was seen as fundamental enough to be put directly into the core spec.
<p>
Therefor JSF 2.3 will provide direct support for WebSockets via the new tag <i><b><f:websocket></b></i>.
<p>
An important detail of the JSF 2.3 implementation of WebSocket support is that it uses the <a href="https://javaee7.zeef.com/arjan.tijms#block_230_java-api-for-websocket-1-0">WebSocket JSR</a> and therefor integrates with the WebSocket support offered by the server on which JSF is running. Proprietary implementations are not rarely based on frameworks such as <a href="https://github.com/Atmosphere">Atmosphere</a>. Both approaches have their own cons and pros, and just as with AJAX support the user can typically choose what to use; the version offered by core JSF, or the one by a component library.
<p>
The tag supports a number of attributes, of which the primary required attribute is "<b>channel</b>". The value set here can be used to send notifications to, which will then be pushed to all instances of the socket with that channel name. The second required attribute is "<b>onmessage</b>". Here a client-side Javascript event handler can be set that is called whenever a push arrives from the server.
<p>
The following shows a minimal example of using the tag on a JSF view:
<pre class="brush: xml;">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
>
<h:head>
Websocket Example
</h:head>
<h:body>
<f:websocket channel="myChannel" onmessage="function(message){alert(message)}" />
</h:body>
</html>
</pre>
<p>
Receiving messages is one part of the process. The other part is of course to push out a message. This can be done via the new <i><b>javax.faces.push.PushContext</b></i>, which can be injected anywhere where CDI is available. The following shows an example:
<pre class="brush: java;">
@Named
@RequestScoped
public class SomeBean {
@Inject @Push
private PushContext myChannel;
public void send(){
myChannel.send("Hello, from the server by push!");
}
}
</pre>
<p>
The injected <i>PushContext</i> is associated with one specific named channel, which by default has the same name as the instance variable in which injection takes place ("myChannel" in the example above).
<p>
Integration between JSF and WebSocket revealed one spec related problem; the WebSocket spec now assumes that the application has statically defined a so-called <i>EndPoint</i> via java code. In the case of <i><f:websocket></i> such required <i>EndPoint</i> has to be created in a more dynamic way, during runtime, or at the very least allow a (CDI) extension to define one. Unfortunately <a href="https://java.net/jira/browse/WEBSOCKET_SPEC-240">neither is possible now</a>, at least not officially (some implementations support it anyway).
<p>
For those implementations that do not support adding an <i>EndPoint</i> dynamically (at the moment only GlassFish/Tyrus), a fake one has to be defined by the application. This kind of end point server no other function than to activate the container's WebSocket implementation. At the moment this is only known to be needed for GlassFish. On Tomcat and JBoss (WildFly/Undertow) this is not needed.
<p>
The following is an example of this:
<pre class="brush: java;">
public class FakeEndpoint extends Endpoint {
@Override
public void onOpen(Session session, EndpointConfig config) {}
}
</pre>
<p>
We will try to resolve this issue with the WebSocket EG, but due to the Java EE 8 hiatus it's unfortunately profoundly difficult to start a MR or revision for any spec that hasn't started one. As an alternative we may look into defining an SPI that each container that incorporates Mojarra has to implement, and in which WebSocket activation can be done in a proprietary way.
<p>
Due to unfinished work with the CDI integration, the following parameter now has to be set (to avoid clashes with a deprecated but still used switch that looks at the 2.3 version of a faces-config.xml file, if any).
<pre class="brush: xml;">
<context-param>
<param-name>javax.faces.ENABLE_CDI_RESOLVER_CHAIN</param-name>
<param-value>true</param-value>
</context-param>
</pre>
While the fake end point is used to initialise the container, the actual WebSocket end point needs to be started as well. This can't be done by default, since otherwise there will be an open socket even when WebSocket is never used. Fully dynamically creating the end point whenever an <i><f:websocket></i> is encountered is unfortunately even harder. Therefor another setting needs to be used:
<pre class="brush: xml;">
<context-param>
 <param-name>javax.faces.ENABLE_WEBSOCKET_ENDPOINT</param-name>
 <param-value>true</param-value>
</context-param>
</pre>
<p>
Further reading:
<ul>
<li> <a href="http://omnifaces-fans.org/2016/03/jsf-23-websocket-quickstart.html">JSF 2.3 - The WebSocket Quickstart under Payara</a> </li>
</ul>
<p>
<br />
<p>
<a name="613"></a>
<strong>Ajax method invocation</strong> (<a href="http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-613">spec issue 613</a>)
<p>
One of many major new features in JSF 2.0 was <a href="https://andyschwartz.wordpress.com/2009/07/31/whats-new-in-jsf-2/#ajax">core support for Ajax</a>. This effectively standardised what legendary libraries such as A4J had been doing in the years prior to that version.
<p>
One particular feature that almost every Ajax library supported wasn't standardised though. That feature is the ability to call an arbitrary server side method in a bean via Ajax. JSF 2.3 will address this omission by introducing the new <b><h:commandScript></b> component. Though many JSF libraries have <a href="http://primefaces.org/showcase/ui/ajax/remoteCommand.xhtml">something similar to this</a>, <h:commandScript> was most directly based on the <a href="http://showcase.omnifaces.org/components/commandScript"><o:commandScript></a> component from OmniFaces.
<p>
Simply said, the component creates a javascript function with a given name that once invoked will invoke on its turns the also given server side method via Ajax. The following shows an example:
<p>
<pre class="brush: xml;">
<h:form>
<h:commandScript name="myJsClientFunction" action="#{myBean.myJavaServerMethod('bar')}" render=":output" />
</h:form>
<h:outputText id="output" value="#{myBean.output}" />
</pre>
<p>
In the example above the client side javascript <i>myJsClientFunction</i> will effectively be connected to the server side Java <i>myJavaServerMethod</i> method.
<p>
<p>
<br/>
<p>
<a name="1412"></a>
<strong>Execute javascript from server at completion of AJAX response</strong> (<a href="http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1412">spec issue 1412</a>)
<p>
It's often quite convenient to be able to execute a piece of javascript coming from the server right after an AJAX response has been applied on the client. Various popular component libraries such as PrimeFaces and OmniFaces have their own utilities to let the developer <a href="http://primefaces.org/docs/api/6.0/org/primefaces/context/RequestContext.html#execute-java.lang.String-">do</a> exactly <a href="http://omnifaces.org/docs/javadoc/2.4/org/omnifaces/util/Ajax.html#oncomplete-java.lang.String...-">this</a>.
<p>
Since AJAX was introduced in JSF there technically has been some level of core support for this. Namely, the <i><partial-response></i> payload that JSF sends after an AJAX request has an <i><eval></i> section where javascript can be put for execution on the client. The response writer used for writing the partial response even had <a href="http://docs.oracle.com/javaee/7/api/javax/faces/context/PartialResponseWriter.html#startEval--">startEval</a> and <a href="http://docs.oracle.com/javaee/7/api/javax/faces/context/PartialResponseWriter.html#endEval--">endEval</a> methods for these, but mysteriously for about 7 years(!) those methods remained totally unused and were probably largely forgotten.
<p>
In JSF 2.3 those methods were rediscovered, and a new method was added to the <a href="http://docs.oracle.com/javaee/7/api/javax/faces/context/PartialViewContext.html">PartialViewContect</a>; <i><b>List<String> getEvalScripts()</b></i>.
<p>
Using this new <i>getEvalScripts()</i> method, a JSF backing bean handling an AJAX request can easily add a piece of javascript to the AJAX response. The following shows an example:
<p>
Within a form on some view:
<pre class="brush: xml;">
<h:commandButton value="submit" action="#{someBean.eval}">
<f:ajax />
</h:commandButton>
</pre>
Backing bean:
<pre class="brush: java;">
@Named
@RequestScoped
public class SomeBean {
@Inject
private FacesContext context;
public void eval() {
context.getPartialViewContext()
.getEvalScripts()
.add("alert('After response')");
}
}
</pre>
<p>
After pushing the button shown above, an alert with the text "After response" in it will be shown. Note that while in the example above the piece of javascript is the only thing in the payload of the response, one would normally combine this with updating data and rerendering one or more parts of the view.
<p>
<p>
<br/>
<p>
<a name="790"></a>
<strong>Updating multiple forms via AJAX</strong> (<a href="http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-790">spec issue 790</a>)
<p>
Via the AJAX support that was introduced in JSF 2.0 it was made possible to selectively update one or more components and the children of those components. Since the beginning of JSF it has been possible for a view to use multiple (non-nested) forms, and this is in fact a quite common thing in JSF applications.
<p>
Curiously though, these 2 very common features didn't work at all together as was discovered soon after AJAX support was added to JSF in 2009. What happens is that in JSF each form needs a hidden input field for the view state. This field is normally added in a somewhat non-trivial way, which is e.g. the reason a caching component <a href="https://github.com/omnifaces/omnifaces/blob/2.4/src/main/java/org/omnifaces/component/output/Cache.java#L127">can't directly cache a form</a>. Now the AJAX partial-response from JSF 2.0 didn't take this fact into account at all, and would just contain the markup of the updated form without the view state field (which incidentally is exactly what you would get when using a caching or buffering component on a form).
<p>
The partial-response did contain the updated view state value, but strangely enough the spec said that this should only be used to update the view state field of the submitting form. This may have been a mistake or an oversight at the time.
<p>
The result is that after an AJAX update that involves the update of multiple forms (directly or via their parent components), the view is left in a broke state. JSF forms without the view state field present simply don't work. Mojarra provided a limited implementation specific fix where you had to explicitly specify all forms to be updated (even if you were updating a single parent of all those forms), and some libraries like OmniFaces provided <a href="http://showcase.omnifaces.org/scripts/FixViewState">a limited fix</a> as well.
<p>
Part of the problem why this is a difficult issue to fix is the fact that JSF can also be used in a Portlet environment. In such environment it's not possible to have a javascript just update all JSF forms that it finds, as these may belong to different Portlets (the markup rendered by different Portlets is all part of the same HTML document with very little to no browser enforced isolation between them).
<p>
Below is an example of this problem. First consider the following view:
<div style="font-size:75%;">
<pre class="brush: xml;">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head/>
<h:body>
<h:panelGroup id="panel1" layout="block">
<h:form id="form1">
<h:commandButton id="button" value="submit form1 and render panel2">
<f:ajax execute=":form1" render=":panel2" />
</h:commandButton>
</h:form>
</h:panelGroup>
<h:panelGroup id="panel2" layout="block">
<h:form id="form2">
<h:commandButton id="button" value="submit form2 and render panel1">
<f:ajax execute=":form2" render=":panel1" />
</h:commandButton>
</h:form>
</h:panelGroup>
</h:body>
</html>
</pre>
</div>
<p>
Using Mojarra 2.2.13 (on Payara 4.1.1.162) clicking the first button will result in the following partial response to be send:
<div style="font-size:75%;">
<pre class="brush: xml;">
<?xml version='1.0' encoding='UTF-8'?>
<partial-response id="j_id1">
<changes>
<update id="panel2">
<![CDATA[
<div id="panel2">
<form id="form2" name="form2" method="post" action="/test-javaee8-ajax/spec790.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="form2" value="form2" />
<input id="form2:button" type="submit" name="form2:button" value="submit form2 and render panel1" onclick="mojarra.ab(this,event,'action','form2','panel1');return false" />
</form>
</div>
]]>
</update>
<update id="j_id1:javax.faces.ViewState:0">
<![CDATA[8345405308944877647:7731292386533209235]]>
</update>
</changes>
</partial-response>
</pre>
</div>
This will result in the HTML document be modified to effectively the HTML shown below:
<div style="font-size:75%;">
<pre class="brush: xml;">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="j_idt3">
<script type="text/javascript" src="/test-javaee8-ajax/javax.faces.resource/jsf.js.xhtml?ln=javax.faces"></script>
</head>
<body>
<div id="panel1">
<form id="form1" name="form1" method="post" action="/test-javaee8-ajax/spec790.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="form1" value="form1">
<input id="form1:button" type="submit" name="form1:button" value="submit form1 and render panel2" onclick="mojarra.ab(this,event,'action','form1','panel2');return false">
<input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="6782127948134886858:-5613250933960587439" autocomplete="off">
</form>
</div>
<div id="panel2">
<form id="form2" name="form2" method="post" action="/test-javaee8-ajax/spec790.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="form2" value="form2">
<input id="form2:button" type="submit" name="form2:button" value="submit form2 and render panel1" onclick="mojarra.ab(this,event,'action','form2','panel1');return false">
</form>
</div>
</body>
</html>
</pre>
</div>
As can be seen, the second form misses the input element with name "javax.faces.ViewState", which means when its submitted JSF won't process it.
<p>
This problem is solved in JSF 2.3 by introducing a "namespaced mode" and a "non namespaced mode", which is the default.
<p>
In namespaced mode, which is specifically intended for Portlets but can be used in other environments as well, the partial response is given an <i>id</i> that's taken to be the "naming container id". All predefined postback parameter names (such as "javax.faces.ViewState", "javax.faces.ClientWindow", "javax.faces.RenderKitId", etc) are prefixed with this and the naming separator (default ":"). e.g. javax.faces.ViewState" becomes "myname:javax.faces.ViewState". Namespaced mode is activated when the <a href="http://docs.oracle.com/javaee/7/api/javax/faces/component/UIViewRoot.html">UIViewRoot</a> instance implements the <a href="http://docs.oracle.com/javaee/7/api/javax/faces/component/NamingContainer.html">NamingContainer</a> interface.
<p>
In non namespaced mode the partial response does not have an <i>id</i> and the "naming container id" is set to be the empty string (""). All predefined postback parameters have their normal name.
<p>
In both cases, the "jsf.js" script handles a partial response by updating all forms where the <i>method</i> is "post", the <i>id</i> attribute is present and that <i>id</i> attribute starts with the "naming container id". In case of non namespaced mode this will thus match every form with an <i>id</i>.
<p>
Using Mojarra 2.3-m07 (on Payara 4.1.1.162) and the <b>non namespaced mode</b> clicking the first button on the view shown above will now result in the following partial response to be send:
<div style="font-size:75%;">
<pre class="brush: xml;">
<?xml version='1.0' encoding='UTF-8'?>
<partial-response>
<changes>
<update id="panel2">
<![CDATA[
<div id="panel2">
<form id="form2" name="form2" method="post" action="/test-javaee8-ajax/spec790.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="form2" value="form2" />
<input id="form2:button" type="submit" name="form2:button" value="submit form2 and render panel1" onclick="mojarra.ab(this,event,'action','form2','panel1');return false" />
</form>
</div>
]]>
</update>
<update id="j_id1:javax.faces.ViewState:0">
<![CDATA[-8282461998981779774:413768236226206985]]>
</update>
</changes>
</partial-response>
</pre>
</div>
After the above response has been received and processed by the "jsf.js" script, the HTML document will effectively be as shown below:
<div style="font-size:75%;">
<pre class="brush: xml;">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="j_idt3">
<script type="text/javascript" src="/test-javaee8-ajax/javax.faces.resource/jsf.js.xhtml?ln=javax.faces"></script>
</head>
<body>
<div id="panel1">
<form id="form1" name="form1" method="post" action="/test-javaee8-ajax/spec790.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="form1" value="form1">
<input id="form1:button" type="submit" name="form1:button" value="submit form1 and render panel2" onclick="mojarra.ab(this,event,'action','form1','panel2');return false">
<input type="hidden" name="javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="2250188649944914411:-7175801439454851104" autocomplete="off">
</form>
</div>
<div id="panel2">
<form id="form2" name="form2" method="post" action="/test-javaee8-ajax/spec790.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="form2" value="form2">
<input id="form2:button" type="submit" name="form2:button" value="submit form2 and render panel1" onclick="mojarra.ab(this,event,'action','form2','panel1');return false">
<input type="hidden" name="javax.faces.ViewState" value="2250188649944914411:-7175801439454851104">
</form>
</div>
</body>
</html>
</pre>
</div>
As can be seen, both forms have their view state input element now, although the second one did loose its <i>id</i> and <i>autocomplete</i> attributes.
<p>
In <b>namespaced mode</b> running a similar view as shown above and pressing the button again will yield the following response:
<div style="font-size:75%;">
<pre class="brush: xml;">
<?xml version='1.0' encoding='UTF-8'?>
<partial-response id="j_id1">
<changes>
<update id="j_id1:panel2">
<![CDATA[
<div id="j_id1:panel2">
<form id="j_id1:form2" name="j_id1:form2" method="post" action="/test-javaee8-namespacedView/spec790.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="j_id1:form2" value="j_id1:form2" />
<input id="j_id1:form2:button" type="submit" name="j_id1:form2:button" value="submit form2 and render panel1" onclick="mojarra.ab(this,event,'action','j_id1:form2','j_id1:panel1');return false" />
</form>
</div>
]]>
</update>
<update id="j_id1:javax.faces.ViewState:0">
<![CDATA[-8822830692037537003:-3037874094673406621]]>
</update>
</changes>
</partial-response>
</pre>
</div>
Note that the <i>partial-response</i> tag now has an <i>id</i> attribute that wasn't present in the non namespaced version, and note that the <i>id</i> attributes of the <i>update</i> tags are prefixed with exactly that value.
The HTML document will look effectively like the one below afterwards:
<div style="font-size:75%;">
<pre class="brush: xml;">
<html xmlns="http://www.w3.org/1999/xhtml"><head id="j_id1:j_idt3">
<script type="text/javascript" src="/test-javaee8-namespacedView/javax.faces.resource/jsf.js.xhtml?ln=javax.faces"></script>
</head>
<body>
<div id="j_id1:panel1">
<form id="j_id1:form1" name="j_id1:form1" method="post" action="/test-javaee8-namespacedView/spec790.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="j_id1:form1" value="j_id1:form1">
<input id="j_id1:form1:button" type="submit" name="j_id1:form1:button" value="submit form1 and render panel2" onclick="mojarra.ab(this,event,'action','j_id1:form1','j_id1:panel2');return false">
<input type="hidden" name="j_id1:javax.faces.ViewState" id="j_id1:javax.faces.ViewState:0" value="6924255192267784760:-4075825978563358382" autocomplete="off">
</form>
</div>
<div id="j_id1:panel2">
<form id="j_id1:form2" name="j_id1:form2" method="post" action="/test-javaee8-namespacedView/spec790.xhtml" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="j_id1:form2" value="j_id1:form2">
<input id="j_id1:form2:button" type="submit" name="j_id1:form2:button" value="submit form2 and render panel1" onclick="mojarra.ab(this,event,'action','j_id1:form2','j_id1:panel1');return false">
<input type="hidden" name="j_id1:javax.faces.ViewState" value="6924255192267784760:-4075825978563358382">
</form>
</div>
</body>
</html>
</pre>
</div>
As the <i>UIViewRoot</i> that was used in the above test is a <i>NamingContainer</i>, all rendered element ids are automatically prefixed as can be seen, as are the names of the input elements as shown in the HTML above.
<p>
By taking the namespaced ids into account, all forms can now be safely updated in a Portlets environment as well.
<p>
<p>
<br/>