1cm

자바 프로그래밍_Day_108_로그인, 로그아웃, 회원가입 구현 본문

국비지원_Java/Java Programming_2

자바 프로그래밍_Day_108_로그인, 로그아웃, 회원가입 구현

dev_1cm 2022. 2. 18. 16:50
반응형

2022. 01. 18

 

 

 

 

bean 내의 driverClassName="oracle~~" 대신 ${db.driver} 식으로 불러올 수 있게 placeholder로 위치를 설정해준다.

 

 

-> root-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

	<!-- Root Context: defines shared resources visible to all other web components -->
	
	<context:property-placeholder location="classpath:driver.properties"/>
	
	<import resource="mybatis-context.xml" />
	
	
</beans>

 

 

그리고 mybatis-context.xml 내의 bean을 수정해주면 불러올 수 있다.

-> property의 값들을 불러올 수 있음

<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
    destroy-method="close"
    p:driverClassName="${db.driver}"
    p:url="${db.url}"
    p:username="${db.username}"
    p:password="${db.password}"
/>

 

 

MemberDao를 MemberMapper로 이름 변경

package com.kh.mvc.member.model.dao;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.session.SqlSession;

import com.kh.mvc.member.model.vo.Member;

@Mapper
public interface MemberMapper {

	Member findMemberById(SqlSession session, String id);

}

 

 

mapperScanner를 만들기 위한 bean 생성

<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer"
    p:basePackage="com.kh.mvc.*.model.dao"
/>

 

 

service, mapper 수정

 

package com.kh.mvc.member.model.service;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.kh.mvc.member.model.dao.MemberDao;
import com.kh.mvc.member.model.dao.MemberMapper;
import com.kh.mvc.member.model.vo.Member;

//@Service("빈 ID")
@Service
public class MemberServiceImpl implements MemberService {
	
	@Autowired
	private MemberMapper mapper;
	
//	@Autowired
//	private SqlSession session;
	
	@Override
	public Member login(String id, String password) {
		
		Member member = null;

//		member = dao.findMemberById(session, id);
		member = mapper.findMemberById(id);
		
		return member;
	}

}

 

 

@Mapper
public interface MemberMapper {

	Member findMemberById(@Param("id") String id);

}

 

 

그리고 member-mapper에 패키지명이 포함된 풀 패키지명으로 이름을 바꿔준다.

<mapper namespace="com.kh.mvc.member.model.dao.MemberMapper">

 

 

실제 호출됐던 쿼리 아이디를 메소드명과 동일하게 바꿔준다.

 

 

@Mapper라는 어노테이션이 스캔될 때 메소드 이름과 쿼리문 ID가 동일해야 수행이 가능하다.

 

 

 

 

 

- 로그인 기능 구현

 

 

로그인 로직

1. HttpSession과 Model 객체 사용

 

> MemberServiceImpl.java

package com.kh.mvc.member.model.service;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.kh.mvc.member.model.dao.MemberMapper;
import com.kh.mvc.member.model.vo.Member;

//@Service("빈 ID")
@Service
public class MemberServiceImpl implements MemberService {
	
	@Autowired
	private MemberMapper mapper;
	
//	@Autowired
//	private SqlSession session;
	
	@Override
	public Member login(String id, String password) {
		
		Member member = null;

//		member = dao.findMemberById(session, id);
		member = mapper.findMemberById(id);
		
//		System.out.println(mapper.findAll());
		
		if(member != null && member.getPassword().equals(password)) {
			return member;
		} else {
			return null;
		}
	}

}

 

 

controller

	
	@Autowired
	private MemberService service;
	
/*
 *  로그인 처리
 *  1. HttpSession과 Model(Controller가 처리하고 만들어진 데이터를 Dispatcher Servlet에게 전달해주는 것) 객체
 *  
 */
	@PostMapping("/login")
	public String login(
			HttpSession session,
			@RequestParam("id")String id, @RequestParam String password) {
		
		log.info("{}, {}", id, password);
		
		Member member = service.login(id, password);
		
		if (member != null) {
			session.setAttribute("loginMember", member);
			
			/*
			 *  return "home";
			 *  	- forwarding 방식으로 ViewResolver에 의해 /WEB-INF/views/home.jsp로 forwarding 한다.
			 *  
			 *  return "redirect:/";
			 *  	- redirect 방식으로 여기서 리턴 한 경로로 브라우저에서 다시 요청을 하도록 반환한다.
			 */
			return "redirect:/";
		} else {
			
            	return "home";
		}

	}

 

 

