我使用JSF / Primefaces创建表单以允许用户输入数据。我已经定义了一个通用类Input
来允许访问数据(因为不同的字段有不同的类型)。但是,当我尝试从声明为Input<Double>
的对象中检索数据时,我得到了异常
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double
我对于为什么会发生这种情况感到有些困惑,因为Input
中存储的值应该是Double?如果有人能指出我正确的方向,我会非常感激。
FormBean.java
@ManagedBean(name="form", eager=true)
@SessionScoped
public class FormBean {
private Input<String> name = new Input<>();
private Input<Date> date = new Input<>();
private Input<Double> hours = new Input<>();
private Input<Double> amount = new Input<>();
public void submit(){
System.out.println(name.getValue());
System.out.println(parseDate(date.getValue(),"dd/MM/yy"));
System.out.println(formatDouble(hours.getValue()));
System.out.println(formatDouble(amount.getValue()));
}
public static String parseDate(Date date, String format){
if(date == null) return "";
DateFormat df = new SimpleDateFormat(format);
return df.format(date);
}
public static String formatDouble(Double d){
if(d==null) return "";
else return String.format("%.2f", (double)d);
}
//-------------------GETTERS AND SETTERS----------------------------
public Input<String> getName() {
return name;
}
public Input<Date> getDate() {
return date;
}
public Input<Double> getHours() {
return hours;
}
public Input<Double> getAmount() {
return amount;
}
}
Input.java
public class Input<T> {
private T value;
private String styleClass = "inputdefault";
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public String getStyleClass() {
return styleClass;
}
public void setStyleClass(String styleClass) {
this.styleClass = styleClass;
}
}
form.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"
xmlns:p="http://primefaces.org/ui">
<h:head>
<ui:define name="title">Form</ui:define>
</h:head>
<h:body>
<h:form id="form">
<p:panelGrid id="formGrid" style="text-align:center;margin:20px;" columns="2" layout="grid">
<h:outputText class="output" value="Name"/>
<p:inputText id="name" class="#{form.name.styleClass}" value="#{form.name.value}"/>
<h:outputText class="output" value="Date:"/>
<p:calendar class="#{form.date.styleClass}" value="#{form.date.value}" pattern="dd/MM/yy"/>
<h:outputText class="output" value="Hours:"/>
<p:inputNumber id="hours" class="#{form.hours.styleClass}" value="#{form.hours.value}" decimalPlaces="2"/>
<h:outputText class="output" value="Amount:"/>
<p:inputNumber class="#{form.amount.styleClass}" value="#{form.amount.value}" decimalPlaces="2"/>
</p:panelGrid>
<p:commandButton value="Submit" update="@form" action="#{form.submit}" class="left"/>
</h:form>
</h:body>
</html>
错误发生在FormBean.java中submit()
方法的第13行:System.out.println(formatDouble(amount.getValue()));
如果需要任何其他信息,请告知我们。 谢谢!
编辑:添加了Stacktrace:
Jun 12, 2017 1:10:55 PM com.sun.faces.lifecycle.InvokeApplicationPhase execute
WARNING: #{form.submit}: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double
javax.faces.FacesException: #{form.submit}: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: javax.faces.el.EvaluationException: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
... 26 more
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double
at FormBean.submit(FormBean.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.el.parser.AstValue.invoke(AstValue.java:278)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
... 27 more
Jun 12, 2017 1:10:55 PM com.sun.faces.context.AjaxExceptionHandlerImpl handlePartialResponseError
SEVERE: javax.faces.el.EvaluationException: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:101)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double
at FormBean.submit(FormBean.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.apache.el.parser.AstValue.invoke(AstValue.java:278)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87)
... 27 more
答案 0 :(得分:0)
我认为在代码的和平中找不到问题。 在您期望异常的时候,bean只是第一次访问bean属性。 JSF正在尝试调用Input.setValue(Double double),但是从jsf控件中传出的值是一个字符串。所以我认为这里会抛出异常。
确保plz发布异常的堆栈跟踪。
该问题的解决方案是为您的控件配置值转换器。
另一个解决方案是将原始值作为字符串存储在输入类中,并在调用方法获取转换后的值(而不是getter-method)时将其转换为目标类型