푸들푸들

1031 [Sakila] Spring 로그인 본문

구디아카데미/JAVA

1031 [Sakila] Spring 로그인

COCO_develop 2024. 11. 1. 09:59

Interceptor

OnInterceptor.java

@Slf4j
@Component // new OnInterceptor -> bean으로 등록해줌
public class OnInterceptor implements HandlerInterceptor{
	
	// 특정 컨트롤러 실행전에 request, response를 가채로어 먼저 실행됨
		@Override
		public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
				throws Exception {
			
			log.debug(request.getRequestURL().toString() +"요청 Interceptor");
			
			// 로그인을 하지 않았다면 session.getAttribute("loginStaff")
			HttpSession session = request.getSession();
			if(session.getAttribute("loginStaff") == null) {
				response.sendRedirect(request.getContextPath() + "/off/login"); // /off/login.jsp
				return false;
			}
			return HandlerInterceptor.super.preHandle(request, response, handler);
		}
}

 

OffInterceptor.java

@Slf4j
@Component
public class OffInterceptor implements HandlerInterceptor {
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		log.debug(request.getRequestURL().toString() + "요청 Interceptor");

		// 로그인이 되어 있다면
		HttpSession session = request.getSession();
		if (session.getAttribute("loginStaff") != null) {
			response.sendRedirect(request.getContextPath() + "/on/main"); // /off/login.jsp
			return false;
		}

		return HandlerInterceptor.super.preHandle(request, response, handler);
	}
}

 

SakilaApplication.java

@SpringBootApplication // 제일 먼저 실행해라
public class SakilaApplication implements WebMvcConfigurer {
	@Autowired
	private OnInterceptor onInterceptor;
	@Autowired
	private OffInterceptor offInterceptor;

	public static void main(String[] args) { // main 메서드 제일 먼저 실행
		SpringApplication.run(SakilaApplication.class, args); // 자기 자신 실행
	}
	
	// 인터셉터 설정(1.인터셉터 클래스 구현 2.인터셉터 맵핑)
	@Override
	public void addInterceptors(InterceptorRegistry registry) { // InterceptorRegistry: 인터셉터 리스트(맵핑 가능)
		// /on/*오로 시작하는 컨트롤러 가로채 onInterceptor.preHandle(request, respone)
		registry.addInterceptor(onInterceptor).addPathPatterns("/on/**");
		registry.addInterceptor(offInterceptor).addPathPatterns("/off/**");
		WebMvcConfigurer.super.addInterceptors(registry);
	}
}

 

StaffMapper.java

- Interface

@Mapper
public interface StaffMapper {
	Staff login(Staff staff);
}

 

StaffMapper.xml

 - MyBatis XML Mapper 파일

 - Interface 파일에 전부 적어도 되지만 가독성을 위해 쿼리만 따로 작성

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.sakila.mapper.StaffMapper">
	<select id = "login"
			parameterType="com.example.sakila.vo.Staff"
			resultType="com.example.sakila.vo.Staff">
		SELECT 
			staff_id staffId
			, store_id storeId
			, username
		FROM staff
		WHERE active = 1 AND staff_id = #{staffId} AND password = #{password}
	</select>
</mapper>

 

로그(Log)

 - 프로그램 개발이나 운영 시 발생하는 문제점을 추적하거나 운영 상태를 모니터링하기 위한 텍스트

 - System.out.println(); 를 사용하여 로그를 확인할 수 있지만 이보다 로그를 기록하는 클래스를 만들어 사용하는 것이 더 나은 방법. (실무에서 Logging 방식 사용)

 - log4j2 로그 레벨 : TRACE > DEBUG > INFO > WARN > ERROR > FATAL

INFO로 셋팅하면, INFO, WARN, ERROR, FATAL은 기록된다.

FATAL : 아주 심각한 에러가 발생한 상태를 나타낸다.

ERROR : 어떠한 요청을 처리하는 중 문제가 발생한 상태를 나타낸다. 프로그램 동작에 큰 문제가 발생했다는 것으로 즉시 문제를 조사해야 하는 (DB를 사용할 수 없는 상태, 중요 에러가 나오는 상황)

WARN : 프로그램의 실행에는 문제가 없지만, 향후 시스템 에러의 원인이 될 수 있는 경고성 메시지를 나타낸다. WARN에서도 2가지의 부분에선 종료가 일어남

명확한 문제 : 현재 데이터를 사용 불가, 캐시값 사용 등