로그인 성공 시 리턴해줄 화면

 

> home.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<c:set var="path" value="${ pageContext.request.contextPath }"/>

<html>
<head>
	<title>Home</title>
</head>
<body>
<h1>
	Hello world!  
</h1>

<P>  The time on the server is ${serverTime}. </P>

<!-- 로그인 전 -->
<c:if test="${ empty loginMember }">
	<form action="${ path }/login" method="post">
		<label>아이디 : <input type="text" name="id" required /></label><br>
		<label>패스워드 : <input type="password" name="password"/></label><br><br>
		
		<input type="submit" value="로그인">
	</form>
</c:if>

<!-- 로그인 성공 시 -->
<c:if test="${ !empty loginMember }">
	${ loginMember.name }님, 안녕하세요.
	
		<button onclick="location.href = '${ path }/logout'">로그아웃</button>
</c:if>


</body>
</html>

 

 

common/msg.jsp 생성

<%@ 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>
	<script>
		// 알림메세지를 띄움
		alert("${ msg }");
	
		// 실행시켜야할 스크립트가 있으면 실행
		if(${ !empty script }) {
			${ script }
		}
		
		// 페이지 이동
		location.replace("${ pageContext.request.contextPath }${ location }");
	</script>
</body>
</html>

 

데이터는 model 객체에 담아서 전달해준다.

@PostMapping("/login")
public String login(
        HttpSession session, Model model,
        @RequestParam("id")String id, @RequestParam String password) {

    log.info("{}, {}", id, password);

    Member member = service.login(id, password);

    if (member != null) {
        session.setAttribute("loginMember", member);

        /*
         *  return "home";
         *  	- forwarding 방식으로 ViewResolver에 의해 /WEB-INF/views/home.jsp로 forwarding 한다.
         *  
         *  return "redirect:/";
         *  	- redirect 방식으로 여기서 리턴 한 경로로 브라우저에서 다시 요청을 하도록 반환한다.
         */
        return "redirect:/";
    } else {
        model.addAttribute("msg", "아이디나 비밀번호가 일치하지 않습니다.");
        model.addAttribute("location","/");

        return "common/msg"; // /WEB-INF/views/common/msg.jsp로 forwarding 한다.
    }
}

 

 

 

로그아웃(Post 요청으로 처리)

// 로그아웃 처리
@PostMapping("/logout")
public String logout(HttpSession session) {

    session.invalidate();

    return "redirect:/";
}

 

 

home.jsp

<!-- 로그인 성공 시 -->
<c:if test="${ !empty loginMember }">
	${ loginMember.name }님, 안녕하세요.
	
	<form action="${ path }/logout" method="post">
		<button type="submit">로그아웃</button>
	</form>
</c:if>

post로 넘어갈 수 있도록 form 태그로 감싸준다.

 

 

 

 

2. @SessionAttributes과 ModelAndView 객체를 활용하는 방법

 

 > MemberController.java

/*
	2. @SessionAttributes과 ModelAndView 객체
*/	
@RequestMapping(value = "/login", method = {RequestMethod.POST})
public String login(@RequestParam("id") String id, @RequestParam("password") String password) {

    log.info("{}, {}", id, password);

    model.setViewName("home");

    return model;
}

 

 

서비스 객체에게 로그인 요청(id, password 전달)

Member loginMember = service.login(id, password);

 

 

로그인 성공 시 home으로 redirect, 실패 시 msg.jsp로 forwarding

/*
2. @SessionAttributes과 ModelAndView 객체
    1) @SessionAttributes("키값")
        - Model 객체에 "키값"에 해당하는 Attribute를 Session Scope까지 범위를 확장시킨다.
    2) ModelAndView
        - 컨트롤러에서 뷰로 전달할 데이터와 뷰에 정보를 담는 객체이다.
        - addAttribute()가 아닌 addObject() 메소드를 통해서 데이터를 담을 수 있다.
*/	
@RequestMapping(value = "/login", method = {RequestMethod.POST})
public ModelAndView login(ModelAndView model,
        @RequestParam("id") String id, @RequestParam("password") String password) {

    log.info("{}, {}", id, password);

    Member loginMember = service.login(id, password);

    if(loginMember != null) {
        model.addObject("loginMember", loginMember);
        model.setViewName("redirect:/");
    } else {
        model.addObject("msg", "아이디나 비밀번호가 일치하지 않습니다.");
        model.addObject("location", "/");
        model.setViewName("common/msg");
    }
    return model;
}

 

