Swagger 도입 Api Test, 설명UI 깔끔 build.gradle에 추가 implementation("io.springfox:springfox-swagger2:2.9.2") implementation("io.springfox:springfox-swagger-ui:2.9.2") SwaggerConfig @Configuration @EnableSwagger2 class SwaggerConfig { @Bean fun docket(): Docket { return Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build() } } 위와 같이 설명, U..
데이터 베이스 스키마 설계 Todo //Column data class Todo( var index: Int? = null, // 일정 index var title: String? = null, // 일정 title var description: String? = null, // 일정 설명 var schedule: LocalDateTime? = null, // 일정 시간 var createdAt: LocalDateTime? = null, // 생성 시간 var updatedAt: LocalDateTime? = null, // 업데이트 시간 ) fun Todo.convertTodo(todoDto: TodoDto): Todo { return Todo().apply { this.index = todoDto.i..
TodoApiController 투두 앱의 CRUD 처리를 담당하는 컨트롤러 작성(설계 단계) Reqeust 에는 필요한 Bodyt 설계 -> Valid 작업들어가기 때문에 핸들러도 작성해준다. @RestController @RequestMapping("/api/todo") class TodoApiController { // R @GetMapping(path = [""]) fun read(@RequestParam(required = false) index: Int?) { // 없으면 전체조회, 있으면 단건 조회, required -> 필수값 아닌지 정하기, Optional이므로 Valid할 필요 없다. } // C @PostMapping(path = [""]) fun create(@Valid @Reque..
본 프로젝트는 테스트 주도 개발(Test-driven development, TDD)로 만들어짐 Repository 작성과 함께 테스트도 함께 작성함 실제 데이터베이스는 사용X(JPA), 메모리DB사용 Config AppConfig // 스프링 부트 실행시, 해당 값들을 먼저 참조 -> Config Class @Configuration class AppConfig { /* val database = TodoDataBase()와 같은 형태로 static 걸어서 쓰지만 Spring의 패러다임은 자동으로 주입되게 만드는 것임.*/ @Bean(initMethod = "init") // Bean으로 등록, init지정, 빈이 만들어질때 어떤 메소드 참조할지 정한다 fun todoDataBase(): TodoDat..
Exception Annotation @RestController @RequestMapping("/api/exception") @Validated class ExceptionApiController { // 연습용 Api, 실무는 X @GetMapping("/hello") fun hello(): String { val list = mutableListOf() //val temp = list[0] return "hello" } @GetMapping("") fun get( @NotBlank @Size(min = 2, max = 6) @RequestParam name: String, @Min(10) @RequestParam age: Int ): String { //통과된 경우만 -> print(Validate..
가끔, 이아니라 일하다보면 외국인이랑 일할 경우가 상당히 많다. 나 같은 경우는 한국인 보다 다른 외국인하고 일하는 경우가 더 많다. 그런데 나의 못된 성품의 탓인지 몰라도, 한국보다 후진국인 필리핀, 미얀마 등등의 동남아의 사람에게는 아무리 상사라도 막 질러버리는 습관이있다. 무의식적으로 나보다 아래라고 보는 거같다. 실제로는 나보다 훨씬 대단하고 인정 받고 있는 사람임에도 불구하고.. 이러한 경우 그러한 사람들에게 나의 부정적 이미지를 심어줄 수 있기 때문에 적어도 한국에서 하는 것 or 일본인에게 하는거 절반이라도 공손하게 대하자. 원래 한국과 같은 유교 사상이 없다고 치더라도 내가 막대하고 있는 것은 그 사람들도 본능적으로 알 거라고 생각하기 때문에 .. 결과적으로 그러한 사람들에게 막대해 봤자 ..
인터넷 상에 공개된 글을 쓴다는 것, 이러한 행위 자체가 나에게는 어느정도 의 생각의 정리를 하게 해준다. 언젠가 그러한 글을 본적이 있다. "내가 만약 글쓰기를 하지않았다면 나는 진즉에 미쳐버렸을 것이다." 지금 어느정도 굉장히 공감이 된다. 나이를 먹음에 따라 서로 자신의 생각이 강해지고 타인을 수용하려는 마음이 없어질때 그러함에도 나는 나의 사상, 생각을 밖으로 표현할 필요가 있다. 이러한 출구로써 불특정 다수에게 보여지는 이러한 글을 쓰는 것 자체가 굉장한 만족감을 준다는 것을 새삼스럽게 깨닫게 된다. 따라서 앞으로는 내가 하고 싶은 말, 내 상각을 가감없이 인터넷 상에 표현하려 한다. 누군가는 읽고 누군가는 읽지 않겠지만 이제 그러한 문제는 나에게 큰 의미가 없다. 세상을 향한 출구로써 이러한 ..
일을 하다보면 상대방을 내가 원하는 방향으로 바꾸려고 나의 주장을 너무나도 강하게 말해버릴 떄가 있다. 그것이 설령 상사라고 해도... 아무리 내가 외국에 있다고해도 나의 의견을 주입시키려 하는 것을 경계하자, 개발 경력이 짧은 나로써는 무조건 책임 회피하는 것이 좋다. 책임을 회피해야 살아남는다 특히 일본에선. 중요한 결정은 항상 매니저, 상사에게 허가를 받으면서 움직이도록 하자. 그리고 말할떄 생각좀 하면서 말하자 무조건 지르지말고, 결국 불투명한 점은 질문을 통해 해소하면 되는 부분이기 때문에 너무 스스로 결론을 내지 말도록 하자. 매우 위험한 행동임에 틀림 없다.. 머리가 어지러울땐 일단 모든걸 접고 혼자 생각정리 , 뭘해서라도 머리를 리셋 시키고 처음부터 다시 천천히 시작하는게 좋다.
92년생 나는 한국나이로 30살, 이제 어느정도 어른이 되었다고 부를 수도 있는? 나이가 되었다. 주변에서는 남들보다 조금 더 성공한 친구도 보이고 그렇지 못한 친구도 보이고.. 어느정도 갈리는 시기가 아닌가 싶다. 내가 일본생활을 시작하고 한국에서 친했던 친구들에게 전화를 할 때 마다 놀라는게 있다. 한국에서는 그렇게 친하게 지내고 오랜 시간 지냈던 친구 이지만 나이가 들고 사는 환경이 달라짐에 따라 서로의 마음이 점점 멀어지는 것을 실시간으로 느끼고 있다... 해외 생활을 해서 더욱 그렇게 느끼는 지몰라도 정말 사람의 인간관계에는 유통기한이 있나.. 라는 생각을 하게 되었다. 물론 나이먹고 친구에게 감정적인 교류를 바라는 것은 어른이 되지 못한자의 어리광같이 느껴지기도 하지만 .. 점점 친구라는 존재..
import java.util.Arrays; import java.util.List; import java.util.function.IntPredicate; public class TestClass { private static final List numList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); public static int count(IntPredicate predicate) { int count = 0; for (int num : numList) { if (predicate.test(num)) { count++; } } return count; } public static void main(String[] args) { int evenNumCoun..
문제 프로젝트에 투입되고 나서 GitLab에서 url 에 따라 gitclone을 하려 했지만 github AccessToken 을 잘못 입력하는 바람에 인증에 실패…. 그후 다시 올바른 암호를 입력해보아도.. 이렇게 Authentication failed for … 이라는 오류 메세지가 발생하게 된다. 원인 깃 랩 GitLab 의 아이디와 1회용으로 발급되는 AccessToken의 값을 틀렸기 때문에 인증에 실패 해결 git config --local --unset credential.helper git config --global --unset credential.helper git config --system --unset credential.helper : git credential cache를 c..
문제 프로젝트에 처음 들어와 개발환경 구축을 하던중 에러가 발생하였다. 도커를 빌드하고 서버 및 클라이언트를 실행하려는 순간 아래 그림 과 같은 에러가 발생하였다. 원인 프로젝트에서 사용되던 8080 포트가 이미 사용중 (예전에 깔아둔 오라클 서버가 실행중 이였음.. 이것을 끄고 실행해줘야 8080 포트를 제대로 사용 할 수 있었음 해결 netstat -a -o : 실행중인 포트를 확인 할 수 있음(프로세스 id -> pid 확인) 여기서 taskkill /f /pid 1234 : 1234 프로세스 kill 하기 명령어를 실행해도 액세스가 거부되어 종료 할 수 없다.(관리자 모드면 가능##) 결국 작업관리자를 실행한 뒤 현재 실행되어있는 프로그램 중 pid 가 일치하는 프로그램을 찾아 직접 종료 시키는 ..
Exception Annotation @ControllerAdvice : Global 예외 처리 및 특정 pakage / Controller 예외 처리 @ExceptionHandler : 특정 Controller의 예외 처리 GlobalControllerAdvice //@RestControllerAdvice(basePackageClasses = [ExceptionApiController::class]) -> Target 설정 가능 //@RestControllerAdvice // RestController의 Exception이 이 컨트롤러를 통하게 됨(Global : 괄호X) class GlobalControllerAdvice { // 특정 예외를 잡겠다고 지정 @ExceptionHandler(value ..
비트연산 정수형 변수를 사람이 사용하는 10진법으로 연산하는 대신 2진법인 비트 단위로 연산할 수 있는 기능 실무에서는 비트연산을 계산에는 거의 사용하지 않음 2진법을 이요한 연산 최적화가 필요하다면 컴파일러의 기능을 사용하는 경우가 대부 분 정수형의 값을 비트단위로 나누어 데이터를 좀더 작은 단위로 담아 경제성을 높이기 위한 용도로 사용함 32비트에서 5비트 따로 27비트 따로 다른 값을 넣어 사용하는 등 변수 하나에 여러개의 값을 담아 사용 주로 플래그 값(상태를 0과 1로 담음) 처리 하거나 네트워크 등에서 프로토콜의 데이터량을 줄이기 위해 사용 좌측으로 갈수록 상위 비트 우측으로 갈 수록 하위 비트 이다 최상위는 부호 비트이기때문에 데이터를 담지 않는 것이 좋다 bitwise shift opera..
Validation 필요한 이유 유효성 검증 하는 코드의 길이가 너무 길다. -> annotation 으로 해결 service logic에 대해서 방해가 된다. 흩어져 있는 경우 어디서 검증 되었는지 찾기 힘들다. 검증 로직이 변경되는 경우 테스트 코드 등, 전체 로직이 흔들릴 수 있다. -> 한 곳에 몰아서 검증 가능 JSR-380 BeanValidation build.gradle.kts 세팅 DeleteApiController // https://beanvalidation.org/2.0-jsr380/spec/ // JSR-320 // hibernate Validation // Spring boot Validation @RestController @RequestMapping("/api") @Valida..
생성자 class Person(var name:String, val birth Year:Int) 새로운 인스턴스를 만들기 위해 호출하는 특수한 함수 -> 생성자를 호출하면 클래스의 인스턴스를 만들어 반환 받을 수 있다. 생성자의 역할 인스턴스의 속성을 초기화 인스턴스 생성시 구문을 수행 기본생성자 fun main() { var a = Person("박보영", 1990) var b = Person("김수미", 1997) var c = Person("정장수", 1994) } class Person(var name: String, val birthYear: Int) { init { println("${this.birthYear}년생 ${this.name}님이 생성되었습니다.") } } 보조생성자 여러 값 겹쳐..
코틀린에서 비동기 처리로 여러개의 루틴을 동시에 처리할 수 있는 방법 메인의 동기처리와 별도로 움직이며 개발자가 제어 가능한 루틴 처리 import kotlinx.coroutines.* import 필수 코르틴은 제어범위 및 실행범위를 지정할 수 있다 -> 코루틴의 Scope Global Scope 프로그램 어디서나 제어, 동작이 가능한 기본범위 CoroutineScope 특정한 목적의 Dispatcher를 지정하여 제어 및 동작이 가능한 범위 모든 플랫폼에서 지원되는 것은 아님, 지원되는 플랫폼에 따라서 사용 Dispatchers.Default(기본적인 백그라운드 동작) Dispatchers.IO(I/O에 최적화 된 동작) Dispatchers.Main메인(UI) 스레드에서 동작 Scope에서 제어되도..
nullable 변수에서 null을 처리하는 법 nullable 변수 var sample: String? = null But null상태로 속성이나 함수를 쓰려고 하면 -> null pointer exception 발생 (null 인 객체를 참조하면 발생하는 오류) var sample: String? = null if (sample != null) println(sample.toUpperCase()) 위와 같은 null Check 필요 ?. null safe operator sample?.toUpperCase() 참조연산자를 실행하기 전에 먼저 객체가 null 인지 확인부터 하고 객체가 null이라면 뒤의 구문을 실행하지 않는 연산자 이다. ?: elvis operator sample?:"default"..
일본의 IT프로젝트는 대체적으로 WaterFall이라고 하는 폭포수 개발 방법론을 따른다, 간혹가다가 애자일이라는 방법론도 쓰기는 하지만 주류는 폭포수형 모델이라고 할 수 있다. 이제부터 그 단 계의 설명을 해보려고 한다. 1. 요건정의 : 고객의 Need를 정의하는 단계 기능 요건 : 어떠한 기능을 필요로 하는가? 처리 요건 : 어떠한 처리를 필요로 하는가? 2. 기본설계 : 무엇을 어떻게 할 것인가를 정하는 단계 ( 고객의 관점를 고려한 설계로써 외부 설계라고도 한다.) 요건 설정 : 무엇을 할 것인가? 사양 설정 : 어떻게 할 것인가? 그러므로 기본설계서에는 대개 다음과 같은 내용이 들어가게 된다. 목적 기능요건 성능요건 (효과) 대상업무 대상데이터 기기구성 네트워크구성 기능구성 화면이미지 DB구성..
Guard Statement(Guard문) Early Exit 원하는 조건이 충족되지 않으면 불필요한 코드 실행 X , 일찍 종료해 버린다 Syntax guard condition else { //condition이 false일때 else문이 실행됨 statements } guard optionalBiding else{ statements } 특징 1. else문을 생략 할 수 없다.(코드를 반드시 중지 시켜야 되기 때문에) 2. Guard문 내에서는 코드를 중지 시켜야 된다(가드문을 호출한 Scope을 중지 시켜야된다.) 3. If문과 다르게 조건이 늘어날수록 코드가 조금더 깔끔해진다(중첩X) 4. OptionalBinding과 함께 사용 가능 5. 대부분 Local Scope에서 사용 Global로 ..