在java中生成随机数的问题

时间:2010-01-07 11:40:12

标签: java jsp jdbc

我已经写了这样的代码,但是它给出了例外。实际上我想生成一个随机的value.save到数据库并将其返回给用户

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类call.i的代码,只是在双引号中传递一个字符串值,如“sample”,并且它有效。表示问题在于securerandom类。我认为值在字符串值字段中以整数形式出现,因此数据库服务器正在发送异常。 plz给我一些代码来生成随机字符串 -

3 个答案:

答案 0 :(得分:1)

在这里发挥作用有几个问题。

首先是NPE的根本原因:

java.lang.NullPointerException
    at org.tranql.connector.jdbc.ConnectionHandle.connectionError(ConnectionHandle.java:103)

这显然是TranQL JDBC驱动程序中的一个错误。在ConnectionHandle#connectionError()方法期间有一些意外的空指针,因此它无法处理实际的连接错误。要解决这个特定的问题(这样你就不会得到一个NPE,而是一个更清晰且特定于驱动程序的SQLException),要么升级驱动程序,要么用更合适的替换它(我从未听说过) TranQL之前)。

关于整个问题的真正原因;从堆栈跟踪判断,看起来没有活动连接的方法。从非线程安全代码判断,看起来之前已经使用过preparedStatement,并且以某种方式隐式地从连接中关闭/分离。

至少它可以归结为你所拥有的非线程安全和非资源漏洞安全的JDBC代码。正常的JDBC习惯用法是,您应始终获取关闭最短范围中的ConnectionPreparedStatementResultSet。因此,已经在同一个(非静态!)方法块内部。永远不应在线程之间共享语句和结果集。连接可以,但你不应该自己动手。为此使用合适的连接池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;
}

请注意,我暗示userIdLong。您真的不希望在代码和数据模型中都有String ID。您可以找到有关编写可靠JDBC代码here的更多信息,提示和其他示例。

那说,堆栈跟踪的以下部分

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

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

答案 1 :(得分:0)

您是否尝试使用调试程序逐步完成此操作?

从发布的代码看起来似乎uid在方法的顶部传入as null。

您也不应该将密码作为纯文本存储在数据库中,而应该使用密码的盐渍单向散列。

答案 2 :(得分:0)

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