Вопрос по java, jsf, jsf-2 – Значение viewParam не установлено в bean-компоненте ViewScoped

3

Извините, возможно, еще один действительно простой вопрос. В моем bean-компоненте ViewScoped 'viewParam' Похоже, он уже установлен, но когда я его использую, значение равно нулю. Я установил точку останова в сеттере (setEventId ()), и он получил значение, но в методе, указанном в моем preRenderView, он исчез, поэтому я не могу загрузить объект Event, который пытаюсь получить.

Это работало нормально, когда мой бин был RequestScoped, но я обнаружил, что при POST и последующей ошибке проверки все мои данные были потеряны, и я прочитал, что ViewScoped был способом обойти эту проблему.

Я обновился до Mojarra 2.1.7, потому что думал, что это может быть ошибкой, и действительно есть «критическая ошибка»; перечислены в их JIRA, исправлены в 2.1.7, но я проверил в журналах Glassfish, что он использует более новую версию, и я все еще получаю ту же проблему:http://java.net/jira/browse/JAVASERVERFACES-2266

Пожалуйста, помогите, вот мой боб (я пробовал с аннотацией ManagedProperty и без нее)

@ViewScoped
@Named
public class EventController extends AbstractController {

    private static final Logger logger = Logger.getLogger("EventController");

    /**
     * Request param managed property
     */
    @ManagedProperty(value="#{param.eventId}")
    private Long eventId;                

    private Event event = new Event();

    /**
     * The event dao
     */
    @Inject
    private EventDao eventDao;    

    /**
     * Load the event (requires eventId has a value)
     * @return 
     */
    public void loadEvent() {
        event = eventDao.find(eventId);
    }    

    /**
     * @return the eventId
     */
    public Long getEventId() {
        return eventId;
    }

    /**
     * @param eventId the eventId to set
     */
    public void setEventId(Long eventId) {
        this.eventId = eventId;
    }   
}

Вот как я создаю ссылку в «listEvents». страница

<h:link value="Full details" outcome="/calendar/viewEvent" includeViewParams="true">
<f:param name="eventId" value="#{calendarController.event.eventId}" />
</h:link>

А вот и страница, которой нужно свойство eventId

<?xml version='1.0' encoding='UTF-8' ?>
<!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:p="http://primefaces.org/ui"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:c="http://java.sun.com/jsp/jstl/core">

    <body>

        <ui:composition template="/WEB-INF/templates/standardTemplate.xhtml">

    <f:metadata>
        <f:viewParam name="eventId" value="#{eventController.eventId}"/>
        <f:event type="preRenderView" listener="#{eventController.loadEvent}" />
    </f:metadata>            

            <ui:define name="content">      

                <h1>Event details for: #{eventController.event.title}</h1>
                <h:form>
                    <p:messages/>                                               

                    <p:panelGrid style="margin-top:20px">  
                        <f:facet name="header">  
                            <p:row>  
                                <p:column colspan="4">Event details</p:column>  
                            </p:row>  
                        </f:facet>  

                        <p:row>  
                            <p:column>
                                Title
                            </p:column>  
                            <p:column colspan="3">
                                <p:inputText value="#{eventController.event.title}" size="49"/>
                                <h:inputHidden id="eventId" value="#{eventController.event.eventId}"/>
                            </p:column>   
                        </p:row>                                                                                                   
                </h:form>                                
            </ui:define>
        </ui:composition>            
    </body>
</html>

Ваш Ответ

2   ответа
1

Я использовал Java EE 7 на Glassfish 4.0 build 89 и Primefaces 4.0. Glassfish сообщил, что он использует Mojarra 2.2.0. Я использовал аннотации типа CDI, то есть @Named и @ javax.faces.view.Viewscoped. Мой * .xhtml файл запустился так

<?xml version="1.0" encoding="UTF-8"?>
<!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:h="http://xmlns.jcp.org/jsf/html"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">

<f:metadata>
    <f:viewAction action="#{personController.initialise}" />
    <f:viewParam name="id" value="#{personController.id}" />
</f:metadata>
...

Независимо от того, что я пробовал, он никогда не устанавливал параметры просмотра. Я читал, что была проблема с Mojarra 2.2.1 и думал, что это может быть то же самое с Mojarra 2.2.0. Updatetool больше не обновлял Mojarra, чем у меня, поэтому я сделал это вручную. Я положил копию последней реализации Mojarra отhttp://repo1.maven.org/maven2/org/glassfish/javax.faces/2.2.5/ в каталог $ GLASSFISH_HOME / glassfish / modules, переименуйте его в javax.faces.jar и создайте резервную копию существующего файла javax.faces.jar. Перезапустил Glassfish и сообщил, что теперь использует Mojarra 2.2.5. Проблемы ушли и код работал нормально.

2

@ViewScoped аннотации работ на JSF@ManagedBean только не на CDI@Named, На CDI@Named вы можете использовать только области действия CDI, а не области JSF. Самое близкое, что предлагает CDI, это@ConversationScoped, Но вы сами управляете началом и концом разговора с помощью дополнительного стандартного кода.

Та же история относится к JSF@ManagedProperty аннотаций. Работает в JSF@ManagedBean только не на CDI@Named, Для CDI вы должны использовать@Inject илипользовательская аннотация HTTP-параметров.

Выпуск 2266 JSFunrelated на это все.

Добро пожаловать. Обратите внимание, что вы все еще можете использовать@Inject в@ManagedBean, Или просто@EJB если это сервисы, которые должны работать в управляемом контейнером транзакционном контексте и ваш контейнер поддерживает его (Glassfish, JBoss AS, TomEE и т. д.).
Ааа. Спасибо, я рвал на себе волосы этим. Заменили Named на ManagedBean и удалили аннотацию ManagedProperty. Теперь работает хорошо, и запоминает значения, когда я получаю ошибку проверки. Richard

Похожие вопросы