본문 바로가기

스프링 부트58

[Error-Log] ORA-01861: literal does not match format string ORA-01861: literal does not match format string 리터럴이 형식 문자열과 일치하지 않음 해커톤 마감을 앞두고 로컬에선 잘만 되던 API가 EC2에선 400에러를 뱉는 상황이 있었습니다. OS의 LANG 설정이 달라 문자열을 날짜로 제대로 변환을 못해서 발생하는 이슈였습니다. 맥 OS와 아마존 리눅스 LANG 설정 차이 OS의 LANG에 대해 전혀 인지를 못해 발생했었습니다. 이런 경우 서로 서버의 LANG을 맞춰주는 것보단 조회 쿼리에서 데이트 포맷을 명시적으로 맞춰주는게 좋아보입니다. EC2 인스턴스가 여러가지 이유들로 교체될 수도 있고 로컬 Lang 또한 상황에 따라 바뀔수도 있기 때문입니다. NLS_LANG이란 것이 등장하는데 OS 계정의 환경 변수를 말합니다. .. 2022. 8. 25.
[스프링부트] 트랜잭션 격리 수준 트랜잭션에서 격리 수준은 일관성 없는 데이터를 허용하도록 하는 수준을 말한다. 격리 수준에는 4가지 종류가 있다. READ_UNCOMMITED READ_COMMITED REPEATABLE_READ SERIALIZABLE\ 숫자가 높아질수록 속도는 느려진다. READ_UNCOMMITED 트랜잭션 처리 중인거나 아직 커밋되지 않은 데이터를 다른 트랜잭션이 읽는 것을 허용한다. 그러나 Dirty Read라는 문제가 발생한다. Dirty Read는 트랜잭션이 완료되지 않았는데 다른 트랜잭션에서 볼 수 있는 현상을 말한다. READ_COMMITED 트랜잭션이 커밋된 데이터만 읽을 수 있다. 어떤 사용자가 A라는 데이터를 변경할때 다른 사용자는 접근할 수 없다. 그러나 Non-Repeatable Read 문제가 발.. 2022. 7. 13.
[스프링부트] Event 발행과 @EventListener에 대해 알아보자 이벤트란? 이벤트 발생이란 상태가 변경됨을 의미한다. 상태가 변경되고 해당 이벤트에 해당하는 동작을 수행하는 기능을 구현할 수 있다. 이벤트 생성 과정 이벤트 생성주체가 이벤트 생성 퍼블리셔가 이벤트 발행 이벤트 핸들러(구독자) 이벤트의 용도 트리거: 도메인 상태가 바뀔때마다 후처리가 필요할때 사용 다른 도메인 간의 동기화: 주문 도메인에서 배송지 변경 이벤트를 발생 시키고 구독자인 핸들러는 외부 배송 서비스와 이를 동기화하는 로직을 구성할 수 있다. 이벤트의 장점 연관 관계 제거 - 서로 다른 도메인 간의 의존 관계를 제거할 수 있다. 기능 확장 용이 - 구매 취소 시 환불과 함께 이메일 전송이 필요하다면 이메일 발송 이벤트를 구현하면 된다. 프로젝트에 적용하기 에어비앤비같은 숙소 예약 플랫폼을 제작하.. 2022. 7. 6.
[스프링 시큐리티] 주요 Security Filter들 정리 ChannelProcessingFilter 전송 레이어 보안을 위해 SSL(TLS) 인증서를 생성하고 어플리케이션에 저장한다. public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)res; FilterInvocation filterInvocation = new FilterInvocation(request, response, chain); Collection a.. 2022. 5. 24.
[스프링 시큐리티] FilterChainProxy 스프링은 많은 필터들을 제공하는데 그 중에서도 DelegatingFilterProxy가 시큐리티 필터를 제공한다. FilterChainProxy Spring Security의 구현은 서블릿 필터 (javax.servlet.Filter 인터페이스 구현체) 를 통해 이뤄진다. WebSecurityConfigurerAdapter라는 추상 클래스를 상속받는 구현체에서 설정할 수 있다.(@EnableWebSecurity 함께 사용) 그 구현체가 바로 DelegatingFilterProxy이 되는 것이다. SecurityFilterAutoConfiguration 클래스에서 DelegatingFilterProxy를 빈으로 자동 등록시킨다. @Bean @ConditionalOnBean(name = DEFAULT_FIL.. 2022. 5. 23.
[스프링 시큐리티] SecurityContextHolder SecurityContextHolder ThreadLocal을 기반으로 동작한다.WAS는 ThradPool을 생성한다. 요청이 들어오면 큐에 적재되고 특정 쓰레드가 큐에서 요청을 가져와 처리한다. HTTP 요청은 처음과 끝이 동일한 쓰레드에서 처리된다. 다 사용된 쓰레드는 반납처리 된다. 최대 동시 처리 요청 개수는 ThreadPool의 개수와 같다. 개수가 늘리면 동시 처리가 늘어나지면 Thread Context Switching에 의한 오버헤드 또한 커지기에 성능이 선형적으로 증가하진 않는다. -> WebFlux 같은 기술로 Thread 개수를 작게 유지하면서 요청을 동시처리할 수 있다. SecurityContext를 쓰레드와 연결해주는 역할을 한다. SecurityContextHolder를 통해 .. 2022. 5. 23.
[스프링 시큐리티] AuthenticationManager, AccessDecisionManager AuthenticationManager 사용자 인증 관련 처리를 담당한다. 오직 authenticate라는 메소드만 가진다. Authentication는 getAuthorities(), getCredentials(), getPrincipal() 등 인증 정보를 가져올 수 있고 setAuthenticated(boolean)를 통해 인증처리를 할 수 있다. 인증 정보가 유효하다면 UserDetailService에서 return한 객체(principal)을 담고있는 Authentication을 리턴한다. AccessDecisionVoter들의 투표(vote)결과를 취합하고, 접근 승인 여부를 결정하는 3가지 구현체를 제공한다. AffirmativeBased(default) — AccessDecisionVote.. 2022. 5. 23.
[스프링 시큐리티] PasswordEncoder PasswordEncoder 인터페이스는 암호가 안전하게 저장되도록 단방향 변환을 수행해준다. 보통 SHA-256 같은 단방향 해시를 통해 암호를 실행한 후 저장한다. 그러나 레인보우 테이블 같은 조회 테이블때문에 암호의 보안을 더 강화해야 했다. 레인보우 테이블이란 암호화 해시 함수의 출력을 캐싱하기 위해 미리 계산된 테이블을 말한다. 제한된 문자 집합으로 구성된 특정 길이까지 키 파생 함수를 복구하는데 사용된다. 무차별 대입 공격보다 더 적은 처리 시간을 가지지만 많은 저장 공간을 사용한다. 따라서 솔티드 암호가 권장되었다. 비밀번호를 사용하는 대신 임의의 추가 바이트를 덧붙여 해시 함수를 통해 해시를 생성한다. 따라서 레인보우 테이블이 효과적이지 않게 되었다. 스프링은 따라서 각 시스템에 맞는 성능.. 2022. 5. 23.
[스프링] Statement 대신 PreparedStatement를 사용해야 하는 이유 PreparedStatement를 사용해야 하는 이유 Statement는 캐시를 사용하지 않고 PreparedStatement는 캐시를 사용해 담긴 객체들을 재사용한다. 반복적이고 많은 쿼리를 날릴때 PreparedStatement가 성능이 좋다. statement는 불편한 연결 과정과 처리를 쿼리마다 반복해야 한다. 가독성도 좋지 못하고 비효율적이다. connection 뿐만 아니라 statement, resultSet 모두 처리를 해야 한다. Connection connection = null; try { connection = dataSource.getConnection(); if(connection != null) { System.out.println("DB 연결 성공!"); } } catch (.. 2022. 4. 19.
[Error-Log] MultipleBagFetchException 해결법 발단: 예전에 프로젝트를 진행하다가 EntityGraph를 사용해 Nested된 클래스들을 가져오는 코드를 짰었다. 그러나 메소드를 실행하는 과정에서 MultipleBagFetchException 예외가 터졌다. 원인은 여러 개의 oneToMany 관계를 가져와서였다. Bag이란? Hibernate에는 Bag이라는 컬렉션 타입이 있다. 자바 프레임워크가 아닌 요소이며 List와 비슷하게 중복 요소를 포함하나 순서가 보장되진 않는 컬렉션이다. 스프링 JPA에서는 기본적으로 컬렉션을 사용해 Many 관계를 매핑한다. Hibernate는 이러한 컬렉션을 Hibernate에서 만든 컬렉션으로 감싼다. List -> PersistentBag Set -> PersistentSet Map -> PersistentM.. 2022. 4. 16.
[인텔리제이] tdd 템플릿 만들기 매번 given when then 을 치기가 귀찮아서 만들었다 인텔리제이 -> Preferences -> live templates -> +버튼 -> Live Template 이름에 tdd 입력해주고 내용에 아래 코드를 집어 넣는다. @Test public void (){ //given //when //then } 사용할때는 tdd만 입력해주면 알아서 만들어지니 편리하다 2022. 4. 11.
[스프링] 빈 등록 Bean, Configuraition, Component 비교 Bean이란? IOC 컨테이너에 의해 관리되는 객체를 말한다. 스프링 DI 컨테이너에 의해 관리되는 POJO를 빈이라고 부른다. 스프링은 이를 싱글톤 객체로 생성하고 관리한다. 빈 등록 방법 @Bean - 수동 @Configuration - 수동 @Component - 자동 [수동 등록] Bean, Configuration 설정 클래스에 Configuration을 붙이고 그 안에 Bean 어노테이션으로 스프링 컨테이너에 빈을 생성한다. 개발자가 제어 불가능한 라이브러리를 쓸 때 전범위로 사용되는 클래스를 등록할때 다형성으로 여러 구현체를 등록할때 사용한다. [자동 등록] Component 스프링이 직접 클래스를 검색해 빈으로 등록해주는 기능이다. @Component를 가진 모든 대상을 가져와 빈에 등록한.. 2022. 4. 6.