Nano Hash - криптовалюты, майнинг, программирование

Неявная навигация не работает

У меня есть управляемый компонент @ConversationScoped CDI в моем приложении JSF с использованием Primefaces 5.2, работающего на Wildfly 8.2.1. Неявная навигация работает только один раз в моем приложении. Во-первых, у меня есть файл index.xhtml, в котором есть кнопка, вызывающая управляемый компонент CiudadManagedBean:

<!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:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"> 

<ui:composition template="/plantilla/template.xhtml">

    <ui:define name="contenido">
    <h:form>
        <p:commandButton action="#{ciudadMB.cargarCiudades()}"
        value="Mostrar ciudades" />
    </h:form>
    </ui:define>
 </ui:composition>
</html>

Далее, вот CiudadesManagedBean. Как видите, я начинаю разговор с методом @PostConstruct, и он загружает список, когда я вызываю cargarCiudades из index.xhtml, и, наконец, он загружает ciudades/lista.xhtml:

package com.saplic.fut.beans;

import java.io.Serializable;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.inject.Inject;
import javax.inject.Named;

import com.saplic.fut.daos.CiudadDAO;
import com.saplic.fut.entity.Ciudad;

@Named(value="ciudadMB")
@ConversationScoped
public class CiudadManagedBean implements Serializable {

    private static final long serialVersionUID = 7339176875158769385L;

    private Ciudad instance;
    private List<Ciudad> cities;
    private Integer idCity;

    @Inject
    private CiudadDAO ciudadDAO;

    @Inject
    private Conversation conversation;

    @PostConstruct
    public void inicializarConversacion() {
        if(conversation.isTransient())
            conversation.begin();
    }

    public Ciudad getInstance() {
        return instance;
    }

    public String cargarCiudades() {
        setCities(ciudadDAO.cargarCiudades());
        return "ciudades/lista";
    }

    public String cargar() {
        Ciudad flt = new Ciudad();
        flt.setId(getIdCity());
        setInstance(ciudadDAO.cargarDetalle(flt));
        if(getInstance() == null)
            setInstance(new Ciudad());
        return "ciudades/detalle";
    }

    public String guardar() {
        ciudadDAO.guardar(getInstance());
        setCities(ciudadDAO.cargarCiudades());
        return "ciudades/lista";
    }

    public String actualizar() {
        ciudadDAO.actualizar(getInstance());
        setCities(ciudadDAO.cargarCiudades());
        return "ciudades/lista";
    }

    public String eliminar() {
        ciudadDAO.guardar(getInstance());
        setCities(ciudadDAO.cargarCiudades());
        return "ciudades/lista";
    }

    public void setInstance(Ciudad instance) {
        this.instance = instance;
    }

    public List<Ciudad> getCities() {
        return cities;
    }

    public void setCities(List<Ciudad> cities) {
        this.cities = cities;
    }

    public Integer getIdCity() {
        return idCity;
    }

    public void setIdCity(Integer idCity) {
        this.idCity = idCity;
    }

}

Наконец, xhtml, в котором я вызываю свой метод cargar(). Я хочу вызвать этот метод, а затем загрузить ciudades/detalle.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:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"> 

<ui:composition template="/plantilla/template.xhtml">

    <ui:define name="contenido">
    <h:form id="frm1">

        <p:dataTable id="tablita" resizableColumns="true" rowIndexVar="rowIdx"
        paginator="true" rows="10" paginatorPosition="bottom" value="#{ciudadMB.cities}"
        var="ciu" >
            <p:column headerText="Código pais">
                <p:outputLabel value="#{ciu.codigoPais}" />
            </p:column>
            <p:column headerText="Distrito">
                <p:outputLabel value="#{ciu.distrito}" />
            </p:column>
            <p:column headerText="Nombre">
                <p:outputLabel value="#{ciu.nombre}" />
            </p:column>
            <p:column headerText="Población">
                <p:outputLabel value="#{ciu.poblacion}" />
            </p:column>
            <p:column headerText="Accion">
                <p:commandLink action="#{ciudadMB.cargar()}" ajax="false" value="Ver" process="@form">
                    <f:setPropertyActionListener value="#{ciu.id}" target="#{ciudadMB.idCity}" />
                </p:commandLink>
            </p:column>
        </p:dataTable>
    </h:form>
    </ui:define>
 </ui:composition>
</html>

Когда я нажимаю на ссылку внутри моей таблицы данных, она вызывает ciudadMB.cargar() и выполняет код внутри нее, но игнорирует возврат "ciudades/detalle". Таким образом, неявная навигация работает в первый раз (когда я нахожусь в index.xhtml и нажимаю кнопки, я перехожу к lista.xhtml), но когда я нажимаю ссылку для перехода к detalle.xhtml, она игнорируется. Он просто обновляет lista.xhtml. Кроме того, я пробовал использовать @SessionScoped и @RequestScoped (всегда используя аннотации javax.enterprise.context вместо аннотаций JSF и удаляя объект Conversation и инициализацию).

С @SessionScoped у него такое же поведение. Разбивка на страницы работает без проблем, но когда я нажимаю на commandLink внутри datatable, он вызывает метод действия, но игнорирует возврат строки.

С @RequestScoped, если я нажму на commandLink, он обновит страницу, но не вызовет метод действия. Если я помещаю фиктивную команду CommandLink за пределы таблицы данных, она вызывает метод действия, но опять же игнорирует возврат строки.

Почему неявная навигация не работает? Проблема с CDI? С Уважением.

