Java注册功能案例怎么实现

wen java案例 24

本文目录导读:

Java注册功能案例怎么实现

  1. 后端实现(Spring Boot)
  2. 前端实现(HTML + JavaScript)
  3. application.yml配置
  4. 依赖配置
  5. 测试用例

我来为您介绍一个完整的Java注册功能实现案例,包含前后端交互。

后端实现(Spring Boot)

实体类

// User.java
package com.example.demo.entity;
import javax.persistence.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(unique = true, nullable = false)
    private String username;
    @Column(nullable = false)
    private String password;
    private String email;
    private String phone;
    @Column(name = "create_time")
    private LocalDateTime createTime;
    // getters and setters
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    public String getPassword() { return password; }
    public void setPassword(String password) { this.password = password; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    public String getPhone() { return phone; }
    public void setPhone(String phone) { this.phone = phone; }
    public LocalDateTime getCreateTime() { return createTime; }
    public void setCreateTime(LocalDateTime createTime) { this.createTime = createTime; }
}

DTO(数据传输对象)

// RegisterRequest.java
package com.example.demo.dto;
import javax.validation.constraints.*;
public class RegisterRequest {
    @NotBlank(message = "用户名不能为空")
    @Size(min = 3, max = 20, message = "用户名长度3-20个字符")
    @Pattern(regexp = "^[a-zA-Z0-9_]+$", message = "用户名只能包含字母、数字和下划线")
    private String username;
    @NotBlank(message = "密码不能为空")
    @Size(min = 6, max = 20, message = "密码长度6-20个字符")
    private String password;
    @Email(message = "邮箱格式不正确")
    private String email;
    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
    private String phone;
    // getters and setters
    public String getUsername() { return username; }
    public void setUsername(String username) { this.username = username; }
    public String getPassword() { return password; }
    public void setPassword(String password) { this.password = password; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    public String getPhone() { return phone; }
    public void setPhone(String phone) { this.phone = phone; }
}

响应类

// ApiResponse.java
package com.example.demo.dto;
public class ApiResponse<T> {
    private int code;
    private String message;
    private T data;
    public ApiResponse(int code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }
    public static <T> ApiResponse<T> success(T data) {
        return new ApiResponse<>(200, "success", data);
    }
    public static <T> ApiResponse<T> error(int code, String message) {
        return new ApiResponse<>(code, message, null);
    }
    // getters
    public int getCode() { return code; }
    public String getMessage() { return message; }
    public T getData() { return data; }
}

Repository层

// UserRepository.java
package com.example.demo.repository;
import com.example.demo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    boolean existsByUsername(String username);
    boolean existsByEmail(String email);
    boolean existsByPhone(String phone);
}

Service层

// UserService.java
package com.example.demo.service;
import com.example.demo.dto.RegisterRequest;
import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private BCryptPasswordEncoder passwordEncoder;
    /**
     * 用户注册
     */
    public User register(RegisterRequest request) {
        // 检查用户名是否已存在
        if (userRepository.existsByUsername(request.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }
        // 检查邮箱是否已存在
        if (request.getEmail() != null && userRepository.existsByEmail(request.getEmail())) {
            throw new RuntimeException("邮箱已被注册");
        }
        // 检查手机号是否已存在
        if (request.getPhone() != null && userRepository.existsByPhone(request.getPhone())) {
            throw new RuntimeException("手机号已被注册");
        }
        // 创建新用户
        User user = new User();
        user.setUsername(request.getUsername());
        user.setPassword(passwordEncoder.encode(request.getPassword())); // 密码加密
        user.setEmail(request.getEmail());
        user.setPhone(request.getPhone());
        user.setCreateTime(LocalDateTime.now());
        return userRepository.save(user);
    }
}

Controller层