-> 어노테이션 @SessionAttributes로 loginMember에 담겨있는 키값을 session Scope까지 확장시켜준다.(확장만, 저장x)

-> 로그인 유지됨

model.addObject("loginMember", loginMember);

 

 

 

- 로그아웃 처리

// 로그아웃 처리 (SessionStatus 객체 사용)
@PostMapping("/logout")
public String logout(SessionStatus status) {

    log.info("status.isComplete() : {}", status.isComplete());

    // SessionStatus 객체의 setComplete() 메소드로 세션 스코프로 확장된 객체들을 지워준다.
    status.setComplete();

    log.info("status.isComplete() : {}", status.isComplete());

    return "redirect:/";
}

 

 

 

 

- 회원가입 (enroll.jsp) 생성

JSP 템플릿 새로 생성 후 적용한 뒤 enroll.jsp 생성

 

 

> enroll.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>회원 가입 정보</h2>
<div id="enroll-container">	 	
 	<form name="memberEnrollFrm" action="${ pageContext.request.contextPath }/member/enroll" method="post">
 		<table>
 			<tr>
				<th>아이디</th>
				<td>
					<input type="text" name="userId" id="newId" placeholder="아이디(4글자이상)" required>
					<input type="button" id="checkDuplicate" value="중복검사" >
				</td> 			
 			</tr>
 			<tr>
				<th>패스워드</th>
				<td>
					<input type="password" name="userPwd" id="pass1" required>
				</td> 			
 			</tr>
 			<tr>
				<th>패스워드확인</th>
				<td>
					<input type="password" id="pass2">
				</td> 			
 			</tr>
 			<tr>
				<th>이름</th>
				<td>
					<input type="text" name="userName" id="userName" required>				
				</td> 			
 			</tr>
 			<tr>
				<th>휴대폰</th>
				<td>
					<input type="tel" placeholder="(-없이)01012345678" name="phone" id="phone" maxlength="11">								
				</td> 			
 			</tr>
 			<tr>
				<th>이메일</th>
				<td>
					<input type="email" placeholder="abc@abc.com" name="email" id="email">												
				</td> 			
 			</tr>
 			<tr>
				<th>주소</th>
				<td>
					<input type="text" name="address" id="address">
				</td> 			
 			</tr>
 			<tr>
				<th>취미</th>
				<td>
					<label><input type="checkbox" name="hobby" id="hobby0" value="운동">운동</label>
					<label><input type="checkbox" name="hobby" id="hobby1" value="등산">등산</label>
					<label><input type="checkbox" name="hobby" id="hobby2" value="독서">독서</label>
					<label><input type="checkbox" name="hobby" id="hobby3" value="게임">게임</label>
					<label><input type="checkbox" name="hobby" id="hobby4" value="여행">여행</label>
				</td> 			
 			</tr> 		
 		</table> 
 		<input type="submit" id="enrollSubmit" value="가입">	
 		<input type="reset" value="취소">	
 	</form>
 	<form name="checkIdForm">
 		<input type="hidden" name="userId">
 	</form>
</div>
<script>
	// 아이디 중복 확인
	$(document).ready(() => {
		$("#checkDuplicate").on("click", () => {
			let userId = $("#newId").val().trim();
			
			$.ajax({
				type: "post",
				url: "${ pageContext.request.contextPath }/member/idCheck",
				dataType: "json",
				data: {
					userId
				},
				success: (data) => {
					console.log(data);
					
					if(data.duplicate === true) {
						alert("이미 사용중인 아이디 입니다.");
					} else {
						alert("사용 가능한 아이디 입니다.");						
					}
				},
				error: (error) => {
					console.log(error);
				}
			});
		});		
	});
</script>
</body>
</html>

 

-> 요청은 enroll을 열어줄 수 있는 컨트롤러를 만들어줘서 호출해줘야 한다.

-> jsp파일을 직접적으로 접근이 불가능하기 때문(WEB-INF이하)

 

 

 

> MemberController.java

// 회원가입
@GetMapping("/member/enroll")
public String enroll() {
    log.info("회원 가입 페이지 요청");

    return "member/enroll";
}

 

 

 

jQuery 추가시켜줬다.

 

 

servlet-context.xml