잠재적 문제 : 개발 모드로 프로그램 시작, 관리자 콘솔 비밀번호가 보호되지 않고 접속 등

INFO : 어떠한 상태 변경과 같은 정보성 메시지를 나타낸다.

DEBUG : 개발시 디버그 용도로 사용하는 메시지를 나타낸다.

TRACE : 디버그 레벨이 너무 광범위한 것을 해결하기 위해서 좀 더 상세한 이벤트를 나타낸다.

 

application.properties

spring.application.name=sakila
server.port=80
server.servlet.context-path=/sakila
spring.mvc.view.prefix=/WEB-INF/view/
spring.mvc.view.suffix=.jsp
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/sakila
spring.datasource.username=root
spring.datasource.password=java1234

# log setting
# fatal error warn info debug trace - 순서(debug찍으면 fatal~error까지 출력됨)
logging.level.com.example.sakila=debug
logging.level.com.example.sakila.controller=debug
logging.level.com.example.sakila.mapper=debug

 

 

 

SLF4J(Simple Logging Facade for Java) 

 - java.util.logging, logback 및 log4j와 같은 다양한 로깅 프레임 워크에 대한 추상화(인터페이스) 역할을 하는 라이브러리   - 추상 로깅 프레임워크이기 때문에 단독으로는 사용할 수는 없다. -> 최종 사용자가 내부적으로 어떤 로깅 라이브러리를 사용하는지는 몰라도 되고 slf4j 프레임웍이 제공하는 API만 사용해서 구현하면 된다.

  * 추상화 역할?

   자동차를 운전할려면 기어변속이라는 API를 알아야 하지만,

   기어API가 추상화 되어있는 오토미션장치(프레임워크)가 장착된 자동차의 경우 운전자가 내부적으로 기어변속이 어떻     게 되는지 신경쓸 필요가 없다!

 

LoginController.java

@Slf4j
@Controller
public class LoginController {
	@Autowired private StaffMapper staffMapper;

	// 로그인 액션
	@PostMapping("/off/login")
	public String login(Model model, HttpSession session // session 받는 가장 간단한 방법(좋은 방법은 XX)
			, @RequestParam(name="staffId") int staffId // int staffId = Interger.parseInt(request.getParameter("staffId"))
			, @RequestParam(name="password") String password) { // String password=request.getParameter("password")
		
		Staff paramStaff = new Staff();
		paramStaff.setStaffId(staffId); 
		paramStaff.setPassword(password);
		
		Staff loginStaff = staffMapper.login(paramStaff);
		if(loginStaff == null) {
			log.debug("로그인 실패");
			model.addAttribute("msg", "로그인실패");
			return "/off/login"; // 포워딩
		}
		session.setAttribute("loginStaff", loginStaff);
		log.debug("로그인 성공, 세션loginStaff속성 추가");
		
	return "redirect:/on/main";
	}
}

 

login.jsp (src/main/webapp/WEB-INF/view/off/login)

<!DOCTYPE html>
<html>
<head>
<link
	href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
	rel="stylesheet">
<script
	src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://code.jquery.com/jquery-3.7.1.js"
	integrity="sha256-eKhayi8LEQwp4NKxN+CfCh+3qOVUtJn3QNZ0TciWLP4="
	crossorigin="anonymous"></script>
<meta charset="UTF-8">
<title></title>
</head>
<body class="container">
	<h1>Staff Login</h1>
	<span>${msg}</span>

    <form action="${pageContext.request.contextPath}/off/login" method="post">
		<div class="mb-3 mt-3">
			<label for="staffId" class="form-label">Staff Id</label>
			<input type="text" class="form-control" id="staffId" name="staffId">
	 	</div>
	 	<div class="mb-3">
			<label for="password" class="form-label">Password</label>
			<input type="password" class="form-control" id="password" name="password">
		</div>
		<button type="submit" class="btn btn-primary">로그인</button>
	</form>
</body>
</html>

 

 

http://localhost/sakila/off/login 접속

 

'구디아카데미 > JAVA' 카테고리의 다른 글

1101 [Sakila] staffOne  (2) 2024.11.01
1101 [Sakila]로그아웃, 유효성 검사  (3) 2024.11.01
1031 Github Token 발급, Commit, Push, 내려받기  (0) 2024.10.31
1030 Spring 기본  (0) 2024.10.30
1030 Spring 세팅  (2) 2024.10.30