목록Spring (23)
참새의 이야기
Enum 타입의 필드는 DB에서 tinyint 혹은 enum이라는 type으로 관리된다.예를 들어, 아래와 같이 StudyType이라는 enum 값이 있다고 하자.public enum StudyType { OFFLINE, ASSIGNMENT;}tinyint의 경우라면 각각에 0, 1이라는 숫자가 붙어 관리된다.만약 위와 같은 StudyType에 새로운 값이 추가된다면 어떤 일이 일어날까?OFFLINE에 이어서 기존에는 ASSIGNMENT가 따라왔지만, ONLINE이 사이에 추가되는 경우를 생각해보자.OFFLINE과 ASSGIGNMENT의 tinyint는 1과 2로 밀리게 된다.이런 문제는 삭제 시에도 똑같이 발생한다.enum값과 대응되는 숫자가 바뀔 수 있다는 점이 문제다.이를 방지하기 위해 ..
지난 글에서는 querydsl을 사용하기 위해 알아야 하는 아주 기본적인 부분들을 소개했다. 이번에는 최근에 프로젝트를 하면서 querydsl을 사용하면 유연하게 db 조회를 할 수 있다는 것을 실감했는데, 지난가을에 했던 뉴핏 프로젝트를 크게 개선할 수 있겠다는 생각이 들어서 글로도 기록해보려고 한다. 우선, 아래는 뉴핏에서 개선이 필요한 코드의 일부분이다. @GetMapping public ResponseEntity getAllEquipment( @RequestHeader(name = "authority-id") Long authorityId, @RequestParam(name = "purposeType", required = false) PurposeType purposeType, @RequestP..

뉴핏 프로젝트를 진행하기에 앞서 querydsl을 공부하고 있었지만 다른 팀원들이 querydsl에 대한 학습 경험이 없어서 일단은 querydsl을 사용하지 않고, Spring Data Jpa가 제공하는 쿼리 메서드와 @Query 어노테이션을 활용하여 repository 계층을 구성했다. 우리 서비스에서 필요한 repository의 메서드들을 어느 정도 구현하고 보니 쿼리를 자동 생성해 주는 쿼리 메서드는 괜찮았지만, @Query 어노테이션으로 직접 쿼리를 작성한 경우에는 가독성이 너무 안 좋다는 점이 아쉬웠다. 이때 querydsl을 도입하지 않을 수 없다는 생각이 들었고, 팀원들에게 querydsl 도입하자고 제안했다. JpaQueryFactory querydsl을 사용하여 쿼리를 만들기 위해서는 ..

Servlet Authentication Architecture 스프링 시큐리티의 인증은 아래의 조각들이 하나가 되어 움직인다. 가장 핵심이 되는 SecurityContextHolder 부터 하나씩 알아보자. SecurityContextHolder 아래 그림은 SecurityContextHolder 의 구조를 보여준다. 이름에서부터 나타나듯이 SecurityContext를 가지고 있다. SecurityContextHolder 는 인증된 사람에 대한 정보(detail)를 가지고 있다. SecurityContext가 채워지는 방식과 무관하게 값만 채워지면 현재 인증된 사용자로 인식한다. SecurityContextHolder 가 SecurityContext 를 가지고 있기 때문에 아래와 같이 간단하게 인증 ..

NewFit을 개발하면서 spring security에 OAuth2.0 + JWT의 조합으로 인증/인가를 구현했다. 단순히 코드를 여기저기서 긁어와서 구현하기보다 원리정도는 알고서 한줄 한줄 신중히 짜고 싶다는 생각에 공식 문서를 읽게 됐다. 지난 5월쯤에 처음 읽었을 때는 filter가 뭔지도 잘 모르겠었는데, MVC 강의를 들으면서 filter가 어떤 순서로 등장하고 어떻게 동작하는지를 배우고 다시 읽으니 이제는 이해가 되는 것 같다. 사실 아래의 내용은 공식 문서를 읽고 정리한지 두 달 정도 지난 내용이지만, 노션 창고에 있는 글을 하나씩 티스토리에도 옮기고자 이렇게 복붙 비슷한 걸 하게되었다. Security Architecture 스프링 MVC를 공부하면서 서블릿과 필터 구조에 대한 이해도가 높..
MVC의 처리 방법 WebServerCustomizer 이전 글에서 다뤘던 WebServerCustomizer 를 이용한 예외 처리를 살펴보자. @GetMapping("/api/members/{id}") public MemberDto getMember(@PathVariable("id") String id) { if (id.equals("ex")) { throw new RuntimeException("잘못된 사용자"); } return new MemberDto(id, "hello "+ id); } 위와 같이 Exception을 사용하여 WebServerCustomizer 에게 처리를 요청하면, 정상적인 요청은 JSON 형식으로 반환하지만, 예외 발생 시에는 Html이 반환된다. WebServerCustom..

서블릿 예외 처리 스프링이 제공하는 예외 처리 방식을 공부하기 전에 서블릿 컨테이너는 예외를 어떻게 처리하는지 알아볼 필요가 있다. 서블릿을 이용할 경우 두 가지 방식의 예외 처리법이 있다. Exception response.sendError(HTTP_STATUS_CODE, ERROR_MESSAGE) Exception 웹 애플리케이션은 request마다 thread가 할당되고 서블릿 컨테이너 안에서 실행된다. @Controller public class ServletExController { @GetMapping("/error-ex") public void errorEx() { throw new RuntimeException("예외 발생"); } } 애플리케이션이 예외를 처리하지 못한다면 예외는 서블릿 ..
로그인 처리를 위해 ArgumentResolver 를 사용하면 세션 정보를 활용하는 과정이 조금 더 편리해진다. 기존 방법에서는 HttpServletRequest 에서 직접 세션 정보를 꺼내서 사용하거나 @SessionAttribute 애노테이션으로 매핑해 사용했다. @SessionAttribute 애노테이션을 사용하면 그나마 간단해지기는 하지만 매번 name과 required를 설정해 주는 것도 꽤 번거로운 일이다. @Login 이라는 애노테이션을 직접 만들어 활용해 보자. @Login @Target(ElementType.PARAMETER) @Retention(RetentionPolicy.RUNTIME) public @interface Login { } @Target(ElementType.PARAMET..