<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<!--  
    mapping 속성에 해당하는 요청에 대해 location 속성에 지정 된 디렉터리(폴더)로 매핑을 시켜준다.
-->
<resources mapping="/resources/**" location="/resources/" />
<!--
    사용자로 부터 /js/jquery-3.6.0.js 라는 요청이 오면 이것을 /resources/js/jquery-3.6.0.js로 매핑시킨다.
 -->
<resources mapping="/js/**" location="/resources/js/" />

 

-> resources를 지워줘도 알아서 찾아줄 수 있다.

 

 

 

 

enroll.jsp 수정 (name, id, password)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>

<c:set var="path" value="${ pageContext.request.contextPath }"/>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="${ path }/js/jquery-3.6.0.js"></script>
</head>
<body>
<h2>회원 가입 정보</h2>
<div id="enroll-container">	 	
<form name="memberEnrollFrm" action="${ path }/member/enroll" method="post">
    <table>
        <tr>
            <th>아이디</th>
            <td>
                <input type="text" name="id" id="newId" placeholder="아이디(4글자이상)" required>
                <input type="button" id="checkDuplicate" value="중복검사" >
            </td> 			
        </tr>
        <tr>
            <th>패스워드</th>
            <td>
                <input type="password" name="password" id="pass1" required>
            </td> 			
        </tr>
        <tr>
            <th>패스워드확인</th>
            <td>
                <input type="password" id="pass2">
            </td> 			
        </tr>
        <tr>
            <th>이름</th>
            <td>
                <input type="text" name="name" id="userName" required>				
            </td> 			
        </tr>

 

 

+ home.jsp에서 회원가입 버튼도 추가시켜줌

<input type="button" onclick="location.href='${ path }/member/enroll'" value="회원가입">

 

 

이름이 같아도 매개 타입이 다르기 때문에 (오버로딩)

같은 이름의 메소드를 사용할 수 있다.

@PostMapping("/member/enroll")
public String enroll(@ModelAttribute Member member) {

    log.info(member.toString());

    return "member/enroll";
}

 

 

 

전체 실습 코드

 

 

> MemberController.java

package com.kh.mvc.member.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;

