#jsf #jsf-2 #view-scope #http-request-parameters
#jsf #jsf-2 #вид-область видимости #http-запрос-параметры #область просмотра
Вопрос:
У моего боба есть это:
@ManagedBean
@ViewScoped
public class BookBean implements Serializable
{
@ManagedProperty(value = "#{param.id}") // does not work with @ViewScoped
private String id;
public void init()
{
id = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id")
if (id != null) {
System.out.println("ID: " id);
currentBook = bookService.find(id);
}
}
@PostConstruct
public void post()
{
// does not work with @ViewScoped
System.out.println("ID: " id);
currentBook = bookService.find(id);
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
И конечный интерфейс имеет это:
<f:metadata>
<f:viewParam name="id" value="#{bookBean.id}">
<f:event type="preRenderView" listener="#{bookBean.init}" />
</f:viewParam>
</f:metadata>
В ходе тестирования я заметил, что @ManagedProperty
и @PostConstruct
работают только с @RequestScoped
компонентом.
Для @ViewScoped
bean я обнаружил, что мне пришлось сделать это, FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("id")
чтобы получить значение id
параметра.
Является ли это единственным способом получить значение параметра запроса с помощью @ViewScoped
?
Есть какие-нибудь мысли?
Ответ №1:
Область представления шире области запроса. @ManagedProperty
Может устанавливать свойства, которые имеют ту же или более широкую область по сравнению с областью управляемого компонента.
Просто продолжайте использовать <f:viewParam>
with <f:event>
. Вы должны только не вкладывать их друг в друга.
<f:metadata>
<f:viewParam name="id" value="#{bookBean.id}" />
<f:event type="preRenderView" listener="#{bookBean.init}" />
</f:metadata>
с
@ManagedBean
@ViewScoped
public class BookBean implements Serializable {
private String id;
public void init() {
if (id != null) {
currentBook = bookService.find(id);
}
}
// ...
}
<f:viewParam>
Установит параметр запроса и <f:event>
выполнит метод прослушивания после установки этих параметров.
@PostConstruct
Также отлично работает на компонентах с областью просмотра, но запускается только непосредственно после построения компонента и установки всех инъекций зависимостей (таких как @ManagedProperty
, @EJB
@Inject
, @Resource
, и т.д.). <f:viewParam>
Однако впоследствии свойство устанавливается, поэтому оно недоступно в @PostConstruct
.
Комментарии:
1. @BalusC: У меня это не сработало. Значение
id
возвращает null.2. Здесь работает нормально. Какой JSF impl / version? Какой сервер приложений? Я создал быстрый тестовый набор с Mojarra 2.0.4 на Tomcat 7.0.11, и он отлично работает при вызове
test.xhtml?id=123
.3. Mojarra 2.1.0, который поставляется с Glassfish 3.1. Мои средства получения / установки созданы для
id
поля =, поэтому технически оно должно принимать значение, установленноеf:viewParam>
тегом4. Вы уверены, что исправили неправильную вложенность? Если вы вложите его, то
f:event
будет вызван раньшеf:viewParam
.5. @BalusC: Да, я забыл переместить тег f:event после
<f:metadata>
тега. Моя ошибка. Сегодня я узнал кое-что новое. Могу ли я предложить, чтобы будущая спецификация JSF была написана вами, Бауке. У вас есть талант в том, что вы можете переводить сложную документацию в простые для понимания демонстрируемые примеры кода. Я уже побывал на многих сайтах JSF 2, включая те, которые написаны сотрудниками Sun, но я не могу разобраться в некоторых их объяснениях новых функций JSF 2, таких как<f:viewParam>
. С другой стороны, у вас это выглядит так просто. Я уважаю тебя за эту способность…
Ответ №2:
Вот еще один метод получения параметра запроса внутри компонента ViewScoped. Это было бы то, что #{param.device} получил бы в компоненте, ограниченном запросами. Преимущество этого заключается в том, что не требуются никакие теги на уровне представления.
private int deviceID;
public int getDeviceID() {
if (deviceID == 0) {
String s = FacesContext.getCurrentInstance().getExternalContext().
getRequestParameterMap().get("device");
try {
deviceID = Integer.parseInt(s);
} catch (NumberFormatException nfe) {
}
}
return deviceID;
}