// UserController.java
package com.example.demo.controller;
import com.example.demo.dto.ApiResponse;
import com.example.demo.dto.RegisterRequest;
import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@RestController
@RequestMapping("/api/user")
@CrossOrigin(origins = "*") // 允许跨域
public class UserController {
    @Autowired
    private UserService userService;
    @PostMapping("/register")
    public ResponseEntity<ApiResponse<User>> register(@Valid @RequestBody RegisterRequest request) {
        try {
            User user = userService.register(request);
            return ResponseEntity.ok(ApiResponse.success(user));
        } catch (RuntimeException e) {
            return ResponseEntity.badRequest()
                .body(ApiResponse.error(400, e.getMessage()));
        }
    }
}

安全配置

// SecurityConfig.java
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
@Configuration
public class SecurityConfig {
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

前端实现(HTML + JavaScript)

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">用户注册</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            font-family: 'Microsoft YaHei', sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .register-container {
            background: white;
            border-radius: 10px;
            padding: 40px;
            width: 400px;
            box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
        }
        h2 {
            text-align: center;
            color: #333;
            margin-bottom: 30px;
            font-size: 28px;
        }
        .form-group {
            margin-bottom: 20px;
        }
        label {
            display: block;
            margin-bottom: 5px;
            color: #555;
            font-size: 14px;
            font-weight: 500;
        }
        input {
            width: 100%;
            padding: 12px 15px;
            border: 1px solid #ddd;
            border-radius: 5px;
            font-size: 14px;
            transition: border-color 0.3s;
        }
        input:focus {
            outline: none;
            border-color: #667eea;
        }
        input.error {
            border-color: #e74c3c;
        }
        .error-message {
            color: #e74c3c;
            font-size: 12px;
            margin-top: 5px;
            display: none;
        }
        .error-message.show {
            display: block;
        }
        button {
            width: 100%;
            padding: 14px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            border-radius: 5px;
            font-size: 16px;
            font-weight: 600;
            cursor: pointer;
            transition: transform 0.2s;
        }
        button:hover {
            transform: translateY(-2px);
        }
        button:disabled {
            opacity: 0.6;
            cursor: not-allowed;
            transform: none;
        }
        .message {
            margin-top: 20px;
            padding: 10px;
            border-radius: 5px;
            display: none;
        }
        .message.success {
            display: block;
            background: #d4edda;
            color: #155724;
            border: 1px solid #c3e6cb;
        }
        .message.error {
            display: block;
            background: #f8d7da;
            color: #721c24;
            border: 1px solid #f5c6cb;
        }
        .password-strength {
            height: 5px;
            margin-top: 5px;
            border-radius: 3px;
            transition: all 0.3s;
        }
        .password-strength.weak {
            width: 33%;
            background: #e74c3c;
        }
        .password-strength.medium {
            width: 66%;
            background: #f39c12;
        }
        .password-strength.strong {
            width: 100%;
            background: #27ae60;
        }
    </style>
