Давайте разберем несколько простых случаев использования и посмотрим, как работают параметры представления (имена параметров представления не обязательны для соответствия параметрам запроса, переданным через строку запроса URL, но в этом посте мы сосредоточимся на этом случае):
ДЕЛО 1
На странице index.xhtml
мы имеем:
01
02
03
04
05
06
07
08
09
10
|
<f:metadata> <f:viewParam name= "playernameparam" value= "#{playersBean.playerName}" /> <f:viewParam name= "playersurnameparam" value= "#{playersBean.playerSurname}" /> </f:metadata> ... <h:form> Enter name:<h:inputText value= "#{playersBean.playerName}" /> Enter surname:<h:inputText value= "#{playersBean.playerSurname}" /> <h:commandButton value= "Send" action= "results?faces-redirect=true&includeViewParams=true" /> </h:form> |
На странице results.xhtml
мы имеем:
1
2
3
4
5
6
7
|
<f:metadata> <f:viewParam name= "playernameparam" value= "#{playersBean.playerName}" /> <f:viewParam name= "playersurnameparam" value= "#{playersBean.playerSurname}" /> </f:metadata> You requested name: <h:outputText value= "#{playersBean.playerName}" /><br/> You requested surname: <h:outputText value= "#{playersBean.playerSurname}" /> |
В PlayersBean
мы имеем:
1
2
3
4
5
6
7
8
|
@Named @RequestScoped public class PlayersBean { private String playerName; private String playerSurname; ... } |
Что происходит, когда приложение достигает (не важно, как вы задали строку запроса; вы можете сделать это вручную или перейти через
с участием
здесь) index.xhtml?playernameparam=rafael&playersurnameparam=nadal
?
- Имена параметров запроса совпадают с именами параметров представления, поэтому параметры представления принимают значения параметров запроса и, наконец, сохраняют их в управляемом компоненте
playerName
подplayerName
иplayerSurname
. Таким образом, грубо говоря, вы устанавливаете поля управляемого компонента с помощью параметров просмотра. - Представление отображается (HTML-разметка создается и отправляется в браузер), поэтому вы можете видеть
rafael
иnadal
в текстовых входах, так как они выбираются из свойств управляемого компонента (это#{playersBean.playerName}
и#{playersBean.playerSurname}
). - Вы (как пользователь) можете вручную изменить эти значения (тексты) при вводе текста (или оставить их такими). Теперь, когда вы нажимаете на
Кнопка Отправить, вы практически отправляете форму с текущими значениями (часть, разделенная<h:form>
</h:form>
). Таким образом, имя и фамилия передаются и переопределяют / инициализируют текущие значения в модели данных (даже если вы их не изменяли). Во время кодирования (рендеринга) представления JSF будет кодировать параметры представления также вPlayersBean
управляемого компонентаPlayersBean
. - Кроме того, JSF замечает, что вы хотите присоединить параметры представления (вы сигнализируете это как:
?faces-redirect=true&includeViewParams=true
) перед переходом на следующую целевую страницу (results.xhtml
). Параметры представления были оцененыPlayersBean
управляемого компонентаPlayersBean
ранее в этом запросе. Итак, JSF обрабатывает параметры представления и присоединяет к URL действия соответствующую строку запроса, вычисленную из имен и значений параметров представления. - JSF переходит к целевому URL (который теперь содержит строку запроса). Это видно благодаря
faces-redirect=true
.
ДЕЛО 2
На странице index.xhtml
мы имеем:
01
02
03
04
05
06
07
08
09
10
|
<f:metadata> <f:viewParam name= "playernameparam" value= "#{playersBean.playerName}" /> <f:viewParam name= "playersurnameparam" value= "#{playersBean.playerSurname}" /> </f:metadata> <h:form> Enter name:<h:inputText value= "#{playersBean.playerName}" /> Enter surname:<h:inputText value= "#{playersBean.playerSurname}" /> <h:commandButton value= "Send" action= "results?faces-redirect=true&includeViewParams=true" /> </h:form> |
На странице results.xhtml
мы имеем:
1
2
3
4
5
6
7
|
<f:metadata> <f:viewParam name= "playernameparam" value= "#{playersBean.playerName}" /> <f:viewParam name= "playersurnameparam" value= "#{playersBean.playerSurname}" /> </f:metadata> You requested name: <h:outputText value= "#{playersBean.playerName}" /><br/> You requested surname: <h:outputText value= "#{playersBean.playerSurname}" /> |
В PlayersBean
мы имеем:
1
2
3
4
5
6
7
8
|
@Named @RequestScoped public class PlayersBean { private String playerName = "roger" ; private String playerSurname = "federer" ; ... } |
Что происходит, когда приложение попадает в index.xhtml? (без строки запроса)
- Нет строки запроса (нет параметров запроса). Таким образом, параметры представления не могут быть инициализированы из строки запроса, и они также ничего не устанавливают в
PlayersBean
! - Представление отображается (HTML-разметка создается и отправляется в браузер), а текстовые вводы отражают
данныеfederer initalization
иfederer initalization
(это результат оценки#{playersBean.playerName}
и#{playersBean.playerSurname}
). - Вы (как пользователь) можете изменять эти значения при вводе текста (или нет!). Теперь, когда вы нажимаете кнопку «
Send
, вы практически отправляете форму (данные, принадлежащие части, разделенной<h:form>
</h:form>
). Итак, имя и фамилия передаются и переопределяют / инициализируют текущие значения в модели (даже если вы их не изменяли). Во время кодирования (рендеринга) представления JSF будет кодировать параметры представления также вPlayersBean
управляемого компонентаPlayersBean
. - Кроме того, JSF замечает, что вы хотите присоединить параметры представления (вы сигнализируете это как:
?faces-redirect=true&includeViewParams=true
) перед переходом на следующую целевую страницу (results.xhtml
). Параметры представления были оцененыPlayersBean
управляемого компонентаPlayersBean
ранее в этом запросе. Итак, JSF обрабатывает параметры представления и присоединяет к URL действия соответствующую строку запроса, вычисленную из имен и значений параметров представления. - JSF переходит к целевому URL (который теперь содержит строку запроса). Это видно благодаря
faces-redirect=true
.
ДЕЛО 3
На странице index.xhtml
мы имеем:
1
2
3
4
5
6
|
<f:metadata> <f:viewParam name= "playernameparam" value= "#{playersBean.playerName}" /> <f:viewParam name= "playersurnameparam" value= "#{playersBean.playerSurname}" /> </f:metadata> <h:link value= "Send" outcome= "results" includeViewParams= "true" /> |
На странице results.xhtml
мы имеем:
1
2
3
4
5
6
7
|
<f:metadata> <f:viewParam name= "playernameparam" value= "#{playersBean.playerName}" /> <f:viewParam name= "playersurnameparam" value= "#{playersBean.playerSurname}" /> </f:metadata> You requested name: <h:outputText value= "#{playersBean.playerName}" /><br/> You requested surname: <h:outputText value= "#{playersBean.playerSurname}" /> |
В PlayersBean
мы имеем:
1
2
3
4
5
6
7
8
|
@Named @RequestScoped public class PlayersBean { private String playerName; private String playerSurname; ... } |
Что происходит, когда приложение достигает (не важно, как вы задали строку запроса; вы можете сделать это вручную или перейти через с участием здесь) index.xhtml?playernameparam=rafael&playersurnameparam=nadal
?
- Имена параметров запроса совпадают с именами параметров представления, поэтому параметры представления принимают значения параметров запроса и сохраняют их в управляемом компоненте в
playerName
иplayerSurname
. Итак, вы устанавливаете поля управляемого компонента через параметры просмотра. - Представление отображается (разметка HTML генерируется и отправляется в браузер), поэтому в текстовых входах вы можете видеть
rafael
иnadal
, так как они выбираются из управляемого компонента (это результаты оценки#{playersBean.playerName}
и#{playersBean.playerSurname}
). Во время кодирования (рендеринга) представления JSF будет кодировать параметры представления также вPlayersBean
управляемого компонентаPlayersBean
. Теперь проверьте исходный код страницы и обратите внимание, что<a href>
соответствующий<h:link>
был сгенерирован, как<a href>
ниже (обратите внимание, что этоfix !
). Итак, JSF преобразует<h:link>
в<a href>
и присоединяет строку запроса, содержащую параметры представления, прямо из исходного запроса.includeViewParams="true"
вызывает ссылку ниже: - Когда вы нажимаете на ссылку, вы НЕ ПРЕДОСТАВЛЯЕТЕ никаких данных (
<h:link>
никогда не должна быть в<h:form>
). Вы просто выполняете приведенный выше статический HTML-код, который представляет собой простой запрос GET! - JSF переходит к целевому URL через этот GET (который содержит строку запроса). Нет необходимости в
faces-redirect=true
.
ДЕЛО 4
На странице index.xhtml
мы имеем:
1
2
3
4
5
6
|
<f:metadata> <f:viewParam name= "playernameparam" value= "#{playersBean.playerName}" /> <f:viewParam name= "playersurnameparam" value= "#{playersBean.playerSurname}" /> </f:metadata> <h:link value= "Send" outcome= "results" includeViewParams= "true" /> |
На странице results.xhtml
мы имеем:
1
2
3
4
5
6
7
|
<f:metadata> <f:viewParam name= "playernameparam" value= "#{playersBean.playerName}" /> <f:viewParam name= "playersurnameparam" value= "#{playersBean.playerSurname}" /> </f:metadata> You requested name: <h:outputText value= "#{playersBean.playerName}" /><br/> You requested surname: <h:outputText value= "#{playersBean.playerSurname}" /> |
В PlayersBean
мы имеем:
1
2
3
4
5
6
7
8
|
@Named @RequestScoped public class PlayersBean { private String playerName = "roger" ; private String playerSurname = "federer" ; ... } |
Что происходит, когда приложение попадает в index.xhtml? (без строки запроса)
- Нет параметров запроса. Таким образом, параметры представления не могут быть инициализированы из строки запроса. Параметры вида также ничего не устанавливают в управляемом бине!
- Представление отображается (разметка HTML создается и отправляется в браузер), поэтому вы можете видеть roger и
federer
в текстовых входах, так как они выбираются из управляемого компонента (это результат оценки#{playersBean.playerName}
и#{playersBean.playerSurname}
). Во время кодирования (рендеринга) представления JSF будет кодировать параметры представления также вPlayersBean
управляемого компонентаPlayersBean
(получениеroger
иfederer
). Теперь проверьте исходный код страницы и обратите внимание, что<a href>
соответствующий<h:link>
был сгенерирован, как<a href>
ниже (обратите внимание, что этоfix !
). Итак, JSF преобразует<h:link>
в<a href>
и присоединяет строку запроса, содержащую параметры представления, прямо из исходного запроса.includeViewParams="true"
вызывает ссылку ниже: - Когда вы нажимаете на ссылку, вы не предоставляете никаких данных. Вы просто выполняете приведенный выше статический HTML-код, который представляет собой простой запрос GET!
- JSF переходит к целевому URL через этот GET (который содержит строку запроса). Там нет необходимости
faces-redirect=true
.
ДЕЛО 5
На странице index.xhtml
мы имеем:
1
2
3
4
5
6
|
<f:metadata> <f:viewParam name= "playernameparam" value= "#{playersBean.playerName}" /> <f:viewParam name= "playersurnameparam" value= "#{playersBean.playerSurname}" /> </f:metadata> <h:link value= "Send" outcome= "results" includeViewParams= "true" /> |
На странице results.xhtml
мы имеем:
1
2
3
4
5
6
7
|
<f:metadata> <f:viewParam name= "playernameparam" value= "#{playersBean.playerName}" /> <f:viewParam name= "playersurnameparam" value= "#{playersBean.playerSurname}" /> </f:metadata> You requested name: <h:outputText value= "#{playersBean.playerName}" /><br/> You requested surname: <h:outputText value= "#{playersBean.playerSurname}" /> |
В PlayersBean
мы имеем:
1
2
3
4
5
6
7
8
|
@Named @RequestScoped public class PlayersBean { private String playerName; // this is null private String playerSurname; // this is null ... } |
Что происходит, когда приложение попадает в index.xhtml? (без строки запроса)
- Нет параметров запроса. Таким образом, параметры представления не могут быть инициализированы из строки запроса. Параметры вида ничего не устанавливают в bean-компоненте!
- Представление отображается (HTML-разметка создается и отправляется в браузер), поэтому в текстовых входах ничего не видно, так как они выбираются из компонента (это
#{playersBean.playerName}
и#{playersBean.playerSurname}
которые являютсяnull
— вы не можете ожидать увидеть текстnull!
). Во время кодирования (рендеринга) представления JSF будет кодировать параметры представления также вPlayersBean
управляемого компонентаPlayersBean
(получениеnull
). Теперь проверьте исходный код страницы и обратите внимание, что<a href>
соответствующий<h:link>
был сгенерирован, как<a href>
ниже (обратите внимание, что этоfix !
). Итак, JSF преобразует<h:link>
в<a href>
, но нет строки запроса, содержащей параметры представления, потому что JSF видитincludeViewParams="true"
, но он не может сгенерировать этот HTML: <a href = ” /…/results.xhtml? playernameparam = null & amp; Playersurnameparam = null «> Отправить </a> Итак, JSF будет« игнорировать »null
значения и нет строки запроса для прикрепления: <a href=oted/…/results.xhtml книг> Отправить </a> - Когда вы нажимаете на ссылку, вы не предоставляете никаких данных. Вы просто выполняете приведенный выше статический HTML-код, который представляет собой простой запрос GET!
- JSF переходит к целевому URL через этот GET (который содержит строку запроса). Нет необходимости в face-redirect = true.
Случай 6 — для лучшего понимания нулевых значений
На странице index.xhtml
мы имеем:
01
02
03
04
05
06
07
08
09
10
|
<f:metadata> <f:viewParam name= "playernameparam" value= "#{playersBean.playerName}" /> <f:viewParam name= "playersurnameparam" value= "#{playersBean.playerSurname}" /> </f:metadata> <h:form> Enter name:<h:inputText value= "#{playersBean.playerName}" /> Enter surname:<h:inputText value= "#{playersBean.playerSurname}" /> <h:commandButton value= "Send" action= "results?faces-redirect=true&includeViewParams=true" /> </h:form> |
На странице results.xhtml
мы имеем:
1
2
3
4
5
6
7
|
<f:metadata> <f:viewParam name= "playernameparam" value= "#{playersBean.playerName}" /> <f:viewParam name= "playersurnameparam" value= "#{playersBean.playerSurname}" /> </f:metadata> You requested name: <h:outputText value= "#{playersBean.playerName}" /><br/> You requested surname: <h:outputText value= "#{playersBean.playerSurname}" /> |
В PlayersBean
мы имеем:
1
2
3
4
5
6
7
8
|
@Named @RequestScoped public class PlayersBean { private String playerName; // this is null private String playerSurname; // this is null ... } |
Что происходит, когда приложение попадает в index.xhtml? (без строки запроса)
- Нет параметров запроса. Таким образом, параметры представления не могут быть инициализированы из строки запроса. Параметры вида также ничего не устанавливают в bean-компоненте!
- Представление отображается (HTML-разметка создается и отправляется в браузер), и вы можете видеть два пустых текстовых ввода (это результаты оценки
#{playersBean.playerName}
и#{playersBean.playerSurname}
). Вы не можете ожидать увидеть текст, ноль! - Как пользователь, не вводите ничего в эти текстовые поля и нажмите кнопку «
Send
. Практически вы отправите форму (данные, принадлежащие части, разделенной<h:form>
</h:form>
). Итак, имя и фамилия (которые являются пустыми местами) передаются и переопределяют / инициализируют текущие значения в модели. Во время кодирования (рендеринга) представления JSF будет кодировать параметры представления такжеPlayersBean
управляемого компонентаPlayersBean
(получит пустые места). - Кроме того, JSF замечает, что вы хотите присоединить параметры представления (вы сигнализируете это как:
?faces-redirect=true&includeViewParams=true
) перед переходом на следующую целевую страницу (results.xhtml
). Параметры представления были оцененыPlayersBean
управляемого компонентаPlayersBean
ранее в этом запросе. Итак, JSF обрабатывает параметры представления и присоединяет к URL действия соответствующую строку запроса, вычисленную из имен и значений параметров представления. - JSF переходит к целевому URL (который теперь содержит строку запроса). Это видно благодаря
faces-redirect=true
.
http://localhost:8080/.../results.xhtml?playernameparam=&playersurnameparam=
Обратите внимание на значения playernameparam
и playersurnameparam!
Так как вы отправили пустые места, это то, что вы увидите. Конечно, это выглядит «некрасиво» и довольно бесполезно. Может быть, вы предпочтете рассматривать пустые места как null
значения. Для этого вы можете установить в web.xml
следующий параметр контекста:
1
2
3
4
|
<context-param> <param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name> <param-value> true </param-value> </context-param> |
Теперь очистите и соберите приложение и запустите его снова с тем же сценарием. На этот раз, когда вы нажимаете на
Кнопка Отправить, вы заметили эту ссылку:
- HTTP: // локальный: 8080 / ch2_6 / лица / results.xhtml
Таким образом, ни одна строка запроса не отражает наличие параметров вида! Ну, вы только что проинструктировали JSF обрабатывать отправленную пустую строку как null
значения Но, как вы знаете, null
значения «игнорируются», когда параметры вида прикреплены.
НОТА
Способ прикрепления параметров представления можно увидеть в Mojarra, в com.sun.faces.application.view.MultiViewHandler
. Особенно в:
01
02
03
04
05
06
07
08
09
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
|
// Mojarra 2.2.9, MultiViewHandler#addViewParameters() protected void addViewParameters(FacesContext ctx, String viewId, Map<String,List<String>> existingParameters) { UIViewRoot currentRoot = ctx.getViewRoot(); String currentViewId = currentRoot.getViewId(); Collection<UIViewParameter> toViewParams = Collections.emptyList(); Collection<UIViewParameter> currentViewParams; boolean currentIsSameAsNew = false ; currentViewParams = ViewMetadata.getViewParameters(currentRoot); if (currentViewId.equals(viewId)) { currentIsSameAsNew = true ; toViewParams = currentViewParams; } else { ViewDeclarationLanguage pdl = getViewDeclarationLanguage(ctx, viewId); ViewMetadata viewMetadata = pdl.getViewMetadata(ctx, viewId); if ( null != viewMetadata) { UIViewRoot root = viewMetadata.createMetadataView(ctx); toViewParams = ViewMetadata.getViewParameters(root); } } if (toViewParams.isEmpty()) { return ; } for (UIViewParameter viewParam : toViewParams) { String value = null ; // don't bother looking at view parameter if it's been overridden if (existingParameters.containsKey(viewParam.getName())) { continue ; } if (paramHasValueExpression(viewParam)) { value = viewParam.getStringValueFromModel(ctx); } if (value == null ) { if (currentIsSameAsNew) { value = viewParam.getStringValue(ctx); } else { value = getStringValueToTransfer(ctx, viewParam, currentViewParams); } } // SO, IF VALUE IS NULL, DON'T CONSIDER THIS A VIEW PARAM if (value != null ) { List<String> existing = existingParameters.get(viewParam.getName()); if (existing == null ) { existing = new ArrayList<String>( 4 ); existingParameters.put(viewParam.getName(), existing); } existing.add(value); } } } |
Ссылка: | Как параметры просмотра получаются / прикрепляются из / к строке запроса URL (примеры)? от нашего партнера JCG Ангела Леонарда в блоге JSF и фанатов OmniFaces . |