java中生成随机no的问题

java中生成随机no的问题,java,jsp,jdbc,Java,Jsp,Jdbc,我已经编写了这样的代码,但它给出了异常。实际上我想生成一个随机值。保存到数据库中,并将其返回给用户 import java.math.BigInteger; import java.security.SecureRandom; public static String recoverpassword(String uid,String ans) { try { verifyans.setString(1,uid); verifyans.setString

我已经编写了这样的代码,但它给出了异常。实际上我想生成一个随机值。保存到数据库中,并将其返回给用户

import java.math.BigInteger;
import java.security.SecureRandom;

public static String recoverpassword(String uid,String ans) {
    try {
        verifyans.setString(1,uid);
        verifyans.setString(2,ans);
        ResultSet resultSet = verifyans.executeQuery();

        if (resultSet.next()) {
            SecureRandom random = new SecureRandom();
            String newpass = new BigInteger(130, random).toString(32);
            resetpass.setString(1,newpass);
            resetpass.setString(2,uid);
            resetpass.executeUpdate();                          
            return newpass;
        } else {
            return "xxx";
        }

    } catch(Exception e) {
        System.out.println("exception" +e);
        e.printStackTrace();
        return "xxx";
    }
}

我遇到了空指针异常,如:

com.ibm.lims.Users@1d193c9]
exceptionjava.lang.NullPointerException
java.lang.NullPointerException
    at org.tranql.connector.jdbc.ConnectionHandle.connectionError(ConnectionHandle.java:103)
    at org.tranql.connector.jdbc.PreparedStatementHandle.executeUpdate(PreparedStatementHandle.java:105)
    at com.ibm.lims.LimsHandler.recoverpassword(LimsHandler.java:940)
    at org.apache.jsp.recoverpasswordresult_jsp._jspService(recoverpasswordresult_jsp.java:78)
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
    at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:369)
    at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
    at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:806)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.geronimo.tomcat.valve.DefaultSubjectValve.invoke(DefaultSubjectValve.java:56)
    at org.apache.geronimo.tomcat.GeronimoStandardContext$SystemMethodValve.invoke(GeronimoStandardContext.java:406)
    at org.apache.geronimo.tomcat.valve.GeronimoBeforeAfterValve.invoke(GeronimoBeforeAfterValve.java:47)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:567)
    at org.apache.geronimo.tomcat.valve.ThreadCleanerValve.invoke(ThreadCleanerValve.java:40)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
    at java.lang.Thread.run(Unknown Source)

嘿,我测试了删除那些securerandom类调用的代码。我只是用双引号传递了一个字符串值,比如“sample”,它就成功了。表示securerandom类存在问题。我认为该值在字符串值字段中是一个整数,因此数据库服务器正在发送异常。请给我一些代码,或者生成随机字符串–

您是否尝试过使用调试器单步执行此操作

从发布的代码来看,可能uid在方法顶部以null形式传入


您也不应该在数据库中以纯文本形式存储密码,您应该使用密码的盐单向散列。

您遇到的问题与随机生成的数字无关。您可以查看您的数据库连接参数,在您试图执行的sql请求中。。。但请更具体地说,“我正在获得NPE”不是一个问题:)

这里有几个问题在起作用

首先是NPE的根本原因:

java.lang.NullPointerException
    at org.tranql.connector.jdbc.ConnectionHandle.connectionError(ConnectionHandle.java:103)
这显然是TranQL JDBC驱动程序中的一个错误。
ConnectionHandle#connectionError()
方法期间出现了一些意外的空指针,因此无法处理实际的连接错误。要解决这个特定的问题(这样您就不会得到一个NPE,而是一个更清晰、更特定于驱动程序的
SQLException
),要么升级驱动程序,要么用一个更合适的驱动程序替换它(我以前从未听说过TranQL)

至于整个问题的真正原因;从stacktrace判断,似乎没有活动连接。从非线程安全代码判断,preparedStatement似乎以前已经使用过,并且以某种方式隐式关闭/分离了连接

至少它可以明确地归结为非线程安全和非资源泄漏安全的JDBC代码。正常的JDBC习惯用法是,您应该始终在尽可能短的范围内获取并关闭
连接
准备语句
结果集
。因此,已经在非常相同的(非静态!)方法块中。语句和结果集不应在线程之间共享。这种联系是可以的,但你不应该把它掌握在自己手中。为此,请使用合适的连接池API,例如C3P0

下面是一个符合理想JDBC习惯用法的示例:

public String recoverPassword(Long userId, String answer) throws SQLException {
    Connection connection = null;
    PreparedStatement verifyAnswer = null;
    ResultSet resultSet = null;
    String newPassword = null;
    PreparedStatement resetPassword = null;

    try {
        connection = database.getConnection();
        verifyAnswer = connection.prepareStatement(SQL_VERIFY_ANSWER);
        verifyAnswer.setLong(1, userId);
        verifyAnswer.setString(2, answer);
        resultSet = statement.executeQuery();

        if (resultSet.next()) {
            SecureRandom random = new SecureRandom();
            newPassword = new BigInteger(130, random).toString(32);
            resetPassword = connection.prepareStatement(SQL_RESET_PASSWORD);
            resetPassword.setString(1, newPassword);
            resetPassword.setLong(2, userId);
            resetPassword.executeUpdate();                          
        }
    } finally {
        // Always free resources in reversed order.
        if (resetPassword != null) try { resetPassword.close(); } catch (SQLException logOrIgnore) {}
        if (resultSet != null) try { resultSet.close(); } catch (SQLException logOrIgnore) {}
        if (verifyAnswer != null) try { verifyAnswer.close(); } catch (SQLException logOrIgnore) {}
        if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
    }

    return newPassword;
}
注意,我暗示了
用户id
长的
。您确实不希望在代码和数据模型中都有
String
ID。您可以找到有关编写可靠JDBC代码的更多信息、提示和其他示例

也就是说,stacktrace的以下部分

at com.ibm.lims.LimsHandler.recoverpassword(LimsHandler.java:940)
at org.apache.jsp.recoverpasswordresult_jsp._jspService(recoverpasswordresult_jsp.java:78)

这意味着您正在使用老式的scriptlet在JSP文件中编写原始Java代码。为了避免将来的维护和调试问题,我强烈建议您不要这样做,只需使用Servlet类即可。

您忘了告诉异常。顺便说一下,我不确定这是否“只是”一个伪示例,但您发布的JDBC代码肯定不是线程安全和资源泄漏安全的。它可能会导致问题,如果没有关于异常/跟踪的信息,很难判断。问题是什么?请说得更具体一些。我得到了空指针异常。我为那个NPE打开了一个问题:嘿,我测试了删除那些securerandom类调用的代码。我刚刚用双引号传递了一个字符串值,如“sample”,它成功了。表示securerandom类存在问题。我认为该值在字符串值字段中是一个整数,因此数据库服务器正在发送异常。请给我一些代码来生成随机字符串。对不起,先生。我正在创建连接。我正在调用另一个类进行连接,另一个类用于创建该连接的实例。问题在于安全随机类,但异常并不能说明这一点。这也不是JDBC代码工作正常的借口。您已经声明了连接和语句
static
。如果您在测试环境中单独工作,它将起作用,但在多用户环境中这确实是一个大问题。另外,很明显,您正在使用
ResultSet#setString()
作为新密码,因此它实际上是整数还是字符串并不重要。此外,从跟踪来看,你在IBM工作?你那边没有导师吗?我真的会咨询他们,让他们检查你的代码。