JSF, составной компонент: вызов метода со значением атрибута по умолчанию в качестве параметра


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

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

Рассмотрим следующие страницы / классы:

  1. / resources / test / custom.xhtml;
  2. / test / CharsetProvider.java;
  3. /тест / CharsetHello.java;
  4. / testWith.xhtml;
  5. / testWithout.xhtml;

/ресурсы / тест / заказ.xhtml

Это составной компонент с одним атрибутом со значением по умолчанию. Компонент просто принимает значение атрибута и передает его в качестве аргумента в CDI bean описан ниже, чтобы получить объект модели, используемый для вывода.

<?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:cc="http://java.sun.com/jsf/composite"
      xmlns:h="http://java.sun.com/jsf/html">

    <cc:interface>
        <cc:attribute name="charset"
                      default="#{charsetProvider.defaultCharset}"
                      type="java.nio.charset.Charset" />
    </cc:interface>

    <cc:implementation>
        <h:outputText value="#{charsetProvider.createCharsetHello(cc.attrs.charset).hello}"/>
    </cc:implementation>
</html>

Тест / CharsetProvider.java

Это компонент CDI, который просто содержит значение по умолчанию, используемое во всем приложении, и имеет метод, который создает объект, используемый в качестве модели для компонента. Причина, по которой я использую CDI-Боб вместо резервного Боба, заключается в том, что в моем конкретном проекте значение по умолчанию должно быть введено во время выполнения, но резервные бобы не являются кандидатами для инъекция.

package test;

import java.nio.charset.Charset;
import javax.annotation.PostConstruct;
import javax.faces.bean.SessionScoped;
import javax.inject.Named;

@Named
@SessionScoped
public class CharsetProvider {

    private Charset defaultCharset;

    @PostConstruct
    protected void postConstruct() {
        this.defaultCharset = Charset.forName("UTF-8");
    }

    public Charset getDefaultCharset() {
        return defaultCharset;
    }

    public Charset getCharsetForName(String name) {
        return Charset.forName(name);
    }

    public CharsetHello createCharsetHello(Charset cs) {
        return new CharsetHello(cs);
    }
}

Тест / CharsetHello.java

Это и есть объект "модель". Он просто преобразует "Привет, мир!- в массив байтов и обратно, используя заданную кодировку.
package test;

import java.nio.charset.Charset;

public class CharsetHello {

    private static final String HW = "Hello World!";
    private final byte[] data;
    private final Charset cs;

    public CharsetHello(Charset cs) {
        this.cs = cs;
        this.data = CharsetHello.HW.getBytes(this.cs);
    }

    public String getHello() {
        return new String(this.data, this.cs);
    }
}

Тествит.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://java.sun.com/jsf/html"
      xmlns:test="http://java.sun.com/jsf/composite/test">
    <h:head>
        <title>Test</title>
    </h:head>
    <h:body>
        <test:custom charset="#{charsetProvider.getCharsetForName('UTF-16')}" />
    </h:body>
</html>

Без теста.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://java.sun.com/jsf/html"
      xmlns:test="http://java.sun.com/jsf/composite/test">
    <h:head>
        <title>Test</title>
    </h:head>
    <h:body>
        <test:custom />
    </h:body>
</html>

Страница выше приводит к странице ошибки JSF со следующим сообщением:

/resources/test/custom.xhtml @14,94 value="#{charsetProvider.createCharsetHello(cc.attrs.charset).hello}": Cannot convert UTF-8 of type class java.lang.String to class java.nio.charset.Charset

Похоже, что в последнем случае значение по умолчанию преобразуется в java.яз..Строка перед передачей в метод.

Во-первых, является ли это ожидаемым поведением и почему?

Если это ожидаемое поведение, можете ли вы предложить другое реализация?

Заранее благодарю вас!

1 3

1 ответ:

Эта проблема имеет точно такую же основу, как и эта проблема: FacesConverter forClass не работает с составным компонентом. Составной тип значения атрибута в Mojarra неверно оценивается как java.lang.Object вместо фактического типа модели.

Это было сообщено как Мохарра выпуск 2568. Он работает в MyFaces 2.1.9.