스프링 부트 기초 - 6(회원가입, 로그인 구현)

3 minute read

예외 처리

@ControllerAdvice	// Exception이 발생했을 때 이쪽으로 들어오게 하기 위해
@RestController
public class GlobalExceptionHandler {

	@ExceptionHandler(value = IllegalArgumentException.class)
	public String handleArgumentException(IllegalArgumentException e) {
		return "<h1>" + e.getMessage() +"</h1>" ;
	}
}


회원가입

▶ joinForm

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
  <!-- header import -->
  <!-- user에서 한칸 올라가야 찾을  있음 -->
  <%@ include file="../layout/header.jsp"%>

  <div class="container">
    <form class="mt-3">
      <div class="form-group">
        <label for="username mt-3">Username</label>
        <input type="text" class="form-control" id="username" aria-describedby="emailHelp" placeholder="Enter username">
      </div>
      <div class="form-group mt-3">
        <label for="password">Password</label>
        <input type="password" class="form-control" id="password" placeholder="password">
      </div>
      <div class="form-group mt-3">
        <label for="Email">Email</label>
        <input type="email" class="form-control" id="email" aria-describedby="emailHelp" placeholder="Enter email">
      </div>
      <!-- <div class="form-group form-check">
      <input type="checkbox" class="form-check-input" id="exampleCheck1"> <label class="form-check-label" for="exampleCheck1">Check me out</label>
    </div> -->
    </form>
    <button type="button" class="btn btn-primary mt-3" id="btn-save">회원가입완료</button>
  </div>

  <script src="/js/user.js">
  </script>

  <!-- footer import -->
  <!-- user에서 한칸 올라가야 찾을 수 있음 -->
  <%@ include file="../layout/footer.jsp"%>
</body>
</html>
  • header와 footer를 분리해서 include를 활용해서 페이지로 가져온다
  • button을 누르고 아래의 script를 통해서 자바스크립트가 실행이 된다



▶ user.js

let index = {
	init: function() {
		$("#btn-save").on("click", () => {
			this.save();
		})
	},

	save: function() {
    //alert("user의 save 함수 호출됨");
    let data = {
			username : $("#username").val(),
			password : $("#password").val(),
			email : $("#email").val(),
		}
	}
}

index.init();



▶ UserApiController

@RestController
public class UserApiController {

	@PostMapping(value = "/api/user")
	public ResponseDto<Integer> save(@RequestBody User user) {
		System.out.println("UserApiController 호출");
		return new ResponseDto<Integer>(HttpStatus.OK,1);
	}
}

@RequestBody → JSON 데이터를 받기 위해 @RequestParam 대신 사용

@RequestBody 와 @RequestParam은 데이터를 받기 위한 방법이다.

@RequestParam같은 경우 url을 통해서 쿼리 스트링으로 오는 값을 읽어들 일 때 사용된다. 반면

@RequestBody 같은 경우 body에 데이터를 담아서 보내온 값을 읽어들 일 때 사용된다. JSON 데이털르 보내기 위해선 body에 데이터를 담아 보내기에 @RequestBody 를 사용해야 한다.

  @RequestBody @RequestParam
객체 생성 가능 불가능
각 변수별로 데이터 저장 불가능 가능



전통적인 로그인

▶ loginForm.jsp

<div class="container">
  <form class="mt-3">
    <div class="form-group">
      <label for="username mt-3">Username</label>
      <input type="text" class="form-control" id="username" placeholder="Enter username">
    </div>
    <div class="form-group mt-3">
      <label for="password">Password</label>
      <input type="password" class="form-control" id="password" placeholder="Enter password">
    </div>
  </form>
  <button type="button" class="btn btn-primary mt-3" id="btn-login">로그인</button>
</div>

<script src="/js/user.js"></script>

username과 password를 입력하고 클릭을 누르게 되고 , 아래의 script가 순차적으로 작동



▶ user.js

let index = {
	init: function() {
		$("#btn-login").on("click", () => {
			this.login();
		});
	},

  login: function() {
      //alert("user의 save 함수 호출됨");
      let data = {
		username : $("#username").val(),
		password : $("#password").val(),
	}

	$.ajax({
		type : "POST",
		url : "/api/user/login",
		data : JSON.stringify(data), 	// 자바에서 처리 하기 위해서 json으로 변경
		contentType : "application/json; charset=utf-8",
		dataType : "json"
	}).done(function(resp) {
		alert("로그인이 완료되었습니다.");
		console.log(resp);
		location.href = "/"
	}).fail(function(error) {
		alert(JSON.stringify(error));
	});	// ajax 통신을 이용해서 3개의 데이터를 json으로 변경하여 insert 요청
  }
}

index.init();

id가 btn-login인 버튼을 클릭시 login 함수 실행

▶ UserApiController

@PostMapping(value = "/api/user/login")
public ResponseDto<Integer> login(@RequestBody User user, HttpSession session) {
	System.out.println("UserApiController:login 호출됨");
	User principal = userService.로그인(user); // principal(접근주체)

	if(principal != null) {
		System.out.println("로그인 성공");
		session.setAttribute("principal", principal);// 세션 만들기
	}
	return new ResponseDto<Integer>(HttpStatus.OK.value(),1);
}

로그인 form에서 입력한 username과 password가 들어오고, service 호출



▶ UserApiController

@Service
public class UserService {

	@Autowired
	private UserRepository userRepository;

	@Transactional(readOnly = true) // select 할 때 트랜잭션 시작, 서비스 종료시에 트랜잭션 종료(정합성)
	public User 로그인(User user) {
		System.out.println("Service 들어옴");
		return userRepository.findByUsernameAndPassword(user.getUsername(), user.getPassword());
	}
}

userRepository를 호출하는데 findByUsernameAndPassword라는 함수를 만들어서 사용 여기서 Username과 Password는 각각 user.getUsername(), user.getPassword() 값들이 들어간다.



▶ UserRepository

public interface UserRepository extends JpaRepository<User, Integer>{	// User라는 클래스, Integer는 User의 primary key의 타입
	// JPA Naming 쿼리 전략
	// select * from user where username = ? and password = ?; 식의 쿼리로 변경되버림 ?에는 username과 password값으 들어감
	User findByUsernameAndPassword(String username, String password);

	// 위와 같다
	//@Query(value ="select * from user where username = ? and password = ?", nativeQuery = true)
	//User login(String username, String password);
}

findByUsernameAndPassword를 이용했다. 이는 JPA에서 제공하는 findBy를 이용한 것이고 뒤의 Username And Password에서 Username과 Password는 db의 컬럼명과 일치해야한다. findBy로 시작을 하면 쿼리를 요청하는 메서드를 알리는 것이다.

findBy를 사용할 때는 카멜케이스 방식으로 사용한다.

1.png

📑 출처

Categories:

Updated:

Leave a comment