Bean Validation 꼼꼼하게 사용하기

목표 복잡한 구조의 클래스의 bean validation 적용 방법을 이해한다. nested child object의 검증 방법 Java bean validation은 기본적으로 검증하고자 하는 클래스에도 @Valid 어노테이션을 붙여줘야된다. @Valid 어노테이션은 field나 getter에 붙여줄 수 있다. data class Project( @field:NotBlank(message = "Project title must be present") @Size(min = 3, max = 20, message = "Project title size not valid") private val title: String, @field:Valid private val owner: User, ) data class User( @field:NotBlank(message = "User name must be present") @field:Size(min = 3, max = 50, message = "User name size not valid") private val name: String, @field:NotBlank(message = "User email must be present") @field:Email(message = "User email format is incorrect") private val email: String, ) 이유 Java bean validation이 nested child object 를 자동으로 스캔해서 검증해준다면, @Valid 어노테이션을 매번 직접 명시하지 않아도 되어서 편리할 것이라고 생각할 수 있다....

2025-05-20 · 2 min · 300 words

JsonPath 문법

배경 통합 테스트에서 WebTestClient를 사용하고 있는데 응답 바디 assertion에서 내부적으로 JsonPath 방식으로 응답 바디의 경로를 지정해 검증하고 있다. 좀 더 유연한 테스트 코드 작성을 위해 JsonPath 표현식 작성법을 이해한다. 표기법 JsonPath 표현식에는 2가지의 표기법이 존재한다. 점 표기법: $.players[0].nickname 괄호 표기법: $['players'][0]['nickname'] 연산자 연산자 설명 $ 루트 노드 @ 처리하고 있는 현재 노드 * 와일드카드. 숫자나 이름이 필요한 모든 곳에서 사용 가능하다. .. Deep scan. 이름이 필요한 모든 곳에서 사용 가능하다. ....

2024-11-06 · 2 min · 385 words

DecimalFormat

목표 DecimalFormat 클래스의 기본 사용법을 이해한다. DecimalFormat String 타입으로 십진수를 표현할 때 사용할 수 있다. 아래 예시는 double d= 1234567.89 으로 설명한다. 0: 숫자가 존재하면 그 숫자를 출력하고, 없으면 0을 출력한다. #: 숫자가 존재하면 그 숫자를 출력하고, 없으면 출력하지 않는다. .: 소수점 구분 기호를 넣을 위치를 표시한다. 만약 소수 부분에서 더 이상 표현할 수 없다면 반올림 된다. ,: 그루핑 구분자가 들어갈 위치를 표시한다. 참고 자료 https://www.baeldung.com/java-decimalformat

2024-10-02 · 1 min · 66 words

Java에서 DNS 캐시 TTL 설정

배경 DNS LookUp을 통해 도메인에 대한 IP 정보를 조회한다. JVM에서는 이런 IP 정보를 캐싱해서 매번 DNS LookUp을 하지 않는다. TTL을 설정하면 캐시가 남아 있는 주기를 설정할 수 있다. security 파일 수정으로 TTL 변경하기 Java 8 기준 $JAVA_HOME/jre/lib/security/java.security, Java 11 이상 기준 $JAVA_HOME/conf/security/java.security 파일에 있는 networkaddress.cache.ttl 프로퍼티 값을 설정하면 변경할 수 있다. 아래 예시는 TTL을 5초로 수정하는 예시다. # # This is the "master security properties file". # # An alternate java....

2024-10-01 · 1 min · 134 words

파일을 통해서 ContentType 찾아오는 법

Java 표준 중에 Files.probeContentType() 메소드를 사용하면 쉽게 확인할 수 있다. @Test public void whenUsingJava7_thenSuccess() { Path path = new File("product.png").toPath(); String mimeType = Files.probeContentType(path); assertEquals(mimeType, "image/png"); } https://www.baeldung.com/java-file-mime-type 파일 이름만으로 유추하는 방법도 있다. String mimeType = URLConnection.guessContentTypeFromName(file.getName()); https://stackoverflow.com/questions/9670040/what-is-the-best-approach-to-identify-a-specific-file-type-in-java

2024-09-15 · 1 min · 38 words

파일 전체 읽기

@Test public void whenReadSmallFileJava7_thenCorrect() throws IOException { String expected_value = "Hello, world!"; Path path = Paths.get("src/test/resources/fileTest.txt"); String read = Files.readAllLines(path).get(0); assertEquals(expected_value, read); } Files를 이용하면 쉽게 파일 전체를 읽을 수 있다. https://www.baeldung.com/reading-file-in-java

2024-09-15 · 1 min · 32 words

