1) @Slf4j ( > Lombok)
Log log = new Log() 객체 생성 -> @Slf4j를 적으면 spring builder에서 log객체를 주입한다.
매개값은 String만 가능하다.
package com.example.sakila.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Controller
public class HelloController {
@GetMapping("/hello")
public String hello() {
// loggin 프레임워크 사용
log.debug("gg");
return "";
}
}
로그 설정은 properties에서 할 수 있다.
properties에서 설정 #log setting : logging.level.패키지명
logging.level.com.example.sakila.controller = debug
# 패키지 범위로도 설정할 수 있다
logging.level.com.example.sakila = debug
레벨순서 : fatal error warn debug trace - debug로 설정하면 debug로 부터 왼쪽에 있는 레벨 log를 보여준다. - 보통 new throws exception 범위는 error로 설정한다. |
<<콘솔 결과>>
2) intercept
Controller에서 response, request 객체가 실행되기 직전에 intercept해서 특정 코드를 실행한다
- ex : 세션 검증
<<HandlerInterceptor 인터페이스>>
public interface HandlerInterceptor {
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable Exception ex) throws Exception {
}
}
- preHandle() : Controller가 실행되기 전에 intercept 한다. true 반환하면 Controller 코드 진행 false 반환시 return;과 같음
- postHandle() : Controller가 실핸된 후에 intercept 한다.
1. << Intercept Component 설정 >>
package com.example.sakila;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component
public class OffInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle
(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.debug(request.getRequestURL().toString() + "reqeust intercepted");
// 로그인을 하지 않았다면 = response + return false
HttpSession session = request.getSession();
if(session.getAttribute("loginStaff") == null) {
response.sendRedirect(request.getContextPath() + "/off/login");
// off/login.jsp on..로 시작하는 컨트롤러를 intercept
return false;
}
return HandlerInterceptor.super.preHandle(request, response, handler);
}
}
// HandlerInterceptor : Default 메서드로 되어있다 (구현하지 않으면 기본 메서드 구현됨)
@Component : 스프링에게 객체(new OffInterceptor(); 를 만들어서 spring beans에 넣어달라 -> Autowired 사용 가능) (=> Stereotype에 소속된다. 구현 하지 않고 그냥 구현 후 spring beans 에 등록) @Controller : 내부적으로 서블릿 구현 후 spring beans 에 등록 @Mapper : 내부적으로로 jdbc 구현 후 spring beans 에 등록 |
<<@SpringBootApplication>>
※ 각 스프링부트 프로젝트마다 디폴트로 가장 먼저 실행되는 클래스가 만들어져있다. @ SpringBootApplication : 쉽게 생각해서, 어느 컨트롤러를 실행하던, 가장 먼저 실행하는 프로세스를 정하는 클래스로 지정하는 애노테이션여기에 인터셉트를 적용하려면, webMvcConfigurer를 구현해야한다.
※ 스프링부트 프로젝트 마다 가장 먼저 실행되는 클래스
2. @SpringBootApplication 을 적용받는 클래스에, Interceptor 구현하기
package com.example.sakila;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@SpringBootApplication
public class SakilaApplication implements WebMvcConfigurer {
@Autowired private OnInterceptor oninterceptor;
public static void main(String[] args) {
SpringApplication.run(SakilaApplication.class, args);
}
// 인터셉터 설정 (1)인터셉터 클래스 구현 (2) 인터셉터 맵핑
@Override
public void addInterceptors(InterceptorRegistry registry) {
// InterceptorRegistry = 인터셉터의 List. 인터셉터를 구현하여 여기다가 add하면 된다
// (1) 클래스 구현 및 (2) 인터셉트 리스트, 맵핑
registry.addInterceptor(oninterceptor).addPathPatterns("/on/**");
WebMvcConfigurer.super.addInterceptors(registry);
}
}
① WebMvcConfigurer 인터페이스의 addInterceptors()메서드 오버라이딩
ㄴ 오버라이딩을 위해 WebMvcConfigurer를 구현.
ㄴ registry는 인터셉터의 List이다. 해당 리스트에 원하는 인터셉트를 add하면 된다.
registry.addInterceptor(oninterceptor).addPathPatterns("/on/**"); |
② @Autowired로 미리 설정한 인터셉트인 OnInterceptor타입 의존성 주입
① 컨트롤러 - 파라미터값 유효성 검사 및 get/post 분기
@Slf4j
@Controller
public class LoginController {
@Autowired com.example.sakila.mapper.Staff staffMapper;
@GetMapping("/off/login")
public String login() {
log.debug("off/login run");
return "/off/login";
}
@PostMapping("/on/login")
public String login(Model model, HttpSession session,
@RequestParam(name="staffId", defaultValue = "1") int staffId, // int staffId = Integer.parseInt(reqeust.getParameter("staffId")
@RequestParam(name = "password") String password) {
Staff paramStaff = new Staff();
paramStaff.setStaffId(staffId);
paramStaff.setPassword(password);
Staff loginStaff = com.example.sakila.mapper.Staff.login(paramStaff);
if(loginStaff == null) {
model.addAttribute("msg", "Login failed");
return "/off/login";
}
session.setAttribute("loginStaff", loginStaff);
return "redirect:/on/login";
}
}
@RequestParam(name="staffId", defaultValue = "1") int staffId, 값 유효하지 않으면 디폴트 값으로 1 저장 // int staffId = Integer.parseInt(reqeust.getParameter("staffId") @RequestParam() String password - 파라미터와 vo타입 변수명이 같으면 생략 가능 |
Mapper에서 사용할 staffMapper 객체 의존성 주입 |
MyBatis는 무조건 매개변수 1개밖에 처리 못함 (Map 또는 Vo 타입 활용)
※ 로그아웃 -> loginController 에 포함 가능
@GetMapping("/on/logout")
public String logout(HttpSession session) {
log.debug("/on/logout run");
session.invalidate();
return "redirect:/off/login";
}
컨트롤러 특징
- 한 클래스에 URL을 여러개 둘수있으며, 하나의 URL에 Mapping이 중복되면 충돌이 난다. |
'SPRING' 카테고리의 다른 글
[Service & MySQL 에러] SQLIntegrityConstraintViolationException (0) | 2024.11.13 |
---|---|
[java 에러] row cannot be resolved to a variable (0) | 2024.11.13 |
{fn:substring} HTML 에서 글자열 자르기 (0) | 2024.11.12 |
[2024-11-07]쿼리파라미터 전달, DB 기본값 Null (0) | 2024.11.08 |
[JSTL] c태그를 이용한 iteration 속성 이용하기 (0) | 2024.11.06 |