РЕДАКТИРОВАТЬ: я также изменил аннотации, чтобы импортировать javax.faces.bean.ManagedBean; импортировать javax.faces.bean.SessionScoped; чтобы проверить, было ли это связано с аннотациями CDI, но это тоже не сработало, так что это не проблема CDI. Нужно ли мне что-то активировать в моей конфигурации, чтобы она работала? Это динамический веб-проект Eclipse 3.1, JPA 2.1 и JSF 2.2, работающий на Wildfly 8.2.1. Вот мой файл конфигурации web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
  <display-name>SistemaFutJsf</display-name>
  <welcome-file-list>
    <welcome-file>index.xhtml</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>Faces Servlet</servlet-name>
    <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/</url-pattern>
    <url-pattern>*.xhtml</url-pattern>
  </servlet-mapping>
  <context-param>
    <param-name>primefaces.THEME</param-name>
    <param-value>cupertino</param-value>
  </context-param>
</web-app>

лица-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config
    xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd"
    version="2.2">

</faces-config>

И файл CDI beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
       version="1.1" bean-discovery-mode="annotated">

</beans>

  • Вы подразумеваете, что он отлично работает с управляемым компонентом JSF. Но вы нигде прямо не подтвердили это в своем вопросе. Просьба уточнить. Кроме того, ваш bean-компонент на самом деле относится к области сеанса, а не к области диалога. Это смущает. 21.08.2015
  • Извините, вы правы. Я перешел на @ SessionScoped, чтобы проверить, не связана ли проблема с @ ConversationScopes, но это тоже не сработало. Я поправлю свой вопрос. 21.08.2015
  • Хорошо, резюмируя, независимо от структуры управления bean-компонентом и независимо от области bean-компонента, метод действия в любом случае вызывается правильно, но возвращаемая строка для результата навигации полностью игнорируется, поскольку она возвращается на ту же страницу? 21.08.2015
  • Точно, это идет к той же самой странице. В выводе консоли я не получаю никакого вывода, указывающего, что мой возврат String неверен или что страница xhtml (ciudades/detalle.xhtml) не существует. Я вижу обновление, потому что использую ajax=false. РЕДАКТИРОВАТЬ: с CDI @RequestScoped commandLink внутри datatable не вызывает метод действия, но вне его он делает 21.08.2015
  • Вот ссылка для загрузки исходного кода infotomb.com/mx2i6.rar (сейчас он имеет JSF аннотации вместо CDI) 21.08.2015
  • Метод вообще выполняется? Или это просто неявная часть навигации, которая терпит неудачу? 21.08.2015
  • Да, метод выполняется без проблем, возврат тоже выполняется без проблем и без Exceptions, похоже какой-то перехватчик JSF просто игнорирует возвращаемое значение. Это странно, потому что, когда я нажимаю кнопку на index.xhtml, которая вызывает CiudadManagedBean.cargarCiudades(), загружает ciudades/lista.xhtml, но после этого первого вызова ManagedBean игнорирует результаты последующих вызовов. 22.08.2015

Ответы:


1

Вы используете относительную навигацию. Попробуйте с

return "detalle";

вместо

return "ciudades/detalle";

Или вместо этого используйте абсолютную навигацию:

return "/ciudades/detalle";

22.08.2015
  • Но это означает, что я не мог классифицировать свой xhtml по папкам, например, что произойдет, если у меня есть /ciudades/detalle и /paises/detalle? 25.08.2015
  • @BalusC, не могли бы вы выступить посредником в этом вопросе? Оскар Кальдерон, я дал вам ответ на ваш вопрос. Вы отклоняете его на основании дополнительного реквизита, в любом случае я рассмотрел этот реквизит в последней строке или вместо этого используйте абсолютную навигацию.. 25.08.2015
  • Извините @lametaweb, я не понял, когда вы говорили об абсолютной навигации, вы говорили о добавлении косой черты. 25.08.2015
  • Спасибо. Я завершил свой ответ, показав абсолютный путь. 25.08.2015

  • 2

    Наконец, я кое-что попробовал: я не установил параметр JSF «PROJECT_STAGE» в моем файле web.xml, поэтому я установил его в режиме разработки:

    <context-param>
            <param-name>javax.faces.PROJECT_STAGE</param-name>
            <param-value>Development</param-value>
    </context-param>
    

    После этого я попробовал еще раз, и я получил эту ошибку:

    09:58:58,487 WARNING [javax.enterprise.resource.webcontainer.jsf.application] (default task-21) JSF1064: Unable to find or serve resource, /ciudades/ciudades/detalle.xhtml.
    

    Проблема в том, что я использовал относительный путь. В первый раз при переходе с index.xhtml на ciudades/lista.xhtml все работало без проблем, потому что я был в корневом пути (http:localhost:8094/SistemaFutJsf), но после этого, когда я пытался перейти на ciudades/ detalle.xhtml, контекст приложения был таким (http:localhost:8094/SistemaFutJsf/ciudades), из-за чего не удалось найти /ciudades/ciudades/detalle.xhtml.

    Итак, решение состояло в том, чтобы добавить косую черту (/), чтобы сделать пути абсолютными, например:

    public String cargarCiudades() {
            setCities(ciudadDAO.cargarCiudades());
            return "/ciudades/lista";
        }
    
        public String cargar() {
            Ciudad flt = new Ciudad();
            flt.setId(getIdCity());
            setInstance(ciudadDAO.cargarDetalle(flt));
            if(getInstance() == null)
                setInstance(new Ciudad());
            return "/ciudades/detalle";
        }
    
    25.08.2015
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..