</head>
<body>
    <div class="register-container">
        <h2>用户注册</h2>
        <form id="registerForm">
            <div class="form-group">
                <label for="username">用户名</label>
                <input type="text" id="username" name="username" 
                       placeholder="3-20位字母、数字或下划线" required>
                <div class="error-message" id="usernameError"></div>
            </div>
            <div class="form-group">
                <label for="password">密码</label>
                <input type="password" id="password" name="password" 
                       placeholder="6-20位字符" required>
                <div class="password-strength" id="passwordStrength"></div>
                <div class="error-message" id="passwordError"></div>
            </div>
            <div class="form-group">
                <label for="confirmPassword">确认密码</label>
                <input type="password" id="confirmPassword" name="confirmPassword" 
                       placeholder="再次输入密码" required>
                <div class="error-message" id="confirmPasswordError"></div>
            </div>
            <div class="form-group">
                <label for="email">邮箱</label>
                <input type="email" id="email" name="email" 
                       placeholder="请输入邮箱地址">
                <div class="error-message" id="emailError"></div>
            </div>
            <div class="form-group">
                <label for="phone">手机号</label>
                <input type="tel" id="phone" name="phone" 
                       placeholder="请输入11位手机号">
                <div class="error-message" id="phoneError"></div>
            </div>
            <button type="submit" id="submitBtn">注册</button>
        </form>
        <div class="message" id="message"></div>
    </div>
    <script>
        // 获取DOM元素
        const form = document.getElementById('registerForm');
        const username = document.getElementById('username');
        const password = document.getElementById('password');
        const confirmPassword = document.getElementById('confirmPassword');
        const email = document.getElementById('email');
        const phone = document.getElementById('phone');
        const submitBtn = document.getElementById('submitBtn');
        const message = document.getElementById('message');
        // 实时验证
        username.addEventListener('blur', validateUsername);
        password.addEventListener('input', validatePassword);
        confirmPassword.addEventListener('blur', validateConfirmPassword);
        email.addEventListener('blur', validateEmail);
        phone.addEventListener('blur', validatePhone);
        // 密码强度检测
        password.addEventListener('input', function() {
            const strength = document.getElementById('passwordStrength');
            const value = this.value;
            if (value.length === 0) {
                strength.className = 'password-strength';
                return;
            }
            let score = 0;
            if (value.length >= 6) score++;
            if (value.length >= 10) score++;
            if (/[a-z]/.test(value)) score++;
            if (/[A-Z]/.test(value)) score++;
            if (/[0-9]/.test(value)) score++;
            if (/[^a-zA-Z0-9]/.test(value)) score++;
            if (score <= 2) {
                strength.className = 'password-strength weak';
            } else if (score <= 4) {
                strength.className = 'password-strength medium';
            } else {
                strength.className = 'password-strength strong';
            }
        });
        // 验证用户名
        function validateUsername() {
            const error = document.getElementById('usernameError');
            const value = username.value;
            if (!value) {
                showError(username, error, '用户名不能为空');
                return false;
            }
            if (!/^[a-zA-Z0-9_]{3,20}$/.test(value)) {
                showError(username, error, '用户名格式不正确(3-20位字母、数字或下划线)');
                return false;
            }
            hideError(username, error);
            return true;
        }
        // 验证密码
        function validatePassword() {
            const error = document.getElementById('passwordError');
            const value = password.value;
            if (!value) {
                showError(password, error, '密码不能为空');
                return false;
            }
            if (value.length < 6 || value.length > 20) {
                showError(password, error, '密码长度需在6-20位之间');
                return false;
            }
            hideError(password, error);
            return true;
        }
        // 验证确认密码
        function validateConfirmPassword() {
            const error = document.getElementById('confirmPasswordError');
            const value = confirmPassword.value;
            if (!value) {
                showError(confirmPassword, error, '请确认密码');
                return false;
            }
            if (value !== password.value) {
                showError(confirmPassword, error, '两次密码不一致');
                return false;
            }
            hideError(confirmPassword, error);
            return true;
        }
        // 验证邮箱
        function validateEmail() {
            const error = document.getElementById('emailError');
            const value = email.value;
            if (!value) return true; // 邮箱可选
            if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
                showError(email, error, '邮箱格式不正确');
                return false;
            }
            hideError(email, error);
            return true;
        }
        // 验证手机号
        function validatePhone() {
            const error = document.getElementById('phoneError');
            const value = phone.value;
            if (!value) return true; // 手机号可选
            if (!/^1[3-9]\d{9}$/.test(value)) {
                showError(phone, error, '手机号格式不正确');
                return false;
            }
            hideError(phone, error);
            return true;
        }
        // 显示错误
        function showError(input, errorElement, message) {
            input.classList.add('error');
            errorElement.textContent = message;
            errorElement.classList.add('show');
        }
        // 隐藏错误
        function hideError(input, errorElement) {
            input.classList.remove('error');
            errorElement.textContent = '';
            errorElement.classList.remove('show');
        }
        // 提交表单
        form.addEventListener('submit', async function(e) {
            e.preventDefault();
            // 验证所有字段
            const isUsernameValid = validateUsername();
            const isPasswordValid = validatePassword();
            const isConfirmPasswordValid = validateConfirmPassword();
            const isEmailValid = validateEmail();
            const isPhoneValid = validatePhone();
            if (!isUsernameValid || !isPasswordValid || !isConfirmPasswordValid || 
                !isEmailValid || !isPhoneValid) {
                return;
            }
            // 准备请求数据
            const data = {
                username: username.value,
                password: password.value,
                email: email.value || null,
                phone: phone.value || null
            };
            // 禁用按钮,显示加载状态
            submitBtn.disabled = true;
            submitBtn.textContent = '注册中...';
            message.className = 'message';
            try {
                const response = await fetch('http://localhost:8080/api/user/register', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(data)
                });
                const result = await response.json();
                if (response.ok && result.code === 200) {
                    showMessage('注册成功!正在跳转到登录页面...', 'success');
                    setTimeout(() => {
                        window.location.href = '/login.html';
                    }, 2000);
                } else {
                    showMessage(result.message || '注册失败', 'error');
                }
            } catch (error) {
                showMessage('网络错误,请稍后重试', 'error');
                console.error('注册错误:', error);
            } finally {
                submitBtn.disabled = false;
                submitBtn.textContent = '注册';
            }
        });
        // 显示消息
        function showMessage(text, type) {
            message.textContent = text;
            message.className = `message ${type}`;
            // 3秒后自动隐藏成功消息
            if (type === 'success') {
                setTimeout(() => {
                    message.className = 'message';
                }, 3000);
            }
        }
    </script>
