1

我将确认代码链接发送到注册用户的电子邮件中,当单击链接时,我需要激活状态以批准会员资格,但我收到标题中显示的错误。一切都是真的,但我不明白为什么会这样。这是我的代码:

1)在此代码部分,用户成为会员,确认代码将发送到他的电子邮件。

@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)在此代码部分,执行用户点击发送到电子邮件的链接后的步骤。因此,如果代码正确,我将验证数据库中用户的状态列。

@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)但问题是当我点击发送到电子邮件的链接时,我收到以下错误。错误 java.time.format.DateTimeParseException: Text '2021-07-24 18:11:33.0' could not be parsed, unparsed text found at index 19

4)这是我与数据库相关的方法。

@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;
    }
4

2 回答 2

0

您必须决定如何处理 resultSet.getString(2) 返回的日期字符串中的“.0”。你可以做一个子字符串来删除它。或者您可以更改格式化字符串以解决它。我选择“.n”表示纳秒,但您必须研究该值的含义。

再想一想,您甚至可能不想使用 resultSet.getString(2)。如果这是来自数据库的内容,您可能需要考虑返回时间戳的 resultSet.getTimestamp(2)。有关如何将其转换为 LocalDateTime 的信息可以在此处找到 如何将 java.sql.timestamp 转换为 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;
}
于 2021-07-24T15:09:20.083 回答
0

您遇到了这个问题,因为您错过了fraction-of-second的模式。您可以使用以下模式:

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

使用方括号将秒的小数部分设为可选

演示:

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);
    }
}

输出:

2021-07-24T18:11:33

ONLINE DEMO

我还建议您将列类型更改为 Date-Time 类型,这将使​​您能够java.time直接使用类型而不是处理String. 检查此答案此答案以了解如何将java.timeAPI 与 JDBC 一起使用。

从Trail: Date Time了解有关现代日期时间 API 的更多信息。

于 2021-07-24T15:13:39.927 回答