24.05.30 15:26 작성
·
76
0
안녕하세요. 스프링부트와 리액트를 이용해 웹앱을 만들고 있는데요, mariadb를 연결해서 회원가입 정보를 저장하려고 하는데 저장이 안 됩니다. 잘 아시는 분들 코드 한번만 봐주실 수 있을까요?
인터넷과 GPT 모두 이용해보아도 해결이 안 되네요 너무 간절합니다 ㅠㅠ 부탁드립니다.
package com.dohwaji.model;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
@Entity
@Table(name = "users")
@Data
@AllArgsConstructor
@Builder
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
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;
}
}
package com.dohwaji.service;
import com.dohwaji.model.User;
import com.dohwaji.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.Optional;
@Service
public class UserService {
@Autowired
private final UserRepository userRepository;
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User registerUser(User user) {
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
return userRepository.save(user);
}
public User authenticate(String username, String password) {
Optional<User> optionalUser = userRepository.findByUsername(username);
if (optionalUser.isPresent() && bCryptPasswordEncoder.matches(password, optionalUser.get().getPassword())) {
return optionalUser.get();
}
return null;
}
public User createUser(String username, String password) {
User user = new User(username, password);
return userRepository.save(user);
}
}
package com.dohwaji.repository;
import com.dohwaji.model.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username);
}
package com.dohwaji.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.dohwaji.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import com.dohwaji.repository.UserRepository;
import com.dohwaji.model.User;
@RestController // REST API 컨트롤러임
@RequestMapping("/api/auth") // 이 컨트롤러의 기본 URL 경로
public class AuthController {
@Autowired // UserService 클래스의 인스턴스가 주입
private UserService userService; // 사용자 관련 비즈니스 로직을 담당하는 서비스 계층
@PostMapping("/login") // HTTP POST 요청이 /api/auth/login 으로 들어오면 이 메서드가 실행됨
public ResponseEntity<?> login(@RequestBody User loginRequest) { // login()메서드는 사용자 이름과 비밀번호를 받아 UserService의 authenticate()메서드를 호출
User user = userService.authenticate(loginRequest.getUsername(), loginRequest.getPassword());
if (user != null) {
// 토큰 발행 로직 추가 가능
return ResponseEntity.ok(user); // 사용자 인증에 성공하면 사용자 정보를 포함한 HTTP 200 OK 응답을 반환
} else {
return ResponseEntity.status(401).body("Invalid credentials"); // 사용자 인증에 실패하면 HTTP 401 Unauthorized 응답을 반환
}
}
@PostMapping("/register") // HTTP POST 요청이 /api/auth/register 로 들어오면 이 메서드가 실행됨
public ResponseEntity<?> register(@RequestBody User registerRequest, HttpServletRequest request) { // register() 메서드는 사용자 정보를 받아 UserService의 registerUser() 메서드를 호출
User user = userService.registerUser(registerRequest);
request.getSession().setAttribute("currentUser", user); // 로그인 된 사용자 정보를 세션에 저장
return ResponseEntity.ok(user); // 회원가입에 성공하면 새로 생성된 사용자 정보를 포함한 HTTP 200 OK 응답을 반환
}
@GetMapping("/logout")
public String logout(HttpServletRequest request) {
request.getSession().invalidate(); // 세션 무효화
return "redirect:/"; // 메인 페이지로 리다이렉트
}
}
build.gradle
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.5'
id 'io.spring.dependency-management' version '1.1.4'
}
group = 'com.dohwaji'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.security:spring-security-crypto'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.mariadb.jdbc:mariadb-java-client'
implementation 'jakarta.persistence:jakarta.persistence-api:3.1.0'
}
tasks.named('test') {
useJUnitPlatform()
}
답변 1
0
안녕하세요, 인프런 AI 인턴입니다.
임서하님, 스프링부트와 리액트를 이용해 웹앱에 회원가입 정보를 MariaDB에 저장하는 과정에서 문제가 발생한 것으로 보이네요. 제공해주신 코드와 설정을 기반으로 몇 가지 확인해볼 사항을 말씀드리겠습니다.
데이터베이스 연결 설정 확인: application.properties
또는 application.yml
파일에서 MariaDB 연결 정보(예: spring.datasource.url
, spring.datasource.username
, spring.datasource.password
)가 올바르게 설정되었는지 확인해주세요. 설정이 누락되거나 잘못된 정보가 입력되어 있으면 데이터베이스에 접근할 수 없습니다.
JPA 엔티티와 테이블 매핑: User
클래스에서 @Entity
와 @Table
애노테이션을 사용해 엔티티를 정의하셨는데, MariaDB 내에 users
테이블이 있는지, 그리고 필드가 User
엔티티의 필드와 일치하는지 확인하세요. 엔티티와 데이터베이스 테이블 간의 불일치는 데이터 저장에 실패할 수 있습니다.
트랜잭션 관리: 스프링에서 데이터를 저장할 때 트랜잭션 관리가 중요합니다. UserService
의 registerUser
메소드 등 데이터를 변경하는 로직에 @Transactional
애노테이션을 추가하여 트랜잭션 처리를 해보세요. 트랜잭션이 제대로 처리되지 않으면 데이터베이스에 변화가 반영되지 않을 수 있습니다.
로깅과 디버깅: 스프링 부트 애플리케이션의 application.properties
또는 application.yml
파일에 spring.jpa.show-sql=true
설정을 추가하여 JPA가 실행하는 SQL 문을 콘솔에서 확인할 수 있습니다. 이를 통해 실제 수행되는 SQL 쿼리를 확인하고 문제를 진단해보세요.
예외 처리와 로그 찍기: UserRepository.save()
호출 시 발생할 수 있는 예외를 적절히 처리하고, 로그를 찍어서 어떤 문제로 데이터가 저장되지 않는지 확인해보세요.
위 사항들을 하나씩 점검해보시면 문제의 원인을 찾고 해결하는 데 도움이 될 것입니다. 만약 여전히 문제를 해결하기 어렵다면, 보다 구체적인 오류 메시지나 로그 내용과 함께 다시 문의해주세요.