1

I send the confirmation code link to the e-mail of the registered user, and when the link is clicked, I need to activate the status so that the membership is approved, but I get the error I show in the title. Everything is completely true, but I can't understand why this happened. This is my code:

1)In this code section, the user becomes a member and a confirmation code is sent to his e-mail.

@WebServlet(name = "RegisterUserSaveController", urlPatterns = {"/register-user-save"})
public class RegisterUserSaveController extends HttpServlet {
    
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            String name = request.getParameter("name");
            String surname = request.getParameter("surname");
            String email = request.getParameter("email");
            String password = request.getParameter("password");
            String repeatPassword = request.getParameter("password-repeat");
            
            if (!password.equals(repeatPassword)) {
                request.setAttribute("error", "Password repeat is not same!");
                request.getRequestDispatcher("register").forward(request, response);
            } else {
                User user = new User();
                user.setName(name);
                user.setSurname(surname);
                user.setEmail(email);
                user.setPassword(PasswordHasher.hashPassword(password));
                String activationCode = UUID.randomUUID().toString();
                user.setActivationCode(MD5.hashedMd5(activationCode));
                LocalDateTime expiredDate = LocalDateTime.now().plusHours(1);
                user.setExpiredDate(expiredDate);
                UserDaoService userDaoService = new UserDaoManager();
                userDaoService.save(user);
                
                String subject = "Confirm Registration";
                
                String link = "http://localhost:8084/employee/registerconfirm?code=" + activationCode;
                
                String title = "Your confirmation link:\n " + link;
                
                SendEmail.sendAsync(email, title, subject);
                
                request.setAttribute("info2", "Your Registration was successfully! Pls check your email.");
                request.getRequestDispatcher("success-info").forward(request, response);
            }
        } catch (GeneralSecurityException e) {
            
        }

2)In this code section, the steps after the user clicks on the link sent to the e-mail are performed. So if the code is correct, I validate the user's status column in the database.

@WebServlet(name = "RegisterConfirmController", urlPatterns = {"/registerconfirm"})
public class RegisterConfirmController extends HttpServlet {

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String code = request.getParameter("code");
        UserDaoService userDaoService = new UserDaoManager();
        if (code == null) {
            request.setAttribute("info1", "Activation code is not correct!");
            request.getRequestDispatcher("error-info").forward(request, response);
        } else {
            code = MD5.hashedMd5(code);

            User user = userDaoService.findByActivationCode(code);

            if (user == null) {
                request.setAttribute("info1", "Activation code is not correct!");
                request.getRequestDispatcher("error-info").forward(request, response);
            } else {
                LocalDateTime expiredDate = user.getExpiredDate();
                LocalDateTime currentDate = LocalDateTime.now();

                if (expiredDate.isBefore(currentDate)) {
                    request.setAttribute("info1", "Activation code is expired!");
                    request.setAttribute("info2", "resend?id=" + user.getId() + "");
                    request.getRequestDispatcher("error-info").forward(request, response);

                } else if (user.getStatus() == UserStatusEnum.CONFIRMED.getValue()) {

                    request.setAttribute("info1", "Your account already confirmed!");
                    request.getRequestDispatcher("error-info").forward(request, response);

                } else {

                    userDaoService.updateStatusById(user.getId(), UserStatusEnum.CONFIRMED);
                    request.setAttribute("info2", "Your account is confirmed!");
                    request.getRequestDispatcher("success-info").forward(request, response);

                }

            }
        }
    }

3)But the problem is that when I click on the link sent to the e-mail, I get the following error. error java.time.format.DateTimeParseException: Text '2021-07-24 18:11:33.0' could not be parsed, unparsed text found at index 19

4)And this is my method in relation to the database.

@Override
    public User findByActivationCode(String activationCode) {
        try (Connection connection = DbConnection.getConnection()) {
            PreparedStatement preparedStatement = connection.prepareStatement("select id,expired_date,status from users where activation_code=?");
            preparedStatement.setString(1, activationCode);
            ResultSet resultSet = preparedStatement.executeQuery();
            if (resultSet.next()) {
                User user = new User();
                user.setId(resultSet.getInt(1));
                user.setExpiredDate(LocalDateTime.parse(resultSet.getString(2), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                user.setStatus(resultSet.getInt(3));
                return user;
            }
        } catch (Exception e) {
            System.out.println("findByActivationCode error " + e);
        }
        return null;
    }
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
justdoit
  • 47
  • 1
  • 8

2 Answers2

0

You will have to decide what to do with the ".0" in the date String returned by resultSet.getString(2). You could do a substring to remove it. Or you could change the formatting string to account for it. I chose ".n" for nanoseconds, but you would have to research what the value means.

Thinking about it a little more, you may not even want to be using resultSet.getString(2). If this is something coming out of the database, you may want to consider resultSet.getTimestamp(2) which returns a Timestamp. Information on how to convert it to LocalDateTime can be found here How to convert java.sql.timestamp to LocalDate (java8) java.time?

public static void main(String[] args)
{
  String text = "2021-07-24 18:11:33.0";
  //
  String text1 = text.substring(0,19);
  LocalDateTime ldt = LocalDateTime.parse(text1, 
  DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
  //
  LocalDateTime ldt2 = LocalDateTime.parse(text, 
  DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.n"));

  int ai = 0;
}
ProgrammersBlock
  • 5,974
  • 4
  • 17
  • 21
0

You faced the problem because you have missed the pattern for the fraction-of-second. You can use the following pattern:

u-M-d H:m:s[.[SSSSSSSSS][SSSSSSSS][SSSSSSS][SSSSSS][SSSSS][SSSS][SSS][SS][S]]

where fraction-of-second has been made optional using the square bracket.

Demo:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern(
                "u-M-d H:m:s[.[SSSSSSSSS][SSSSSSSS][SSSSSSS][SSSSSS][SSSSS][SSSS][SSS][SS][S]]", Locale.ENGLISH);
        String strDateTime = "2021-07-24 18:11:33.0";
        LocalDateTime ldt = LocalDateTime.parse(strDateTime, dtf);
        System.out.println(ldt);
    }
}

Output:

2021-07-24T18:11:33

ONLINE DEMO

I also suggest you change the column type to a Date-Time type which will enable you to use java.time types directly instead of dealing with String. Check this answer and this answer to learn how to use java.time API with JDBC.

Learn more about the modern Date-Time API from Trail: Date Time.

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110