Spring TIL - 커뮤니티 로그인, 로그아웃

Jieun·2023년 4월 25일
0

📝 커뮤니티 로그인, 로그아웃 기능 공부 후 자습
#230425

💻 작업파일

[src/main/java] - [edu.kh.comm.member.dao] - MemberDAO.java
[src/main/java] - [edu.kh.comm.member.controller] - MemberController.java
[src/main/java] - [edu.kh.comm.main.controller] - MainController.java (신규)

[src/main/resources] - [mappers] - member-mapper.xml
[src/main/resources] - mybatis-config.xml

[src]-[main]-[webapp]-[WEB-INF]-[views]-[common] - footer.jsp (수정)
[src]-[main]-[webapp]-[WEB-INF]-[views]-[common] - main.jsp (기존 index.jsp)
[src]-[main]-[webapp]- index.jsp (신규)

📌 앞에 1.2번은 230424 스프링 공부내용정리 하단 참고

3. 1행 조회 (파라미터가 VO)인 경우


mapper에서 파라미터로 VO가 전달된 경우

1) 패키지명 + 클래스명을 모두 작성해야 한다.
2) mapper에서 VO에 저장된 값을 얻어와 사용할 경우 #{필드명}을 사용한다.

단, VO에 반드시 Getter가 작성되어 있어야 한다.

<< memberDAO >>

// 1행 조회 (파라미터가 VO인 경우)
String memberTel = sqlSession.selectOne("memberMapper.test3", inputMember);
							
                         inputMember에 저장된 값 : memberEmail, memberPw

디비버가서 테이블 복제 후 설정해주기
mapper 가서 sql문 써주기

<<  member-mapper.xml >>
<!-- 
	조회되는 행의 개수 : 1행
	파라미터 타입 : edu.kh.comm.member.model.vo.Member  (패키지명+클래스명)
	조회되는 타입 : java.lang.String -> string
-->	

<!--sql문 조건 : 
	아이디, 비밀번호가 일치하는 회원의 전화번호 조회 / 단, 정상회원만-->
<select id="test3" parameterType="edu.kh.comm.member.model.vo.Member" resultType="string">
	SELECT MEMBER_TEL FROM MEMBER_S
	WHERE MEMBER_EMAIL = #{memberEmail}
	AND MEMBER_PW = #{memberPw}
	AND SECESSION_FL = 'N'
</select>

typeAliases : 별칭 작성 부분

mybatis-config.xml내에서
VO클래스의 패키지명 + 클래스명 모두 작성하는 것이 불편하기 때문에 짧은 별칭 부여

➡️ vo로 객체 불러 올 때마다 매번 parameterType을 길게 쓰기엔 너무 비효율적이여서...

<< mybatis-config.xml >>

<typeAliases>
	<typeAlias type="edu.kh.comm.member.model.vo.Member" alias="member"/>
</typeAliases>

--------------------------------------------------------------------------------------
<< member-mappter.xml >>

<!-- <select id="test3" parameterType="edu.kh.comm.member.model.vo.Member"
						resultType="string"> -->
<select id="test3" parameterType="member" resultType="string">
	SELECT MEMBER_TEL FROM MEMBER_S
	WHERE MEMBER_EMAIL = #{memberEmail}
	AND MEMBER_PW = #{memberPw}
	AND SECESSION_FL = 'N'
</select>

4. 1행 조회 (파라미터가 VO, 반환되는 결과도 VO)인 경우

resultType에 VO를 작성하는 경우 : resultMap[1]

사용

VO의 필드명과 조회되는 컬럼명이 일치하면 자동으로 VO객체에 값이 세팅된다.
하지만 java와 DB의 표기법 차이로 인해서 위 특징이 적용되는 경우가 많지 않다
그래서 필드명, 컬럼명이 달라도 이를 연결시켜줄 수 있는 resultMap 태그를 제공

resultMap은 최상단에 입력해준다!

ex)
java표기법 / db표기법
memberNo / MEMBER_NO


<< Member.DAO >>

Member loginMember = sqlSession.selectOne("memberMapper.login", inputMember);
		
return loginMember;

<< member-mappter.xml >>

<!-- 로그인 -->
	
<!--
조회되는 행의 개수 : 1행  
파라미터 타입 : edu.kh.comm.member.model.vo.Member -> member (사용자 정의)
조회되는 타입 : edu.kh.comm.member.model.vo.Member -> member (사용자 정의)
				
