컨트롤러에서 아래를 통해 세션값을 가져오는 부분을 어노테이션을 이용해 메소드 인자로 세션값을 받을 수 있도록 코드를 바꾸는 과정에서 spring_session 테이블이 없다는 오류 발생
기존 코드
SessionUser user = (SessionUser) httpSession.getAttribute("user");
바꾼 코드
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginUser {
}
@RequiredArgsConstructor
@Component
public class LoginUserArgumentResolver implements HandlerMethodArgumentResolver {
private final HttpSession httpSession;
@Override
public boolean supportsParameter(MethodParameter parameter) {
// 컨트롤러 메서드의 특정 파라미터를 지원하는지 판단
boolean isLoginUserAnnotation = parameter.getParameterAnnotation(LoginUser.class) != null;
boolean isUserClass = SessionUser.class.equals(parameter.getParameterType());
// 파라미터에 @LoginUser 어토네이션이 있고, 파라미터 클래스 타입이 SessionUser.class 인 경우 true 반환
return isLoginUserAnnotation && isUserClass;
}
@Override
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
// 세션에서 객체를 가져와 파라미터에 전달
return httpSession.getAttribute("user");
}
}
@GetMapping("/")
public String home(Model model,
@RequestParam(required = false, defaultValue = "0", value = "page") int page,
@LoginUser SessionUser user) {
Page<BoardResponseDto> boardList = boardService.findAll(page);
boardList.stream().forEach(BoardResponseDto::getContent);
model.addAttribute("boardList", boardList);
if (user != null) {
model.addAttribute("member", user);
}
return "home";
}
yml에 아래와 같이 작성 했음에도 데이터 베이스에 스프링 시큐리티가 사용하는 세션 저장소 spring_session이 자동으로 만들어 지지 않는 것을 확인
spring:
session:
store-type: jdbc
해결 과정
1. 애플리케이션 시작 시점에 spring_session 테이블이 생성되도록 schema.sql을 작성
CREATE TABLE SPRING_SESSION
(
PRIMARY_ID CHAR(36) NOT NULL,
SESSION_ID CHAR(36) NOT NULL,
CREATION_TIME BIGINT NOT NULL,
LAST_ACCESS_TIME BIGINT NOT NULL,
MAX_INACTIVE_INTERVAL INT NOT NULL,
EXPIRY_TIME BIGINT NOT NULL,
PRINCIPAL_NAME VARCHAR(100),
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
);
CREATE UNIQUE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (EXPIRY_TIME);
CREATE INDEX SPRING_SESSION_IX3 ON SPRING_SESSION (PRINCIPAL_NAME);
CREATE TABLE SPRING_SESSION_ATTRIBUTES
(
SESSION_PRIMARY_ID CHAR(36) NOT NULL,
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
ATTRIBUTE_BYTES BLOB NOT NULL,
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION (PRIMARY_ID) ON DELETE CASCADE
);
다시 애플리케이션을 작동시켰으나 여전히 관련 테이블이 만들어지지 않았다.
spring.jpa.hibernate.ddl-auto 기능과 schema.sql 자동 실행 기능을 함께 사용할 수 없는 것 같다.
2. yml 파일에 아래 내용 추가
spring:
sql:
init:
mode: always
이후 데이터베이스에 spring_session 테이블이 만들어진 것을 확인할 수 있었다.