public Optional<Member> findByLoginId(String loginId){
/* List<Member> all = findAll();
for (Member m : all) {
if(m.getLoginId().equals(loginId)){
return Optional.of(m);
}
}
return Optional.empty(); */
return findAll().stream()
.filter(m -> m.getLoginId().equals(loginId))
.findFirst();
}
store.values() 하면 value인 member가 리스트로 변환이 됨
못찾을 수 있으니까 Member를 Optional로 반환한다.
Optional이란건 Optional 이라는 통이 있는거.
이 Optional 안에 회원 객체가 있을 수도 있고 없을 수도 있다.
값이 없으면 null을 직접 반환하는게 아니라 Optional.empty();로 찾아서 반환한다.
findAll().stream() : 리스트를 스트림으로 바꿈 (루프를 돈다고 생각하면 됨)
.filter(m -> m.getLoginId().equals(loginId))
이 조건에 만족하는 애만 다음 단계로 넘어감
만족하지 않는 애는 버려짐
.findFirst();
먼저 나오는 애를 받아다가 반환
자바8에 나오는 람다와 스트림은 기본으로 쓸 수 있어야 한다.
로그인 했는데 이게 맞냐 틀리냐 확인할 수 있는 핵심 로직이 필요하다.
@Service (스프링 빈으로 등록해준다)
Optional.get 하면 안에 있는게 꺼내져 나온다.
public Member login(String loginId, String password){
Optional<Member> findMemberOptional = memberRepository.findByLoginId(loginId);
Member member = findMemberOptional.get();
if (member.getPassword().equals((password))) {
return member;
}else{
return null;
}
.
.
.
V
return Optional<Member> byLoginId = memberRepository.findByLoginId(loginId);
byLoginId.filter(m -> m.getPassword().equals(password))
.orElse(null);
reject()는 글로벌 오류이다.
서버에서 로그인 성공처리 로직에서 쿠키를 생성해서 클라이언트에게 전달해줘야한다. 그럼 웹브라우저가 쿠키 저장소에 쿠키를 넣어둔다.
Htttp응답에서 보낼 때 response에 넣어서 보내줘야 한다.
그래서 HttpServletResponse가 필요하다
redirect 하면 requestHeader에 쿠키 값이 들어있는 것을 확인 가능
@CookieValue(name="memberId",required = false) Long memberId
cookie값은 String이지만 스프링이 자동으로 타입 컨버팅 해줌
쿠키 값은 클라이언트에서 서버로 보내는것이기 때문에 위변조가 가능하다
ctrl + alt + c : 상수로 만듦
shift+F6 : 이름 변경
ctrl + shift + 엔터 : code Complete
Arrays.stream() : 배열을 stream으로 바꿔준다
stream이라는건 루프를 하나씩 도는 거다.
findFirst() : 순서가 중요. 순서 중 하나를 찾는거
findAny():순서와 상관없이 찾아지면 하나 반환
//세션 생성
HttpServletResponse response = new MockHttpServletResponse();
Member member = new Member();
sessionManager.createSession(member, response);
이 부분에서 세션 생성해서 response까지 담긴것. 웹 브라우저에 응답이 나갔다고 가정하면 됨
MockHttpServletResponse으로 해줘야 response.getCookies();가 가능!
세션메니저 사용해야하기 때문에 주입 받자.
sessionManager는 @Component되어 있기 때문에 들어온다~
homeLoginV2에선 쿠키 받는걸 빼야한다
SessionConst는
상수만 갖다 쓸거기 때문에
new할 수 없게 abstract class 나 interface로 만든다
세션은 메모리를 쓰는 것이므로 꼭 필요할 때만 생성해야한다.
Member loginMember = (Member) session.getAttribute(SessionConst.LOGIN_MEMBER);
세션 담을때 loginMember 타입이 Member이므로 타입 캐스팅을 해야함.
? 세션 : 브라우저 껐다 키면 깔끔하게 지워짐
스프링이 제공해주는 거 사용하기~
?
@SessionAttribute(name = SessionConst.LOGIN_MEMBER,required = false) Member member
LOGIN_MEMBER 여기에 있는거 뒤져서 member에 값을 넣어준다?
정리
서블릿의 HttpSession 이 제공하는 타임아웃 기능 덕분에 세션을 안전하고 편리하게 사용할 수 있다. 실무에서 주의할 점은 세션에는 최소한의 데이터만 보관해야 한다는 점이다. 보관한 데이터 용량 * 사용자 수로 세션의 메모리 사용량이 급격하게 늘어나서 장애로 이어질 수 있다. 추가로 세션의 시간을 너무 길게 가져가면 메모리 사용이 계속 누적 될 수 있으므로 적당한 시간을 선택하는 것이 필요하다. 기본이 30분이라는 것을 기준으로 고민하면 된다.
예제에서는 멤버 객체를 그대로 담았지만
실무에서는 memberId만 담는 등, 폼 객체를 만들거나 해서 최신의 데이터만 보관한다.