java.lang.String 在使用泛型时不能强制转换为 java.lang.Double



我正在使用JSF/Primefaces创建一个表单来允许用户输入数据。我定义了一个泛型类Input以允许访问数据(因为不同的字段具有不同的类型(。但是,当我尝试从声明为 Input<Double> 的对象中检索数据时,我收到异常 java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Double

我有点困惑为什么会发生这种情况,因为存储在Input中的值应该是双精度值?如果有人能指出我正确的方向,导致这种情况的原因,我将不胜感激。

憨豆.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;
    }
}

输入.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;
    }
}

形式.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 中 submit() 方法的第 13 行.java:System.out.println(formatDouble(amount.getValue()));

如果需要任何其他信息,请告诉我。谢谢!

编辑:添加了堆栈跟踪:

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

我认为问题无法在代码的和平中找到。在您预期异常时,Bean 只是第一次访问 Bean 属性。JSF 正在尝试调用 Input.setValue(Double double(,但从 jsf 控件中产生的值是一个字符串。所以我认为这里抛出了例外。

为了确保安全,请发布异常的堆栈跟踪。

该问题的解决方案是为控件配置值转换器。

http://download.oracle.com/otn_hosted_doc/jdeveloper/j2ee101302/jsf_apps/eventvalidate/sf_avc_converters.html

另一种解决方案是将原始值存储为输入类中的字符串,并在调用方法以获取转换后的值(而不是 getter-method(时将其转换为目标类型

相关内容

最新更新