resultMap="member_rm" -> 조회 결과를 member_rm을 이용하여 비교해서 VO에 세팅         
-->
<select id="login" parameterType="member" resultMap="member_rm">
	SELECT MEMBER_NO,MEMBER_EMAIL,MEMBER_NICK ,MEMBER_TEL,
    MEMBER_ADDR, PROFILE_IMG, 
    TO_CHAR( ENROLL_DT, 'YYYY-MM-DD HH24:MI:SS') AS ENROLL_DT
	FROM MEMBER_S
	WHERE MEMBER_EMAIL = #{memberEmail}
	AND MEMBER_PW = #{memberPw}
	AND SECESSION_FL = 'N'
</select>

resultMap 태그[1]

SELECT 조회 결과(ResultSet)의 컬럼과
조회결과를 옮겨 담을 VO의 필드명이 일치하지 않을 때

이를 매핑시켜 조회결과가 필드에 세팅되게 하는 역할

[resultMap 속성]
1) type : 조회결과를 담을 VO의 타입 또는 별칭
2) id : 만들어진 resultMap 태그를 지칭할 이름(식별명)

[resultMap 내부 작성 태그]
: PK 역할의 컬럼 - 필드 연결
: PK을 제외한 나머지 컬럼 - 필드 연결

💻 태그 및 속성 자동완성 설정값 : ctrl + space


<< member-mappter.xml >>
  
 <mapper namespace="memberMapper">
   
   resultMap은 최상단에 입력하기 때문에 namespace 바로 아래 입력해준다!
  
	
	<resultMap type="member" id="member_rm">
	 	
      <id property="memberNo" column="MEMBER_NO"/>

      <result property="memberEmail" 		column="MEMBER_EMAIL"/>
      <result property="memberPw" 		column="MEMBER_PW"/>
      <result property="memberNickname" 	column="MEMBER_NICK"/>
      <result property="memberTel" 		column="MEMBER_TEL"/>
      <result property="memberAddress" 	column="MEMBER_ADDR"/>
      <result property="profileImage" 	column="PROFILE_IMG"/>
      <result property="enrollDate" 		column="ENROLL_DT"/>
      <result property="secessionFlag" 	column="SECESSION_FL"/>
	</resultMap>

디버그로 서버 돌린 후, 로그인 하면 아래처럼 뜸!!!!
그럼 성공😊😊😊

현재의 로그인 기능 흐름


📌📌📌📌📌📌

@ModelAttribute

생략된 상태에서 파라미터가 필드에 세팅된 객체

Model ;

데이터를 맵 형식(K:V) 형태로 담아 전달하는 용도의 객체
➡️ request, session을 대체하는 객체

  • 기본 scope : request
  • session scope로 변환하고 싶은 경우, 클래스 레벨로 @SessionAttributes를 작성하면 된다.

@SessionAttributes 미작성 ➡️ request scope

로그인


@SessionAttributes({"loginMember"}) // 자바 배열형태 {}로 넣기
public class MemberControler { 
   
