我是JSF的新手,仍在學習。我試着尋找解決我下面描述的具體問題的解決方案,但我找不到任何東西。如果因爲我在尋找錯誤的東西,請指出我的方向是正確的,但希望這是一種未被回答的問題,一個答案可以讓每個人都受益。JSF,複合組件:使用默認屬性值作爲參數的方法調用
以下示例說明了我遇到的問題。這個例子被簡化爲專注於這個問題並隱藏出現問題的實際項目的複雜性。
考慮以下頁/類:
- /resources/test/custom.xhtml;
- /test/CharsetProvider.java;
- /test/CharsetHello.java;
- /testWith.xhtml;
- /testWithout.xhtml;
/resources/test/custom.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 bean而不是後臺bean的原因是因爲在我的特定項目中,缺省值需要在運行時注入,但後備bean不適用於注入。
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
這是 「模型」 對象。它只是轉換「Hello world!」到一個字節數組並返回給定的字符集。
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);
}
}
testWith.xhtml
這是使用通過指定的組件屬性的值以上定義的複合部件測試頁。該頁面正確呈現,即「Hello World!」在屏幕上打印。
<?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>
testWithout.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.lang.String該方法。
首先,這是預期的行爲,爲什麼?
如果這是預期的行爲,你可以建議一個不同的實現?
預先感謝您!
我能夠重現它。不知道這是否是特定的行爲,我必須先看規格。我至少沒有直覺地期待它。雖然,對於EL具有內建強制功能的類型(例如'Number','Boolean'和'Enum'(只要您不使用'Integer'將被解釋爲'Long'),它就可以正常工作。 – BalusC