JavaFX学生注册应用出现NumberFormatException错误求助
JavaFX学生数据库注册应用NumberFormatException问题排查与解决
点击Register按钮时触发异常,错误根源为NumberFormatException: For input string: "",即空字符串无法转换为Integer类型。
错误信息
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException at javafx.fxml@19-ea/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1857) at javafx.fxml@19-ea/javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1724) at javafx.base@19-ea/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86) at javafx.base@19-ea/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234) at javafx.base@19-ea/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) at javafx.base@19-ea/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) at javafx.base@19-ea/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) at javafx.base@19-ea/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base@19-ea/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at javafx.base@19-ea/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base@19-ea/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at javafx.base@19-ea/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base@19-ea/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at javafx.base@19-ea/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49) at javafx.base@19-ea/javafx.event.Event.fireEvent(Event.java:198) at javafx.graphics@19-ea/javafx.scene.Node.fireEvent(Node.java:8797) at javafx.controls@19-ea/javafx.scene.control.Button.fire(Button.java:203) at javafx.controls@19-ea/com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:208) at javafx.controls@19-ea/com.sun.javafx.scene.control.inputmap.InputMap.handle(InputMap.java:274) at javafx.base@19-ea/com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:247) at javafx.base@19-ea/com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80) at javafx.base@19-ea/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:234) at javafx.base@19-ea/com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) at javafx.base@19-ea/com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) at javafx.base@19-ea/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) at javafx.base@19-ea/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base@19-ea/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at javafx.base@19-ea/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base@19-ea/com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) at javafx.base@19-ea/com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) at javafx.base@19-ea/com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) at javafx.base@19-ea/com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54) at javafx.base@19-ea/javafx.event.Event.fireEvent(Event.java:198) at javafx.graphics@19-ea/javafx.scene.Scene$MouseHandler.process(Scene.java:3881) at javafx.graphics@19-ea/javafx.scene.Scene.processMouseEvent(Scene.java:1874) at javafx.graphics@19-ea/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2607) at javafx.graphics@19-ea/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:411) at javafx.graphics@19-ea/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:301) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at javafx.graphics@19-ea/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:450) at javafx.graphics@19-ea/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:424) at javafx.graphics@19-ea/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:449) at javafx.graphics@19-ea/com.sun.glass.ui.View.handleMouseEvent(View.java:551) at javafx.graphics@19-ea/com.sun.glass.ui.View.notifyMouse(View.java:937) at javafx.graphics@19-ea/com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at javafx.graphics@19-ea/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184) at java.base/java.lang.Thread.run(Thread.java:1589) Caused by: java.lang.reflect.InvocationTargetException at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:119) at java.base/java.lang.reflect.Method.invoke(Method.java:578) at com.sun.javafx.reflect.Trampoline.invoke(MethodUtil.java:77) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) at java.base/java.lang.reflect.Method.invoke(Method.java:578) at javafx.base@19-ea/com.sun.javafx.reflect.MethodUtil.invoke(MethodUtil.java:275) at javafx.fxml@19-ea/com.sun.javafx.fxml.MethodHelper.invoke(MethodHelper.java:84) at javafx.fxml@19-ea/javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1852) ... 46 more Caused by: java.lang.NumberFormatException: For input string: "" at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67) at java.base/java.lang.Integer.parseInt(Integer.java:675) at java.base/java.lang.Integer.valueOf(Integer.java:992) at com.example.studentdatabase/com.example.studentdatabase.Register.register(Register.java:99) at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104) ... 53 more
问题分析
从代码片段可以看到,错误出在register方法的执行顺序:先清空了所有输入文本框,再尝试读取空文本框的内容转换为Integer来拼接SQL语句,自然触发空字符串转Integer的异常。
原问题代码片段:
public void register(ActionEvent event){ if(hasFirstName && hasLastName && hasAge && hasGrade){ studentID++; warning.setText("Registration Completed!"); warning.setVisible(true); // 此处清空文本框 firstNameTF.setText(""); lastNameTF.setText(""); ageTF.setText(""); GradeTF.setText(""); // ...重置其他状态 // 此处使用已清空的文本框内容转Integer String registerString = "INSERT INTO student_data(student_id,first_name,last_name,age,grade) VALUES('"+studentID+"','"+firstNameTF.getText()+"','"+lastNameTF.getText()+"','"+Integer.valueOf(ageTF.getText())+"','"+Integer.valueOf(GradeTF.getText())+"')"; try{ Statement statement = connection.createStatement(); statement.executeUpdate(registerString); }catch(Exception e){ e.printStackTrace(); e.getCause(); } }else{ warning.setText("Fields are Empty!"); warning.setVisible(true); } }
解决方案
- 先获取输入框的内容并存储到变量中,确保使用的是用户输入的有效数据
- 使用
PreparedStatement拼接SQL,避免SQL注入风险和字符串拼接错误 - 执行数据库操作成功后,再清空输入框和重置UI状态
修复后的代码:
public void register(ActionEvent event){ if(hasFirstName && hasLastName && hasAge && hasGrade){ studentID++; // 先获取用户输入的有效数据,trim()去除前后空格 String firstName = firstNameTF.getText().trim(); String lastName = lastNameTF.getText().trim(); int age = Integer.valueOf(ageTF.getText().trim()); int grade = Integer.valueOf(GradeTF.getText().trim()); // 使用PreparedStatement防止SQL注入 String registerString = "INSERT INTO student_data(student_id,first_name,last_name,age,grade) VALUES(?,?,?,?,?)"; try{ PreparedStatement statement = connection.prepareStatement(registerString); statement.setInt(1, studentID); statement.setString(2, firstName); statement.setString(3, lastName); statement.setInt(4, age); statement.setInt(5, grade); statement.executeUpdate(); // 数据库操作成功后更新UI并清空输入框 warning.setText("Registration Completed!"); warning.setVisible(true); firstNameTF.setText(""); lastNameTF.setText(""); ageTF.setText(""); GradeTF.setText(""); // ...重置其他状态 }catch(Exception e){ e.printStackTrace(); warning.setText("Registration Failed!"); warning.setVisible(true); } }else{ warning.setText("Fields are Empty!"); warning.setVisible(true); } }
额外建议
- 对输入框内容增加前置校验,比如判断年龄、年级是否为有效数字,提前拦截非法输入
- 始终使用
PreparedStatement代替直接拼接SQL字符串,彻底避免SQL注入风险
内容的提问来源于stack exchange,提问作者Dinira Francisco
相关产品推荐
相关产品推荐