특정 패키지에 있는 클래스들의 빈 생성자 전부 호출하기

1. 특정 패키지에 있는 클래스 가져오기 이전에 학습했던 System Class Loader를 이용하면 특정 패키지에 있는 모든 클래스를 가지고 올 수 있다. private Set<Class<?>> findAllClassesUsingClassLoader(String packageName) { final InputStream stream = ClassLoader.getSystemClassLoader() .getResourceAsStream(packageName.replaceAll("[.]", "/")); final BufferedReader reader = new BufferedReader(new InputStreamReader(Objects.requireNonNull(stream))); return reader.lines() .filter(line -> line.endsWith(".class")) .map(line -> getClass(line, packageName)) .collect(Collectors.toSet()); } private Class<?> getClass(String className, String packageName) { final String classPath = packageName + "." + className.substring(0, className.lastIndexOf('.')); try { return Class....

2024-09-15 · 1 min · 201 words

특정 디렉토리에 있는 전체 파일 가져오기

Files.walk 메소드는 현재 입력받은 경로로부터 파일 트리를 전부 탐색해서 stream 으로 반환한다. Files.walk(Paths.get("folder")) .filter(Files::isRegularFile) .forEach(System.out::println); folder\file1.txt folder\file2.txt folder\subfolder\file3.txt folder\subfolder\file4.txt 현재 디렉토리에 있는 파일만 가져올 경우는 list() 메소드를 사용하면 된다. Files.list(Paths.get("folder")) .filter(Files::isRegularFile) .forEach(System.out::println); folder\file1.txt folder\file2.txt https://stackoverflow.com/questions/1844688/how-to-read-all-files-in-a-folder-from-java https://docs.oracle.com/javase/8/docs/api/java/nio/file/Files.html

2024-09-15 · 1 min · 36 words

타입 소거

목표 타입 소거의 의미를 이해한다. 타입 소거가 필요한 이유를 이해한다. 타입 소거의 의미 타입 파라미터에 대해서 컴파일 타임에만 타입 검사를 하고 런타임에는 타입에 대한 정보를 삭제하는 방식 아래와 같은 코드가 있다고 가정하면 public static <E> boolean containsElement(E [] elements, E element){ for (E e : elements){ if(e.equals(element)){ return true; } } return false; } 런타임에는 아래와 같이 동작한다. unbound 타입인 E가 Object 타입으로 치환되었다. public static boolean containsElement(Object [] elements, Object element){ for (Object e : elements){ if(e....

2024-09-15 · 2 min · 244 words

입출력

Java에서 입출력시 InputStream과 OutputStream을 사용한다. 이 들은 각각 추상 클래스기 때문에 별도의 구현체를 사용한다. Byte Stream 데이터를 바이트 단위로 주고 받을 때 사용한다. InputStream BytesArrayInputStream: 바이트 배열을 읽기 위해서 내장된 버퍼를 사용한다. FileInputStream: 파일을 바이트 단위로 읽기위해서 사용한다. FilterInputStream: InputStream에 추가 기능을 사용하기 위해서 사용한다. 이는 다른 InputStream을 포함하고 있어야되면 단독으로 사용은 불가능하다. BufferedInputStream: 입력 성능을 개선하기 위해 사용한다. 특정 크기(기본값 8bytes)만큼의 버퍼를 할당한 후 데이터를 미리 읽고 저장한다. 이후 주가적인 읽기 작업이 필요하면 버퍼의 크기를 늘려 읽기를 실행시킨다....

2024-09-15 · 2 min · 321 words

이미지 리사이징 및 압축

이미지 처리 방법 Java에서 이미지 처리하는 방법에는 여러 가지가 있다. AWT: Java 기본 라이브러리로 창 생성, 버튼 등의 GUI와 관련된 처리를 할 수 있도록 도와주는 라이브러리다. ImageJ: 이미지 작업을 위해 만들어진 라이브러리다. 만들어진 목적이 GUI가 아니라 처음부터 이미지 처리였기때문에 이미지 처리에대해 좋은 기능이 많이 있다. OpenIMAJ: 비디오, 오디오 처리나 머신 러닝 등의 작업을 할 수 있다. 이 라이브러리를 통해서도 이미지 처리를 할 수 있다. TwelveMonkeys ImageIO: Java 기본 라이브러리인 ImageIO를 확장한 형태다....

2024-09-15 · 3 min · 578 words

여러 개의 숫자 중 최대 값 찾기

Math.max(12.123, 12.456) 참고 자료 https://www.tutorialspoint.com/java/number_max.htm

2024-09-15 · 1 min · 5 words

얕은 복사, 깊은 복사 그리고 배열의 복사

문제 풀이 중 배열의 복사 과정이 빈번히 일어나는 경우가 있었다. 매번 반복문을 이용해서 복사하는 과정을 간략하게 작성할 수 있는 방법이 있을 것 같아서 정보를 찾게 되었다. 얕은 복사? 깊은 복사? 복사에 대해서 이해하기 위해서는 얕은 복사와 깊은 복사를 이해할 필요가 있다. 얕은 복사: 복사본에 원본 데이터의 포인터를 가리키도록 하는 방법이다. 상대적으로 복사가 빠르지만, 원본 데이터의 값을 수정하면 함께 값이 변하므로 유의해야 된다. 깊은 복사: 복사본에 원본 데이터의 값들을 직접 복사하는 방법이다....

2024-09-15 · 1 min · 142 words

소켓 통신 시 BufferdReader가 입력을 기다리지 않는 문제

기존 코드 while (bufferedReader.ready()) { ... } 이렇게 구현하니 클라이언트가 데이터를 보내기전에 여기에오면 그냥 통과해버리는 문제가 있었다. 현재 코드 while (Objects.nonNull(line = bufferedReader.readLine())) { ... } 어차피 readLine() 메소드는 다음 입력이 오기전까지 대기하기 때문에 ready() 없이 해결할 수 있었다. 참고 자료 https://stackoverflow.com/questions/19353133/block-bufferedreader-until-data-appears

2024-09-15 · 1 min · 42 words

로깅 테스트하기

logback 구현체를 통해서 appender를 추가해서 테스트를 진행할 수 있다. ListAppender를 사용하면 로깅 내용을 메모리로 저장할 수 있다. class ReflectionsTest { private static final Logger log = (Logger) LoggerFactory.getLogger(ReflectionsTest.class); private static final ListAppender<ILoggingEvent> listAppender = new ListAppender<>(); static { listAppender.setContext((LoggerContext) LoggerFactory.getILoggerFactory()); log.setLevel(Level.DEBUG); log.addAppender(listAppender); listAppender.start(); } @Test void someTest() { //... assertThat(result).contains("[DEBUG] examples.QnaController", "[DEBUG] examples.MyQnaService", "[DEBUG] examples.JdbcUserRepository", "[DEBUG] examples.JdbcQuestionRepository"); } } 참고 자료 https://www.baeldung.com/junit-asserting-logs

2024-09-15 · 1 min · 62 words

개행 문자

운영체제마다 개행을 나타내는 특수 문자가 다르다. 리눅스, 유닉스, 맥은 , 윈도우는 \r 를 사용한다. 플랫폼에 독립적인 코드를 작성하고 싶다면 %n 을 사용하거나 System.lineSeparator() 메소드를 사용해야된다. 참고 자료 https://www.baeldung.com/java-string-newline

2024-09-15 · 1 min · 28 words

Url Encoding, Decoding 하기

URLEncoder.encode(value, StandardCharsets.UTF_8.toString()); URLDecoder.decode(value, StandardCharsets.UTF_8.toString()); https://www.baeldung.com/java-url-encoding-decoding

2024-09-15 · 1 min · 5 words

UnaryOperator T 함수형 인터페이스

T를 인자로 받고 T를 반환한다.

2024-09-15 · 1 min · 5 words

TreeSet

지속적으로 정렬 상태를 유지하면서, 새로운 데이터가 추가/삭제가 자주 일어나는 경우가 있었다. 쉽게 말해서 균형 잡힌 이진 트리인 레드 블랙 트리를 사용해야 됐다. TreeSet은 Set 인터페이스의 구현체다. 대표 메서드 TreeSet에서 사용되는 대표적인 메서드를 정리해본다. E floor(E e): e 이하인 객체 중 가장 큰 값을 리턴한다. 없으면 null이 리턴된다. O(log n) E ceiling(E e): e 이상인 객체 중 가장 작은 값을 리턴한다. 없으면 null이 리턴된다. O(log n) E higher(E e): e 초과인 객체 중 가장 작은 값을 리턴한다....

2024-09-15 · 1 min · 126 words

transient란

Serializable 을 구현한 클래스에서 필드 중에 직렬화를 원치 않는 필드에 붙이면 된다. public class DispatcherServlet extends HttpServlet { private static final long serialVersionUID = 1L; private static final Logger log = LoggerFactory.getLogger(DispatcherServlet.class); private static final HandlerAdapter HANDLER_ADAPTER = new DefaultHandlerAdapter(); private final transient HandlerMappings handlerMappings; public DispatcherServlet() { this.handlerMappings = new HandlerMappings(); } //... } https://nesoy.github.io/articles/2018-06/Java-transient

2024-09-15 · 1 min · 56 words