Проблема JSF Navigation Facelets и Beans

У меня проблема с навигацией в моей простой системе jsf.

У меня есть MainBean с двумя методами: public String register() и public String login().

Я играл с faces-config.xml в течение нескольких часов и чувствую, что упускаю что-то очень важное, потому что я думаю, что до сих пор пробовал все простые решения :).

Я добавил соединитель MySQL (jdbc) в папку lib Tomcat, и я могу зарегистрировать таблицу в базе данных MySQL. Он даже позволяет моим пользователям входить на страницу.

Единственная проблема в том, что я не могу использовать навигацию на любой другой странице, кроме login.xhtml. Похоже, навигация активна только на этом. Я пытался использовать <from-view-id>*, но это не радость. Я уверен, что для этого есть простое решение, и кто-то скоро придумает правильное решение. Давайте пропустим всю часть MySQL и попробуем решить проблему с навигацией, пожалуйста.

Вот faces-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
    version="1.2">
  <application>
    <view-handler>com.sun.facelets.FaceletViewHandler</view-handler>    
  </application>
 <managed-bean>
  <managed-bean-name>mainBean</managed-bean-name>
  <managed-bean-class>dk.itu.beans.MainBean</managed-bean-class>
  <managed-bean-scope>session</managed-bean-scope>
 </managed-bean>
 <managed-bean>
  <managed-bean-name>registerBean</managed-bean-name>
  <managed-bean-class>dk.itu.beans.RegisterBean</managed-bean-class>
  <managed-bean-scope>session</managed-bean-scope>
 </managed-bean>
 <navigation-rule>
  <from-view-id>/login.xhtml</from-view-id>
  <navigation-case>
   <from-outcome>success</from-outcome>
   <to-view-id>/welcome.xhtml</to-view-id>
  </navigation-case>
        <navigation-case>
      <from-outcome>failure</from-outcome>
      <to-view-id>/login_failed.xhtml</to-view-id>
    </navigation-case>
        <navigation-case>
      <from-outcome>sign</from-outcome>
      <to-view-id>/register.xhtml</to-view-id>
    </navigation-case>
 </navigation-rule>
  <navigation-rule>
  <from-view-id>/login_failed.xhtml</from-view-id>
  <navigation-case>
  <from-outcome>back</from-outcome>
      <to-view-id>/login.xhtml</to-view-id>
  </navigation-case>
  </navigation-rule>
</faces-config>

Здесь последнее правило навигации из login_failed.xhtml вообще не работает.

Вот login.xhtml (основной - начальный вид):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
<body>
<ui:composition template="/template.xhtml">
  <ui:define name="body">
    <h:form id="helloForm">
    <h:panelGrid columns="2">
   <h:outputText value="Username2:" />
   <h:inputText id="username" value="#{mainBean.username}" />
   <h:outputText value="Password:" />
   <h:inputSecret id="password" value="#{mainBean.password}" />
  </h:panelGrid>
  <h:commandButton value="Log in" action="#{mainBean.login}" />
  <h:commandButton value="Sign up" action="sign" />
 </h:form>
  </ui:define>  
</ui:composition>
</body>
</html>
login_failed.xhtml:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
<body>
<ui:composition template="/template.xhtml">
  <ui:define name="body">
<f:view>
 <h:outputText value="Unknown username or password." />
 <h:commandButton value="Sign up" action="sign" />
 <h:commandButton value="Log in" action="back" />
</f:view>
</ui:define>  
</ui:composition>
</body>
</html>

Тут перепробовал много вариантов. Я использовал метод action="#{mainBean.register})", который возвращает строку «знак», и ни один из них не работал. Есть еще один файл (не указан в файле faces-config.xml, т.к. тоже не работал - но переход с login.xhtml по кнопке работает нормально. Пробовал сначала управлять навигацией с login_failed.xhtml, потом применю то же правило для регистрации, чтобы вернуться в логин страницу, когда клиент регистрирует свой никнейм).

Вот register.xhtml:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
<body>
<ui:composition template="/template.xhtml">
  <ui:define name="body">
    <h:form id="helloForm">
    <h:panelGrid columns="2">
       <h:outputText value="User Name:"/>
      <h:inputText type="text" id="userName" value=""/>
   <h:outputText value="Password:"/>
      <h:inputSecret type="text" id="userPassword" value=""/>
      <h:outputText value="Member Level:"/>
      <h:selectOneRadio value="">
                              <f:selectItem itemLabel="Platinium" itemValue="Platinum" />
                              <f:selectItem itemLabel="Gold" itemValue="Gold" />
                              <f:selectItem itemLabel="Normal" itemValue="Normal" />
                          </h:selectOneRadio>
      <h:outputText value="Full Name:"/>
      <h:inputText type="text" id="userFull" value=""/>
      <h:outputText value="Address:"/>
      <h:inputTextarea type="text" id="userAddress" value=""/>
      <h:outputText value="Zip Code:"/>
      <h:inputText type="text" id="userZip" value=""/>
      <h:outputText value="City:"/>
      <h:inputText type="text" id="userCity" value=""/>
   <h:commandButton value="Sign Up" action="#{mainBean.register}" />
    </h:panelGrid>
    </h:form>
  </ui:define>  
</ui:composition>
</body>
</html>

В основном mainBean.register теперь вызывает базу данных и возвращает строку, но, очевидно, она не переходит к какому-либо представлению (но дает запись в базу данных).

Я считаю, что это простое решение для большинства опытных веб-разработчиков, и любая помощь будет принята с благодарностью.

Я использую eclipse, tomcat 6 и Widows Vista, если это помогает :)

Заранее спасибо. С наилучшими пожеланиями.


person ortho    schedule 14.03.2010    source источник


Ответы (2)


В общем, я могу порекомендовать попробовать что-то простое, прежде чем переходить к более сложным вещам, таким как шаблоны. Несколько указателей:

  • Используйте перенаправление в правиле навигации на странице входа. Таким образом, вам не нужна какая-то особая шумиха, чтобы кнопка «Назад» заработала.
  • Как правило, создавать сессионный компонент до проверки входа в систему — плохая идея. Распространенным решением является использование компонента identity bean с областью действия запроса на странице входа, а затем внедрение его в действие LoginAction, которое проверяет учетные данные и создает пользовательский сеанс.

У меня есть довольно полный онлайн-образец Facelets/JSF2, демонстрирующий такое поведение:

Не стесняйтесь применять шаблон проектирования «копировать-вставить» к своему коду сколько угодно.

person Lars Tackmann    schedule 14.03.2010
comment
Эти ссылки не работают. Ответ все еще несколько полезен, но есть ли шанс, что вы сможете исправить эти ссылки? - person Tim S.; 22.11.2013

Компоненты UICommand должны быть размещены внутри элемента UIForm. В login_failed.xhtml вы забыли использовать h:form. Добавьте его, и он будет работать.

person BalusC    schedule 14.03.2010