문제발생관리자가 원하는 날짜의 주문판매현황을 조회한 후 이메일로 전송받는 로직의 테스트코드이며 테스트 메서드 자체에는 문제가 없지만 테스트의 독립성을 위해 테스트 후 deleteAllInBatch() 메서드를 통해 저장소를 비우는 과정에서 예외가 발생한듯 하였다. @SpringBootTestclass OrderStatisticsServiceTest { @Autowired OrderStatisticsService orderStatisticsService; @Autowired OrderRepository orderRepository; @Autowired ProductRepository productRepository; @AfterEach void tearDown()..
웹 애플리케이션은 클라이언트의 로그인 여부(인증)를 확인하기위해서 서버는 아래 3가지 방법을 대표적으로 사용한다.쿠키세션토큰==쿠키방식의 단점==보안에 취약하다쿠키에는 용량 제한이 있어 많은 정보를 담을 수 없다웹 브라우저마다 쿠키에 대한 지원 형태가 다르기때문에 브라우저간 공유가 불가능하다쿠키의 사이즈가 커질수록 네트워크에 부하가 심해진다==세션방식의 단점==세션 ID자체를 탈취당하는 보안문제가 있다서버에서 세션을 유지하기때문에 stateless하지않다토큰 인증토큰 기반 인증 시스템은 클라이언트가 서버에 접속을 하면 서버에서 해당 클라이언트에게 인증되었다는 의미로 '토큰'을 부여한다. 이 토큰은 유일하며 토큰을 받는 클라이언트는 또 다시 서버에 요청을 보낼 때 요청 헤더에 토큰을 심어서 보냄으로써 서버..
![[Spring] 서블릿 필터와 스프링 인터셉터 비교하기!](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdna%2FqNoS3%2FbtsIWfzYzbv%2FAAAAAAAAAAAAAAAAAAAAABj05hpDxrZeWYksBVdoYCLvR-gv03f6fSxmrL4AFWsc%2Fimg.png%3Fcredential%3DyqXZFxpELC7KVnFOS48ylbz2pIh7yKj8%26expires%3D1756652399%26allow_ip%3D%26allow_referer%3D%26signature%3DSiWjYGZOKyf4xfF7mXAZrOvPXLw%253D)
일반적인 웹 페이지는 로그인한 사용자와 로그인하지 않은 사용자를 구분하여 역할에 맞는 기능을 제공해야한다.먼저, 프론트 화면처리로 로그인하지 않은 사용자에게는 상품관리라는 버튼을 숨겨서 기능을 제공하지 않을 수 있지만, URL경로를 직접 호출하게 된다면 프론트 처리만으로는 서비스에 제한을 둘 수 없다.이런 로그인 여부확인은 회원가입, 정보수정, 삭제 등등 많은 서비스에서 사용되는데 여러 곳에서 공통으로 사용되는 로직을 웹에서는 스프링인터셉터를 사용하여 웹과 관련된 공통 관심사를 처리할 수 있다.서블릿 필터필터는 서블릿 스펙의 일부로 스프링 MVC와는 독립적으로 동작하며 모든 요청에 대해 동작할 수 있다.javax.servlet.Filter인터페이스를 사용한다.모든 HTTP요청에 대해 공통적으로 처리해야 ..
MyBatis에서는 기본적으로 JdbcTemplate이 제공하는 대부분의 기능을 제공한다.추가적으로 아래와 같은 장점을 가지고있다.SQL을 XML을 통해 편리하게 작성, 관리동적 쿼리를 태그로 편리하게 작성설정JdbcTemplate은 스프링에 내장된 기능으로 별도의 설정없이 사용할 수 있다.반면에 MyBatis는 약간의 설정이 필요하다.실무에서는 프로젝트에 동적쿼리와 복잡한 쿼리가 많다면 MyBatis를 사용하고 단순한 쿼리들이 많다면 JdbcTemplate을 선택해서 사용하면된다.물론 이 둘을 함께 사용할수도 있다.MyBatis공식 사이트https://mybatis.org/mybatis-3/ko/index.html동적 쿼리에 대한 문서https://mybatis.org/mybatis-3/ko/dynam..
![[JAVA] 예외 계층](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdna%2Fc3DqoE%2FbtsIrdDE7TN%2FAAAAAAAAAAAAAAAAAAAAALQqDNPX9iV_YX1rO4SMLJxM1XjmWA6csQ0ZEVW79tq_%2Fimg.png%3Fcredential%3DyqXZFxpELC7KVnFOS48ylbz2pIh7yKj8%26expires%3D1756652399%26allow_ip%3D%26allow_referer%3D%26signature%3D52MIGUV7fEQeY3jNbeVBvVJbtZA%253D)
Throwable: 최상이 예외Error: 메모리 부족이나 심각한 시스템 오류와 같이 애플리케이션에서 복구가 불가능한 시스템 예외Exception애플리케이션 로직에서 사용할 수 있는 실질적인 최상위 예외Exception과 그 하위 예외는 모두 컴파일러가 체크하는 체크 예외이다. 단 RuntimeException은 예외RuntimeException: 언체크 예외, 런타임 에외컴파일러가 체크하지 않는 언체크 예외RuntimeException과 그 자식 에외는 모두 언체크 예외이다사용자 정의 예외 계층예외 계층화의 장점부모의 예외를 잡거나 던지면 자식 예외도 함께 잡거나 던질 수 있다특정 예외를 잡아서 처리하고 싶다면 하위예외를 잡아서 따로 처리하면 된다사용자정의 최상위 예외public class Networ..
em.find() vs em.getReference()em.find()데이터베이스를 통해서 실제 엔티티 객체를 조회em.getReference()데이터베이스 조회를 미루는 가짜 엔티티 객체 조회Member member = new Member(null, "memberA"); em.persist(member); em.flush(); em.clear(); Member findMember = em.find(Member.class, member.getId()); System.out.println("findMember = " + findMember); tx.commit();find()로 멤버를 조회할 시에는 findMember변수의 사용 여부와 관계없이 메서드가 실행되는 시점에 즉시 실제 데이터베이스로부..
![[JAVA] 자바의 정렬 인터페이스 Comparable과 Comparator](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdna%2F82ETj%2FbtsIokhcnV1%2FAAAAAAAAAAAAAAAAAAAAAGLOsOIxPaJPedf2JMjL8DSruk4WoGT9VlT8RiNGvHhk%2Fimg.png%3Fcredential%3DyqXZFxpELC7KVnFOS48ylbz2pIh7yKj8%26expires%3D1756652399%26allow_ip%3D%26allow_referer%3D%26signature%3D8rghJra5eptVqmwSuadl9o1buGE%253D)
자바에서 배열에 대해 정렬을 하고싶다면 어떻게해야할까?코드를 통해 살펴보자import java.util.Arrays; public class SortMain1 { public static void main(String[] args) { Integer[] array = {3, 2, 1}; System.out.println(Arrays.toString(array)); System.out.println("기본 정렬 후"); Arrays.sort(array); System.out.println(Arrays.toString(array)); } }실행결과[3, 2, 1]기본 정렬 후[1, 2, 3]util패키지의 ..
import java.util.Arrays; public class HashStart1 { public static void main(String[] args) { Integer[] inputArray = new Integer[4]; inputArray[0] = 1; inputArray[1] = 2; inputArray[2] = 5; inputArray[3] = 8; System.out.println(Arrays.toString(inputArray)); int searchValue = 8; for (int inputValue : inputArray) { ..