페이지 관련 이전 블로그를 참고하면 된다.
insert into user_tb(username, password, email, created_at) values('ssar', '1234', 'ssar@nate.com', now()); insert into user_tb(username, password, email, created_at) values('cos', '1234', 'cos@nate.com', now());
resources/DB/data.sql 폴더를 만들었다. 이 더미데이터를 활용하기 위해 application-dev.yml 에 코드를 추가한다.
sql: init: data-locations: - classpath:db/data.sql
해당 폴더를 실행하면 입력한 쿼리문이 자동으로 입력된다.
1. 로그인 오류 수정
만약 동일한 유저네임을 가입하게 된다면 이런 오류가 발생한다.
이것을 잡기 위해서 두 가지 방법이 있다.
(1) try-catch 사용
@PostMapping("/join") public String login(UserRequest.JoinDTO requsetDTO){ if(requsetDTO.getUsername().length()<3){ return "error/400"; } try{ userRepository.save(requsetDTO); return "redirect:/loginForm"; }catch (Exception e) { return "error/400"; } }
(2) 트랜잭션 활용
@Transactional @PostMapping("/join") public String join(UserRequest.JoinDTO requsetDTO){ if(requsetDTO.getUsername().length()<3){ return "error/400"; } User user = userRepository.findByUsername(requsetDTO.getUsername()); if(user == null){ userRepository.save(requsetDTO) ; // 위임 }else { return "error/400"; } return"redirect:/loginForm"; }
유효성 검사와 레포지토리를 하나의 트랜잭션으로 묶는다.
회원가입을 할 때 여러 사람이 중복된 아이디를 입력하게 되면 DB 에서 오류가 발생할 수 있기 때문에 트랜잭션을 걸어 한 명의 클라이언트가 DB와 통신할 때 다른 클라이언트는 락을 걸어 고립성을 유지한다.
try-catch 보다 트랜잭션을 활용한다.
public User findByUsername(String username) { Query query = em.createNativeQuery("select * from user_tb where username=?",User.class); //User.class 알아서 맵핑.@Entity가 있어야됨 ResultSet해서 하나씩 파싱 안해도 됨. query.setParameter(1,username); // getSingleResult는 내부적으로 트라이캐치가 구현되어 있음. 내가 원하는 트라이캐치를 원하면 내가 새로 만들면 됨 // 내부적으로 터지면 터지는 위치를 내가 찾아서 트라이캐치해야 됨/ // 터지는 위치를 찾고 싶다면 system.out.print(1) 이런 식으로 번호를 넣어서 어디서 터지는지 찾아야됨. try{ User user = (User) query.getSingleResult(); // getSingleResult()의 리턴값이 오브젝트라 다운캐스팅 return user ; }catch(Exception e){ return null ; } }
userRepository 에 username 이 있는지 확인하는 메서드를 만든다.
2. 로그아웃
@GetMapping("/logout") public String logout() { session.invalidate(); // 로그아웃. 서랍의 내용을 다 삭제 // 깃 테스트 코드 return "redirect:/"; // 깃테스트 }
session.invalidate 는 세션을 무효화 하는 코드이다. 세션을 무효화하면 해당 세션과 관련된 데이터와 상태가 모두 삭제되어 더 이상 유효하지 않다.
server: servlet: encoding: charset: utf-8 force: true session: timeout: 30m port: 8080
applocation-dev.yml 에서 session: timeout 을 사용할 수 있다. 이를 사용하면 정해진 시간 동안 세션에 아무 요청이 없다면 연결을 종료하는 코드이다.
로그아웃이 된다. 세션에 접근한 기록이 있기 때문에 브라우저에 쿠키는 저장된다.
하지만 이후에 다시 로그인을 하게 되면 새로운 쿠키를 부여받는다.
Share article