-
2022-07-25 : JAVATIL ( Today I Learned ) 2022. 7. 25. 14:06
1.GSON
: json구조를 띄는 직렬화된 데이터를 JAVA의 객체로 역직렬화, 직렬화 해주는 자바 라이브러리이다.
즉, JSON Object → JAVA Object 또는 그 반대의 행위를 돕는 라이브러리이다.
2. @NonNull, @Nullable
@NonNull : null을 허용하지 않는 경우
@Nullable : null을 허용하는 경우
3. @Async를 이용한 비동기 처리
- @Async : 비동기적으로 처리를 할 수 있게끔 스프링에서 제공하는 어노테이션
ㆍ해당 어노테이션을 붙이게되면 각기 다른 쓰레드로 실행된다.
즉, 호출자는 해당 메서드가 완료되는 것을 기다릴 필요가 없다.
- 이 어노테이션을 사용하기 위해서는 @EnableAsync가 달려있는 configuration클래스가 우선적으로 필요
@Configuration @EnableAsync public class AsyncConfig { }
- @Async 어노테이션을 사용하기 위한 2가지 제약조건
ㆍpublic 메서드일 것 : 프록시를 사용하기 위해
ㆍ동일 클래스에서 호출하는 Self-invocation이어서 안됨 : 프록시를 무시하고 바로 메서드를 호출하기에
- 기본적으로 스프링은 비동기적으로 메서드를 실행하기 위해서 SimpleAsyncTaskExecutor을 사용
( SimpleAsyncTaskExecutor는 요청이 오는대로 계속해서 쓰레드를 생성 )
@Configuration @EnableAsync public class AsyncConfig { @Bean("customAsyncExecutor") public Executor customAsyncExcutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(5); executor.setThreadNamePrefix("bepoz"); executor.initialize(); // 꼭 써줘야 한다. return executor; } }
@Service @Slf4j public class AsyncService { @Async("customAsyncExecutor") public void call() { log.info("async Test"); } }
참고자료 : https://bepoz-study-diary.tistory.com/399
4. 스프링 메세지 소스 ( Spring MessageSource )
: 스프링 메세지 소스는 국제화을 제공하는 인터페이스,
메시지 설정 파일을 모아놓고 각 국가마다 로컬라이징을 함으로서 쉽게 각 지역에 맞춘 메세지를 제공
- 메세지 설정 파일 셋업
: .properties 확장자가 붙은 프로퍼티 파일에 [파일이름]_[언어]_[국가].proerties 형식으로 메시지파일 추가
ㆍmessage.properties : 기본메시지, 시스템의 언어 및 지역에 맞는 프로퍼티 파일 존재X시 사용
ㆍmessage_en.properties : 영어메시지
ㆍmessage_ko.properties : 한글메시지
ㆍmessage_en_UK.properties : 영국을 위한 영어 메시지
- 사용 방법
@Component public class ex { @Autowired MessageSource messageSource; public void use() { System.out.println(messageSource.getMessage("greeting", new String[]{"haha"},Locale.KOREA)); }
+ ReloadableResourceBundleMessageSource 객체를 통한 MessageSour 리로딩
- ReloadableResourceBundleMessageSource객체의 메세지 리로딩 방법
@Bean public MessageSource messageSource() { ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); messageSource.setBasename("classpath:/messages"); messageSource.setDefaultEncoding("UTF-8"); messageSource.setCacheSeconds(10); return messageSource; }
참고자료 : https://engkimbs.tistory.com/717
* classpath : 빌드시 컴파일된 class 파일들의 위치 경로
- classpath는 기본 entry가 src/main/java, src/main/resources로 잡혀있고, 빌드결과인 output은 target/classes에 저장
참고자료 : https://engkimbs.tistory.com/717
5. MyBatis - resultMap
: 복잡한 결과 매핑을 간편하게 만들어주기 위해 만들어진 태그
<resultMap id="testMap" type="User객체경로.User"> <result column="user_id" property="id" jdbcType="NVARCHAR" javaType="String"/> <result column="user_name" property="username" jdbcType="NVARCHAR" javaType="String"/> <result column="hashed_password" property="hashedPassword" jdbcType="NVARCHAR" javaType="String"/> </resultMap> <select id="selectUsers" resultMap="testMap"> select user_id, user_name, hashed_password from some_table where id = #{id} </select>
참고자료 : https://yeonyeon.tistory.com/131
6. @Valid와 BindingResult
@Valid : @RequestBody 옆에 @Valid를 작성하면, RequestBody로 들어오는 객체에 대한 검증 수행
이 검증의 세부적인 사항은 객체 안에 정의해두어야한다.
ㆍ@NotNull : 인자로 들어온 필드 값에 null 값을 허용하지 않는다
ㆍ@Eamil : 인자로 들어온 값을 Email 형식을 갖추어야한다.
ㆍ더 많은 검증 어노테이션은 참고자료를 확인
+ @Valid시 발생하는 Exception Handling
- @ControllerAdvice를 이용한 전역 에러 핸들링, 혹은 @Controller단에서의 지역 에러 핸들링을 사용하면 된다
- @ExceptionHandler 어노테이션을 지정하여 커스템 에러 핸들링
@RestControllerAdvice public class ApiControllerAdvice { @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<Map<String, String>> handleValidationExceptions(MethodArgumentNotValidException ex){ Map<String, String> errors = new HashMap<>(); ex.getBindingResult().getAllErrors() .forEach(c -> errors.put(((FieldError) c).getField(), c.getDefaultMessage())); return ResponseEntity.badRequest().body(errors); } }
- ResponseEntity 값으로, error가 난 field 갑과, 에러메시지를 Map형태로 만들어서, Response로 넣어줌
- Map으로 선언하여 forEach를 한 이유는 @Valid를 사용할 때, 해당 객체에서 valid에 실패한 내용을 모두 리턴해주기 때문에, 모든 error 값을 수용
참고자료 : https://jyami.tistory.com/55
7. BindingResult
: ModelAttribute을 이용해 매개변수를 Bean에 binding할 때 발생한 오류 정보를 받기 위해 선언해야하는 애노테이션
8. HttpServletRequest
- 웹브라우저 사용자인 클라이언트로부터 서버로 요청이 들어오면 서버에서는 HttpServletRequest를 생성하며, 요청정보에 있는 패스로 매핑된 서블릿에게 전달한다.
- Http 프로토콜의 request정보를 서블릿에게 전달하기 위한 목적으로 사용
- Header정보, Parameter, Cookie, URI, URL 등의 정보를 읽어들이는 메소드를 가진 클래스
- Body의 Stream을 읽어들이는 메소드를 가지고 있음
+ HttpServletResponse
- Servlet은 HttpServletResponse 객체에 COntent Type, 응답코드, 응답메시지등을 담아서 전송
9. Servlet
: 클라이언트의 요청을 처리하고, 그 결과를 반환하는 Servlet 클래스의 구현 규칙을 지킨 자바 웹 프로그래밍 기술
- 특징
ㆍ클라이언트의 요청에 대해 동적으로 작동하는 웹 어플리케이션 컴포넌트
ㆍhtml을 사용하여 요청에 응답한다
ㆍJava Thread를 이용하여 동작한다
ㆍMVC패턴에서 Controller로 이용된다
ㆍHTTP 프로토콜 서비스를 지원하는 javax.servlet.http.HttpServlet 클래스를 상속받는다.
ㆍUDP보다 처리 속도가 느리다
ㆍHTML 변경시 Servlet을 재컴파일해야 하는 단점이 있다
- Servlet 동작 방식
1. 사용자(클라이언트)가 URL을 입력하면 HTTP Request가 Servlet Container로 전송
2. 요청을 전송받은 Servlet Container는 HttpServletRequest, HttpServletResponse 객체를 생성
3. web.xml을 기반으로 사용자가 요청한 URL이 어느 서블릿에 대한 요청인지 찾는다.
4. 해당 서블릿에서 service메소드를 호출한 후 클라이언트의 GET, POST여부에 따라 doGet() 또는 doPost() 호출
5. doGet() or doPost() 메소드는 동적 페이지를 생성한 후 HttpServletResponse 객체에 응답
6. 응답이 끝나면 HttpServletRequest, HttpServletResponse 두 객체를 소멸
10. HashMap과 keySet, EntrySet
HashMap
- 키와 값으로 구성된 객체를 저장하는 구조로 되어 있는 자료구조를 구현한 클래스
- 순서가 유지되지 않는다. ( 순서유지가 필요하다면 LinkedHashMap )]
- hashing 기법을 사용하기 때문에 많은 양의 데이터가 저장될 때 유용, 검색에 최고성능
- 추가/삭제/검색/접근성 모두 뛰어남
keySet, EntrySet
- Map 전체를 순회하기 위해서는 entrySet(), keySet() 메소드를 사용
ㆍentrySet() : key와 value의 값이 모두 필요한 겨우
ㆍkeySet() : key의 값만 필요한 경우
entrySet()
: Map에 저장되어있는 Entry객체들을 반환한다. Entry객체는 키(Key)와 값(Value)의 쌍(Pair)을 저장하는 객체로 getKey()와 getValue() 메소드로 각각의 값을 가지고 올 수 있다
keySet()
: Map에 저장되어있는 키(Key)들을 반환한다. get()메소드로 키(Key)에 대응되는 값(Value)를 가지고 올 수 있다.
참고자료 : https://fvor001.tistory.com/49
11. enum
- 관련이 있는 상수들의 집합
- 자바에서 final로 String과 같은 문자열이나 숫자들을 나타내는 기본 자료형의 값을 고정
- 어떤 클래스가 상수만으로 작성되어 있으면 반드시 class로 선언할 필요는 없다.
- 이럴 때 class로 선언된 부분에 enum이라고 선언하면 이 객체는 상수의 집합
참고자료 : https://www.nextree.co.kr/p11686/
12. Cipher
- Java에는 암호화, 복호화를 쉽게 도와주는 Cipher 클래스 존재
- Cipher 객체를 생성하기 위해서는 getInstance() 메서드를 호출
- getInstance() 의 인자로 "알고리즘" 또는 "알고리즘/모드/패딩" 형식으로 암호화 방식 지정 가능
- Java Cipher 객체 인스턴스화
// Cipher cipher = Cipher.getInstance("알고리즘 종류/모드/패딩"); Cipher cipher1 = Cipher.getInstance("DES/CBC/NoPadding"); Cipher cipher2 = Cipher.getInstance("AES/CBC/NoPadding"); Cipher cipher3 = Cipher.getInstance("AES/ECB/PKCS5Padding"); Cipher cipher4 = Cipher.getInstance("DESede/CBC/NoPadding"); Cipher cipher5 = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); ...
- SecretKeySpec
: 비밀키를 생성하는 클래스
ㆍKeySpec, SecretKey 인터페이스를 구현한 클래스
ㆍ생성자를 통해 비밀키 생성
ㆍ생성자에 입력되는 파라미터들로 byte[] key, String algorithm 입력
byte[] key = new byte[] { 2, 6, 7, 13, 3, 7, 8, 9 }; // SecretKeySpec secretKeySpec = new SecretKeySpec(byte[] key, "algorithm"); SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
- IvParameterSpec
: DES CBC 모드나 RSA OAEP 모드같은 IV를 사용하는 *feedback 모드의 암호화에서 초기화 벡터(IV)를 생성
ㆍAlgorithmParameterSpec 인터페이스를 구현한 클래스
ㆍ생성자를 통해 IV를 생성
ㆍ생성자에 입력되는 파라미터로 byte[] iv를 입력
byte[] iv = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }; IvParameterSpec ivSpec = new IvParameterSpec(iv);
- Cipher.init
: Cipher 객체 초기화
ㆍCipher의 작동 모드를 설정하는 opmode 설정
ㆍ인증서(certificate), 키(Key), 초기 벡터(IV) 등을 파라미터로 입력
- 작동 모드 설정하는 opmode의 종류
ㆍENCRYPT_MODE : 암호화 모드로 작동
ㆍDECRYPT_MODE : 복호화 모드로 작동
ㆍWRAP_MODE : Key_Wrapping 모드로 작동
ㆍUNWRAP_MODE : Key_Unwrapping 모드로 작동
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
- Cipher.doFinal
: Cipher 객체 초기화 후 실제 작업(암호화, 복호화)을 수행하기 위한 doFinal() 메서드 호출
ㆍ입력한 byte[] 배열 평문을 암호화, 복호화 된 byte[] 배열로 반환
return cipher.doFinal(plaintextBytes);
'TIL ( Today I Learned )' 카테고리의 다른 글
2022-07-27 : 파일업로드 & buffer, 기타 등등 (0) 2022.07.27 2022-07-26 : Git (0) 2022.07.26 2022-07-21 : Git (0) 2022.07.21 2022-07-18 : JS (0) 2022.07.18 2022-7-15 : react / JS / TS (0) 2022.07.15