</body>
</html>

application.yml配置

# application.yml
server:
  port: 8080
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/demo?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf-8
    username: root
    password: your_password
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL8Dialect
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: Asia/Shanghai

依赖配置

<!-- pom.xml 关键依赖 -->
<dependencies>
    <!-- Spring Boot Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- Spring Boot JPA -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <!-- MySQL驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <!-- 数据验证 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
    <!-- 密码加密 -->
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-crypto</artifactId>
    </dependency>
</dependencies>

测试用例

// UserServiceTest.java
@SpringBootTest
@AutoConfigureMockMvc
class UserServiceTest {
    @Autowired
    private MockMvc mockMvc;
    @Autowired
    private UserRepository userRepository;
    @BeforeEach
    void setUp() {
        userRepository.deleteAll();
    }
    @Test
    void testRegisterSuccess() throws Exception {
        String requestBody = "{\"username\":\"testuser\",\"password\":\"123456\"," +
                           "\"email\":\"test@example.com\",\"phone\":\"13800138000\"}";
        mockMvc.perform(post("/api/user/register")
                .contentType(MediaType.APPLICATION_JSON)
                .content(requestBody))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.code").value(200));
    }
    @Test
    void testRegisterDuplicateUsername() throws Exception {
        // 先注册一个用户
        User existingUser = new User();
        existingUser.setUsername("testuser");
        existingUser.setPassword("password");
        userRepository.save(existingUser);
        String requestBody = "{\"username\":\"testuser\",\"password\":\"123456\"}";
        mockMvc.perform(post("/api/user/register")
                .contentType(MediaType.APPLICATION_JSON)
                .content(requestBody))
                .andExpect(status().isBadRequest())
                .andExpect(jsonPath("$.message").value("用户名已存在"));
    }
}

这个注册功能案例包括了:

  1. 后端实现

    • 实体类设计
    • 数据验证
    • 密码加密
    • 异常处理
    • RESTful API
  2. 前端实现

    • 表单验证
    • 实时密码强度检测
    • AJAX请求
    • 用户友好的错误提示
  3. 安全考虑

    • 密码加密存储
    • 输入验证
    • 防止SQL注入
    • 跨域配置
  4. 用户体验

    • 实时验证反馈
    • 密码强度指示器
    • 加载状态提示
    • 错误信息友好显示

运行项目后,访问 http://localhost:8080/register.html 即可测试注册功能。

抱歉,评论功能暂时关闭!