проблема генерации случайного нет в Java - PullRequest
0 голосов
/ 07 января 2010

Я написал такой код, но он дает исключения. На самом деле я хочу сгенерировать случайное значение. Сохранить в базе данных и вернуть его пользователю

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. Я думаю, что значение в поле строкового значения представляет собой целое число, поэтому сервер базы данных отправляет исключение. Пожалуйста, дайте мне код для генерации случайной строки в качестве альтернативы -

Ответы [ 3 ]

1 голос
/ 07 января 2010

Здесь есть несколько проблем, которые играют роль.

Первая причина NPE:

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

Это явно ошибка в драйвере TranQL JDBC. Во время метода ConnectionHandle#connectionError() произошел неожиданный нулевой указатель, поэтому он не смог обработать фактическую ошибку соединения. Чтобы исправить эту конкретную проблему (чтобы у вас не было NPE, но есть более понятный и специфичный для драйвера SQLException), либо обновите драйвер, либо замените его более подходящим (я никогда раньше не слышал о TranQL) ).

Что касается истинной причины всей проблемы; Судя по трассировке стека, похоже, что нет активного соединения. Судя по не поточнобезопасному коду, похоже, что подготовленное состояние уже использовалось ранее и каким-то образом неявно было закрыто / отсоединено от соединения.

По крайней мере, он явно сводится к тому, что у вас есть не-потокобезопасный и небезопасный код JDBC. Обычная идиома JDBC заключается в том, что вы всегда должны получить и , чтобы закрыть Connection, PreparedStatement и ResultSet в кратчайшей области действия . Таким образом, уже внутри того же (нестатического!) Метода блока. Утверждение и набор результатов никогда не должны быть разделены между потоками. Связь может быть, но вы не должны брать ее в свои руки. Используйте для этого приличный 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;
}

Обратите внимание, что я намекнул userId на Long. Вы действительно не хотите, чтобы в вашем коде и модели данных были String идентификаторы. Вы можете найти более подробную информацию, советы и другие примеры написания твердого кода JDBC здесь .

Тем не менее, следующая часть стека трассировки

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

подразумевает, что вы пишете необработанный код Java в файле JSP с использованием старомодных скриптлетов. Чтобы избежать будущих проблем с обслуживанием и отладкой, я настоятельно рекомендую вам не делать этого, а просто использовать для этого класс Servlet.

0 голосов
/ 07 января 2010

Ваша проблема не связана со случайным геном числа. Вы могли бы взглянуть на параметры соединения с БД, на запрос sql, который вы пытаетесь выполнить, ... Но, пожалуйста, будьте более конкретны: "Я получаю NPE", это не вопрос:)

0 голосов
/ 07 января 2010

Вы пробовали пройти через это с помощью отладчика?

Судя по опубликованному коду, похоже, что uid передается как null в верхней части метода.

Вы также не должны хранить пароли в виде простого текста в базе данных, вместо этого вы должны использовать соленый односторонний хэш пароля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...