JSF ViewParams не передается

Я обнаружил, что параметры просмотра не будут передаваться со страницы, где на целевой странице используется другой компонент поддержки. Как я могу передать параметр продукта из test1.xhtml в test2.xhtml?

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

<body>
    <f:metadata>
        <o:viewParam name="product" value="#{holder.value}"
            converter="#{productConverter}"
            converterMessage="Bad request. Unknown product." required="true"
            requiredMessage="Bad request. Please use a link from within the system." />
    </f:metadata>
    <h:link outcome="/test2.xhtml" includeViewParams="true">link</h:link>

</body>
</html>

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

<h:head></h:head>
<body>
    <f:metadata>
        <o:viewParam name="product" value="#{holder2.value}"
            converter="#{productConverter}"
            converterMessage="Bad request. Unknown product." required="true"
            requiredMessage="Bad request. Please use a link from within the system." />
    </f:metadata>
    <h:link outcome="/test.xhtml" includeViewParams="true">link</h:link>
</body>
</html>

Держатель.java

@ManagedBean
@ViewScoped
public class Holder<T> implements Serializable {
    private T value;

    public T getValue() {
        return value;
    }

    public void setValue(T value) {
        this.value = value;
    }


}

Держатель2.java

@ManagedBean
@ViewScoped
public class Holder2<T> implements Serializable {
    private T value;

    public T getValue() {
        return value;
    }

    public void setValue(T value) {
        this.value = value;
    }


}

Продукт.java

public class Product {

    private String name;

    public Product(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }



}

Конвертер продуктов

public class ProductConverter implements Converter {

        private Map<String,Product> productMap=new HashMap<String, Product>();

        public ProductConverter(List<Product> products) {
            for (Product product:products){
                productMap.put(product.getName().toLowerCase(), product);
            }
        }

        @Override
        public Object getAsObject(FacesContext context, UIComponent component, String value) {
            return productMap.get(value.toLowerCase());
        }

        @Override
        public String getAsString(FacesContext context, UIComponent component, Object value) {
              if (!(value instanceof Product) ) {
                    return null;
                }

                return ((Product) value).getName().toLowerCase();
        }





    }

person DD.    schedule 27.12.2012    source источник


Ответы (2)


<h:link outcome="/test2.xhtml?includeViewParams=true">link</h:link>

Это неправильный способ разрешить JSF включать параметры представления в файл <h:link>. Предоставление его в качестве параметра строки запроса допустимо только в атрибуте action компонентов UICommand.

Вам нужен атрибут includeViewParams для <h:link>< /a> вместо этого.

<h:link outcome="/test2.xhtml" includeViewParams="true">link</h:link>
person BalusC    schedule 27.12.2012
comment
Я изменил свой вопрос, чтобы отразить ваши предложения, но все еще имею ту же проблему. - person DD.; 27.12.2012
comment
Какая реализация/версия JSF? Обратите внимание, что он включается только в том случае, если целевое представление также имеет те параметры представления, которые объявлены в метаданных. Итак, основываясь на ваших фрагментах кода, опубликованных до сих пор, это уже должно быть хорошо. - person BalusC; 27.12.2012
comment
Извините, я не могу воспроизвести вашу проблему на Mojarra 2.1.13 с опубликованным кодом. Не слишком ли вы упростили? Вы уверены, что getAsString() преобразователя не сломан? - person BalusC; 27.12.2012
comment
Я включил все классы без каких-либо упрощений. - person DD.; 28.12.2012
comment
Как конвертер регистрируется/создается? Его конструктор, принимающий List<Product>, вообще не будет использоваться JSF. - person BalusC; 28.12.2012
comment
Зарегистрировался с помощью Spring ... конвертер, кажется, работает нормально везде. - person DD.; 28.12.2012
comment
Я смог воспроизвести вашу проблему. Совершенно неожиданно он включает параметр вида из модели целевого вида, а не из модели текущего вида. Если бы вы использовали #{holder.value} в обоих представлениях (как я сделал во время моего первоначального теста, извините за это), то это сработало бы. Если вам действительно нужны 2 отдельных bean-компонента с одинаковым значением, вам следует использовать <f:param name="product" value="#{holder.value.name}"> в ссылке. Я пока не публикую это как ответ, потому что такое поведение слишком похоже на ошибку в Мохарре. Я должен буду исследовать это завтра или в эти выходные. - person BalusC; 28.12.2012

@ViewScoped действителен только для обратных передач — если вы измените URL-адрес, bean-компонент умрет.

Для передачи параметров между фейслетами используйте <ui:param>

person 8bitjunkie    schedule 27.12.2012
comment
Хотя ваше утверждение верно, это не совсем причина конкретной проблемы OP. OP пытается автоматически включить параметры просмотра в URL-адрес ссылки. Кроме того, <ui:param> заслуживает совершенно другой цели, это передача параметров между Facelets (в рамках одного запроса/композиции!), вы, вероятно, хотели предложить <f:param> передавать параметры между запросами. - person BalusC; 27.12.2012
comment
Разве использование <f:param> не просто ответ? - person djmj; 28.12.2012