   ......  중략
   
----------------------------------------------------------------   
@PostMapping("/login")
public String login( /*@ModelAttribute */ Member inputMember, Model model) {
   
   logger.info("로그인 기능 수행됨")
   // 아이디, 비밀번호가 일치하는 회원정보를 조회하는 Service 호출 후 결과 반환 받기
   Member loginMember = service.login(inputMember);
   
   // ==req.setAttribute("loginMember, loginMember);
   model.addAttribute("loginMember", loginMember);
 
   return "redirect:/"; 

서버돌리면 이렇게 세션 저장되면서 로그인됨

로그아웃 해보기

   
@GetMapping("/logout")
public String logout( /* HttpSession session */
							SessionStatus status ) {
		
	// 로그아웃 == 세션을 없애는 것
	
	// * @SessionAttributes을 이용해서 session scope에 배치된 데이터는
	//   SessionStatus라는 별도 객체를 이용해야만 없앨 수 있다.
	logger.info("로그아웃 수행됨");
		
	//session.invalidate(); // 기존 세션 무효화 방식으로는 안된다!
	status.setComplete(); // 세션이 할 일이 완료됨 -> 없앰
		
	return "redirect:/";
}
  • index.jsp 내용 복사해서 main.jsp 만들기

  • index.jsp 내용수정하기

<< index.jsp >> 
   
 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

 <jsp:forward page="main" />
 
  • footer 수정 session 부분 없애기. 수정하면 아래 내용처럼!

  • mainController 클래스 만들어서 내용 작성 후 서버 돌리면 움직임
   
<< MainController >> 
   
@Controller
public class MainController {

	@RequestMapping("/main")
	public String mainForward() {
		
		return "common/main";
		
	}   
  • 로그인하고 쿠키 만들기

flashAttribute 사용하려면 해당 request내용을 redirect에 담아서
MainController를 통해 main으로 갔다가 main 하단에 footer로 가서
request에 message 속성에서 잠깐 머물렀다가 사라짐


// 로그인 
@PostMapping("/login")
public String login( /*@ModelAttribute */ Member inputMember, 
					Model model,
					RedirectAttributes ra,
					HttpServletResponse resp,
					HttpServletRequest req,
					@RequestParam(value="saveId", required=false) String saveId ) {
	
	// 커맨드 객체
	// @ModelAttribute 생략된 상태에서 파라미터가 필드에 세팅된 객체
	
	logger.info("로그인 기능 수행됨");
		
	// 아이디, 비밀번호가 일치하는 회원 정보를 조회하는 Service 호출 후 결과 반환 받기
	Member loginMember = service.login(inputMember);
		
		
	/* Model : 데이터를 맵 형식(K:V) 형태로 담아 전달하는 용도의 객체
	 * -> request, session을 대체하는 객체
	 * 
	 * - 기본 scope : request
	 * - session scope로 변환하고 싶은 경우
	 *   클래스 레벨로 @SessionAttributes를 작성하면 된다.
	 *   
	 *   @SessionAttributes 미작성 -> request scope
	 * 
	 * */
	 if ( loginMember != null) { // 로그인 성공시
	   	  model.addAttribute("loginMember", loginMember);  
          // ==req.setAttribute("loginMember", loginMember);	
	    	  
	    	// 로그인 성공시 무조건 쿠키 생성
	    	// 단, 아이디 저장 체크 여부에 따라서 쿠키의 유지시간을 조정
	    	  
	    	Cookie cookie = new Cookie("saveId", loginMember.getMemberEmail());
	    	 
	    	if (saveId != null ) { // 아이디 저장이 체크되어있을 때	
		    	  cookie.setMaxAge(60 * 60 * 24 * 365); // 초단위 지정(1년    		  
	    	
            } else { // 체크되지 않았을 때	  
	    		  cookie.setMaxAge(0); // 0초 -> 생성되자마자 사라짐 == 쿠키삭제
	    	}
	    	  
	    	// 쿠키가 적용될 범위(경로) 지정
	    	cookie.setPath(req.getContextPath());   // /comm 안에서 모두 쿠키 적용하겠다는 말
	    	  
	    	// 쿠키를 응답 시 클라이언트에게 전달
	    	resp.addCookie(cookie);
	    	  
	    } else {
	    	// model.addAttribute("message", "아이디 또는 비밀번호가 일치하지 않습니다.");
	    	
	    	ra.addFlashAttribute("message", "아이디 또는 비밀번호가 일치하지 않습니다.");
	    	
	    	// redirect 시에도 request scope로 세팅된 데이터가 유지될 수 있도록 하는 방법을
	    	// Spring 에서 제공해줌
	    	// RedirectAttributes객체 (컨트롤러 매개변수에 작성하면 사용 가능)
	    }
		
		return "redirect:/"; 
	}
    
    
    //로그아웃
	@GetMapping("/logout")
	public String logout(/*HttpSession session*/
						SessionStatus status ) {
		// 로그아웃 == 세션을 없애는 것
		
		// * @SessionAttributes을 이용해서 session scope에 배치된 데이터는
		//   SessionStatus라는 별도 객체를 이용해야만 없앨 수 있다.
		
		logger.info("로그아웃 수행됨");
		
		// session.invalidate(); 기존 세션 무효화 방식으로는 X
		
		status.setComplete(); // 세션이 할 일이 완료됨 -> 없앰
		
		return "redirect:/";  // 메인페이지 재요청
	} 
profile
👩‍💼👩‍💼➡️➡️➡️👩‍💻👩‍💻 생산자의 삶을 살기 위해 개발공부중

0개의 댓글