JSF, составной компонент: вызов метода со значением атрибута по умолчанию в качестве параметра
Я новичок в JSF и все еще учусь. Я попытался найти решение моей конкретной проблемы, описанной ниже, но ничего не смог найти. Если это потому, что я искал неправильные вещи, пожалуйста, направьте меня в правильном направлении, но, надеюсь, это то, что не было ответом, и ответ может принести пользу всем.
Следующий пример иллюстрирует проблему, с которой я столкнулся. Пример упрощен, чтобы сосредоточиться на проблеме и скрыть сложности фактического проект, в котором возникла проблема.Рассмотрим следующие страницы / классы:
- / resources / test / custom.xhtml;
- / test / CharsetProvider.java;
- /тест / CharsetHello.java;
- / testWith.xhtml;
- / 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 ответ:
Эта проблема имеет точно такую же основу, как и эта проблема: FacesConverter forClass не работает с составным компонентом. Составной тип значения атрибута в Mojarra неверно оценивается как
java.lang.Object
вместо фактического типа модели.Это было сообщено как Мохарра выпуск 2568. Он работает в MyFaces 2.1.9.