[英]Is there a way to get JSF to work with Generic setters and getters
有没有一种方法可以使JSF与通用实体一起使用,如下所述:
Property.java
public interface MyProperty<T> {
void setMyValue(T value);
T getMyValue(T value);
}
在我的应用程序中T
只能是Date
, String
, Integer
或Long
MyObject.java
public class MyObject {
List<MyProperty<?>> properties;
public List<MyProperty<?>> getProperties() {
return properties;
}
}
MyController.java
@Named("controller")
@RequestScoped
public class MyController {
MyObject myObject;
public void setMyObject(MyObject myObject) { this.myObject = myObject; };
public MyObject getMyObject() { return myObject; } ;
}
edit.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head><title></title></h:head><h:body>
<h:form>
<ui:repeat var="property" value="#{controller.myObject.properties}">
<h:inputText value="#{property.myValue}"/>
</ui:repeat>
<h:commandButton action="#{controller.save}" value="save"/>
</h:form>
</h:body>
</html>
不幸的是,这不起作用,因为JSF尝试在myObject上查找带有签名的setter:
void setMyValue(String value);
由于类型擦除导致该方法具有以下签名,因此显然不存在哪种方法:
void setMyValue(Object value);
有什么办法可以解决这个问题?
您的答案尚不清楚,但是答案肯定是 ,JSF可以与泛型一起使用。
但是,这取决于您使用泛型的明智程度,最终取决于您是否确实了解泛型的问题。
据我从您的示例可以看出,您将使用通用接口作为实现类中包含的对象的包装 。
使用这种方法,您不直接处理MyInterface
实现,而是按照接口方法定义的内容处理。
基本接口:
public interface MyInterface<T> {
void setMyValue(T value);
T getMyValue();
}
实施班:
public class MyString implements MyInterface<String> {
private String myValue;
public MyString(String myValue) {
this.myValue = myValue;
}
public void setMyValue(String value) {
this.myValue = value;
}
public String getMyValue() {
return myValue;
}
@Override
public String toString() {
return myValue;
}
}
和
public class MyInteger implements MyInterface<Integer> {
private Integer myValue;
public MyInteger(Integer myValue) {
this.myValue = myValue;
}
public void setMyValue(Integer value) {
this.myValue = value;
}
public Integer getMyValue() {
return myValue;
}
@Override
public String toString() {
return Integer.toString(myValue);
}
}
托管bean(带有匿名类 ):
@ManagedBean
@RequestScoped
public class MyInterfaceBean {
private MyString myString;
private MyInteger myInteger;
private MyInterface<Float> myFloat;
public MyInterfaceBean() {
myString = new MyString("String");
myInteger = new MyInteger(1);
myFloat = new MyInterface<Float>() {
private Float myValue;
public void setMyValue(Float value) {
this.myValue = value;
}
public Float getMyValue() {
return myValue;
}
@Override
public String toString() {
return Float.toString(myValue);
}
};
myFloat.setMyValue(3.1f);
}
public String getMyString() {
return myString.getMyValue();
}
public void setMyString(String myString) {
this.myString.setMyValue(myString);
}
public Integer getMyInteger() {
return myInteger.getMyValue();
}
public void setMyInteger(Integer myInteger) {
this.myInteger.setMyValue(myInteger);
}
public Float getMyFloat() {
return myFloat.getMyValue();
}
public void setMyFloat(Float myFloat) {
this.myFloat.setMyValue(myFloat);
}
public String action() {
return null;
}
}
风景:
<h:outputText value="String: #{myInterfaceBean.myString}"/>
<br/>
<h:outputText value="Integer: #{myInterfaceBean.myInteger}"/>
<br/>
<h:outputText value="Float: #{myInterfaceBean.myFloat}"/>
<br/>
<h:form>
<h:outputText value="String: "/><h:inputText value="#{myInterfaceBean.myString}"/>
<br/>
<h:outputText value="Integer: "/><h:inputText value="#{myInterfaceBean.myInteger}"/>
<br/>
<h:outputText value="Float: "/><h:inputText value="#{myInterfaceBean.myFloat}"/>
<br/>
<h:commandButton value="Submit" action="#{myInterfaceBean.action}"/>
</h:form>
另一种方法是使用@FacesConverter
以便JSF知道如何将输入字段中的字符串转换为实现MyInterface
对象。
托管bean(带有匿名类 ):
@ManagedBean
@RequestScoped
public class MyInterfaceBean {
private MyString myString;
private MyInteger myInteger;
private MyInterface<Float> myFloat;
public MyInterfaceBean() {
myString = new MyString("String");
myInteger = new MyInteger(1);
myFloat = new MyInterface<Float>() {
private Float myValue;
public void setMyValue(Float value) {
this.myValue = value;
}
public Float getMyValue() {
return myValue;
}
@Override
public String toString() {
return Float.toString(myValue);
}
};
myFloat.setMyValue(3.1f);
}
public MyString getMyString() {
return myString;
}
public void setMyString(MyString myString) {
this.myString = myString;
}
public MyInteger getMyInteger() {
return myInteger;
}
public void setMyInteger(MyInteger myInteger) {
this.myInteger = myInteger;
}
public MyInterface<Float> getMyFloat() {
return myFloat;
}
public void setMyFloat(MyInterface<Float> myFloat) {
this.myFloat.setMyValue(myFloat.getMyValue());//not to lose this anonymous class, can substitute for other implementation directly
}
public String action() {
return null;
}
}
转换器:
@FacesConverter(value = "myStringConverter")
public class MyStringConverter implements Converter {
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if(value == null || value.equals("")) {
return null;
}
MyString obj = new MyString(value);
return obj;
}
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (!(value instanceof MyString) || (value == null)) {
return null;
}
return ((MyString)value).getMyValue();
}
}
和
@FacesConverter(value = "myIntegerConverter")
public class MyIntegerConverter implements Converter {
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if(value == null || value.equals("")) {
return null;
}
MyInteger obj = null;
try {
Integer integer = Integer.valueOf(value);
obj = new MyInteger(integer);
} catch(NumberFormatException nfe) {
throw new ConverterException(new FacesMessage("Integer could not be parsed from string: " + value));
}
return obj;
}
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (!(value instanceof MyInteger) || (value == null)) {
return null;
}
return ((MyInteger)value).getMyValue().toString();
}
}
和
@FacesConverter(value = "myFloatConverter")
public class MyFloatConverter implements Converter {
public Object getAsObject(FacesContext context, UIComponent component, String value) {
if(value == null || value.equals("")) {
return null;
}
MyInterface<Float> obj = null;
try {
Float floatValue = Float.valueOf(value);
obj = new MyInterface<Float>() {
private Float myValue;
public void setMyValue(Float value) {
this.myValue = value;
}
public Float getMyValue() {
return myValue;
}
@Override
public String toString() {
return Float.toString(myValue);
}
};
obj.setMyValue(floatValue);
} catch(NumberFormatException nfe) {
throw new ConverterException(new FacesMessage("Float could not be parsed from string: " + value));
}
return obj;
}
public String getAsString(FacesContext context, UIComponent component, Object value) {
if (!(value instanceof MyInterface) || (value == null)) {
if(!(((MyInterface)value).getMyValue() instanceof Float)) {
return null;
}
}
return ((MyInterface)value).getMyValue().toString();
}
}
风景:
<h:outputText value="String: #{myInterfaceBean.myString}"/>
<br/>
<h:outputText value="Integer: #{myInterfaceBean.myInteger}"/>
<br/>
<h:outputText value="Float: #{myInterfaceBean.myFloat}"/>
<br/>
<h:form>
<h:outputText value="String: "/><h:inputText value="#{myInterfaceBean.myString}" converter="myStringConverter"/>
<br/>
<h:outputText value="Integer: "/><h:inputText value="#{myInterfaceBean.myInteger}" converter="myIntegerConverter"/>
<br/>
<h:outputText value="Float: "/><h:inputText value="#{myInterfaceBean.myFloat}" converter="myFloatConverter"/>
<br/>
<h:commandButton value="Submit" action="#{myInterfaceBean.action}"/>
</h:form>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.