import com.kh.mvc.member.model.service.MemberService;
import com.kh.mvc.member.model.service.MemberServiceImpl;
import com.kh.mvc.member.model.vo.Member;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
//Model 객체에 loginMember라는 키값으로 객체가 추가되면 해당 객체를 세션 스코프에 추가하는 어노테이션이다.
@SessionAttributes("loginMember")
public class MemberController {
/*
	// controller가 처리하게 될 요청에 대해 정의함(URL, Method 등)
//	@RequestMapping(value = "/login", method = {RequestMethod.GET})
	@GetMapping("/login")
	// 요청을 처리할 메소드 작성
	public String login() {
		
		log.info("login() - 호출");
		
		return "home";
	}
	
	사용자의 파라미터를 전송받는 방법
	
	1. HttpServletRequest를 통해서 전달(전송)받기(기존 JSP/Servlet 방식)
		- 메소드의 매개 변수로 HttpServletRequest를 작성하면 메소드 실행 시 스프링 컨테이너가 자동으로 객체를 인자로 주입해준다.
	@PostMapping("/login")
	public String login(HttpServletRequest request) {
		String id = request.getParameter("id");
		String password = request.getParameter("password");
		
		log.info("login() - 호출 : {} {}", id, password);
		
		return "home";
	}
	
	2-1. @RequestParam 어노테이션을 통해서 전송받기
		- 스프링에서 조금 더 간편하게 파라미터를 받아올 수 있는 방법 중 하나이다.
		- 내부적으로는 Request 객체를 이용해서 데이터를 전송받는 방법이다.
		- 단, 매개변수의 이름과 name 속성의 값이 동일하게 설정된 경우 자동으로 주입된다.
			(어노테이션을 사용하는 것이 아니기 때문에 defaultValue 설정이 불가능하다.)
		
	@RequestMapping(value = "login", method= {RequestMethod.POST})
//	public String login(@RequestParam("id") String id, @RequestParam("password") String password) {
	public String login(String userId, String password) {
	
		// name 속성의 갑소가 매개변수의 명이 같으면 어노테이션 생략이 가능
		public String login(String id, String password) {
		
		log.info("login() - 호출 : {} {}", id, password);
		
		return "home";
	}
	
	2-2. @RequestParam에 default 값 설정
		- defaultValue 속성을 사용하면 파라미터 name 속성에 값이 없을 경우 기본값을 지정할 수 있다.
	@PostMapping("/login")
	public String login(@RequestParam("id") String id, 
						@RequestParam(value = "password", defaultValue = "0000") String password) {
	
		log.info("login() - 호출 : {} {}", id, password);

		return "home";
	}
	
	2-3. @RequestParam에 실제 존재하지 않는 파라미터를 받으려고 할 때
		- 파라미터 name 속성에 없는 값이 넘어올 경우 에러가 발생한다.
		- @RequestParam(required = false)로 지정하면 null 값을 넘겨준다.
		- 단, defaultValue를 설정하면 defaultValue에 설정된 값으로 넘겨준다. (에러가 발생하지 않음)
	
	@PostMapping("/login")
	public String login(@RequestParam("id") String id, 
						@RequestParam(value = "password") String password,
//						@RequestParam(value = "address", required = false)String address) {
						@RequestParam(value = "address", defaultValue = "서울특별시") String address) {
	
		log.info("login() - 호출 : {} {} {}", new Object[] {id, password, address});

		return "home";
	}
	
	3. @PathVariable 어노테이션을 통해서 전송받기 (restAPI시 많이 사용)
		- URL 패스상에 있는 특정 값을 가져오기 위해 사용하는 방법이다.
		- REST API를 사용할 때, 요청 URL 상에서 필요한 값을 가져오는 경우 주로 사용한다.
		- 매핑 URL에 {}로 묶는다면, {} 안의 값을 Path Variable로 사용하고 요청 시 실제 경로상의 값을 해당 Path Variable로 받겠다는 의미이다.
		- 매핑 URL에 {} 안의 변수명과 매개변수의 변수명이 동일하다면 @PathVariable의 괄호는 생략이 가능하다.
			(어노테이션 자체는 생략이 안된다. @RequestParam인지 @PathVariable인지 알 수 없음)
			
	@GetMapping("/member/{id}")
//	public String findMember(@PathVariable("id") String id) {
	public String findMember(@PathVariable String id) {
		
		log.info("Member ID : {}", id);
		
		return "home";
	}
	
	4. @ModelAttribute 어노테이션을 통해서 전송받기 (파라미터가 많을 경우)
		- 요청 파라미터가 많은 경우 객체 타입으로 파라미터를 넘겨받는 방법이다.
		- 스프링 컨테이너가 기본 생성자를 통해서 객체를 생성하고
			파라미터 NAME 속성의 값과 동일한 필드명을 가진 필드에 값을 주입해준다.
		- 단, 기본 생성자와 Setter가 존재해야 한다.
		- @ModelAttribute 어노테이션을 생략해도 객체로 매핑된다.
		
	@PostMapping("/login")
//	public String login(@ModelAttribute Member member) {
	public String login(Member member) {
		
		log.info("{}, {}", member.getId(), member.getPassword());
		
		return "home";
	}
	
 */
	
	@Autowired
	private MemberService service;
	
/*
 *  로그인 처리
 *  1. HttpSession과 Model(Controller가 처리하고 만들어진 데이터를 Dispatcher Servlet에게 전달해주는 것) 객체
 *  	1) Model
 *  		- 컨트롤러에서 데이터를 뷰로 전달하고자 할 때 사용하는 객체이다.
 *		    - 전달하고자 하는 데이터를 맵 형태(key, value)로 담을 수 있다.
 *		    - Model 객체의 Scope는 기본적으로 Request이다. (하나의 요청을 받아서 응답될때까지만 유지)
 *

	@PostMapping("/login")
	public String login(
			HttpSession session, Model model,
			@RequestParam("id")String id, @RequestParam String password) {
		
		log.info("{}, {}", id, password);
		
		Member member = service.login(id, password);
		
		if (member != null) {
			session.setAttribute("loginMember", member);
			
			/*
			 *  return "home";
			 *  	- forwarding 방식으로 ViewResolver에 의해 /WEB-INF/views/home.jsp로 forwarding 한다.
			 *  
			 *  return "redirect:/";
			 *  	- redirect 방식으로 여기서 리턴 한 경로로 브라우저에서 다시 요청을 하도록 반환한다.
			 *
			 *
			return "redirect:/";
		} else {
			model.addAttribute("msg", "아이디나 비밀번호가 일치하지 않습니다.");
			model.addAttribute("location","/");

			return "common/msg"; // /WEB-INF/views/common/msg.jsp로 forwarding 한다.
		}
	}
	
	// 로그아웃 처리
	@PostMapping("/logout")
	public String logout(HttpSession session) {
		
		session.invalidate();
		
		return "redirect:/";
	}
	
	2. @SessionAttributes과 ModelAndView 객체
		1) @SessionAttributes("키값")
			- Model 객체에 "키값"에 해당하는 Attribute를 Session Scope까지 범위를 확장시킨다.
		2) ModelAndView
	 	    - 컨트롤러에서 뷰로 전달할 데이터와 뷰에 정보를 담는 객체이다.
	 	    - addAttribute()가 아닌 addObject() 메소드를 통해서 데이터를 담을 수 있다.

*/	
	@RequestMapping(value = "/login", method = {RequestMethod.POST})
	public ModelAndView login(ModelAndView model,
			@RequestParam("id") String id, @RequestParam("password") String password) {
		
		log.info("{}, {}", id, password);
		
		Member loginMember = service.login(id, password);
		
		if(loginMember != null) {
			model.addObject("loginMember", loginMember);
			model.setViewName("redirect:/");
		} else {
			model.addObject("msg", "아이디나 비밀번호가 일치하지 않습니다.");
			model.addObject("location", "/");
			model.setViewName("common/msg");
		}
		return model;
	}
	
	// 로그아웃 처리 (SessionStatus 객체 사용)
	@PostMapping("/logout")
	public String logout(SessionStatus status) {
		
		log.info("status.isComplete() : {}", status.isComplete());
		
		// SessionStatus 객체의 setComplete() 메소드로 세션 스코프로 확장된 객체들을 지워준다.
		status.setComplete();
		
		log.info("status.isComplete() : {}", status.isComplete());
		
		return "redirect:/";
	}
	
	// 회원가입
	@GetMapping("/member/enroll")
	public String enroll() {
		log.info("회원 가입 페이지 요청");
		
		return "member/enroll";
	}
	
	@PostMapping("/member/enroll")
	public String enroll(@ModelAttribute Member member) {
		
		log.info(member.toString());
		
		return "member/enroll";
	}

	
}

 

 

 

 

> home.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<c:set var="path" value="${ pageContext.request.contextPath }"/>

<html>
<head>
	<title>Home</title>
</head>
<body>
<h1>
	Hello world!  
</h1>

<P>  The time on the server is ${serverTime}. </P>

<!-- 로그인 전 -->
<c:if test="${ empty loginMember }">
	<form action="${ path }/login" method="post">
		<label>아이디 : <input type="text" name="id" required /></label><br>
		<label>패스워드 : <input type="password" name="password"/></label><br><br>
		
		<input type="button" onclick="location.href='${ path }/member/enroll'" value="회원가입">
		<input type="submit" value="로그인">
	</form>
</c:if>

<!-- 로그인 성공 시 -->
<c:if test="${ !empty loginMember }">
	${ loginMember.name }님, 안녕하세요.
	
	<form action="${ path }/logout" method="post">
		<button type="submit">로그아웃</button>
	</form>
</c:if>


</body>
</html>

 

 

 

 

 

 > MemberService.java

package com.kh.mvc.member.model.service;

import com.kh.mvc.member.model.vo.Member;

public interface MemberService {

	Member login(String id, String password);

}

 

 

 

 > MemberServiceImpl.java

package com.kh.mvc.member.model.service;

import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.kh.mvc.member.model.dao.MemberMapper;
import com.kh.mvc.member.model.vo.Member;

//@Service("빈 ID")
@Service
public class MemberServiceImpl implements MemberService {
	
	@Autowired
	private MemberMapper mapper;
	
//	@Autowired
//	private SqlSession session;
	
	@Override
	public Member login(String id, String password) {
		
		Member member = null;

//		member = dao.findMemberById(session, id);
		member = mapper.findMemberById(id);
		
//		System.out.println(mapper.findAll());
		
		if(member != null && member.getPassword().equals(password)) {
			return member;
		} else {
			return null;
		}
	}

}

 

 

 

 > MemberMapper.java

package com.kh.mvc.member.model.dao;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.session.SqlSession;

import com.kh.mvc.member.model.vo.Member;

@Mapper
public interface MemberMapper {

	Member findMemberById(@Param("id") String id);
	
//	@Select("sellect * from member")
//	List<Member> findAll();
}
반응형
Comments