사실 이 이야기는 Effective Java 6장 - 불필요한 객체 생성을 피하라 에 나오는 아주 기초적인 이야기 이다. 그러나 습관이 되지 않아 생각없이 개발하다보면 어느새 이 규칙을 어겨서 어김없이 리팩토링 대상이 되곤 하는데다가, 막상 개발하면서 쓰려다 보면 사용 방법이 잘 생각나지 않아 메모할 겸 짧은 글을 작성 해본다. (요즘 좀 정신이 나가 있어서 공부는 꾸준히 하기는 한다만, 공부하는 양은 좀 줄었고, 진도는 좀처럼 나가지가 않는다. 에라이)
@DisplayName("Utils 테스트") classUtilsTest{ @Test @DisplayName("숫자 외의 문자가 있을 경우 false를 return 해야 한다") voidshould_return_false_when_has_other_characters(){ String numbersWithCharacter = "1a2s3d4f5g6"; boolean expected = false;
boolean result = Utils.hasOnlyNumbers(numbersWithCharacter);
assertEquals(expected, result); } @Test @DisplayName("숫자외의 문자가 없을 경우 true를 return 해야 한다") voidshould_return_true_when_has_only_numbers(){ String numbersWithCharacter = "123456789"; boolean expected = true;
boolean result = Utils.hasOnlyNumbers(numbersWithCharacter);
assertEquals(expected, result); } }
오케이, 원하는 바를 손쉽게 얻었다. 그러나 지금 얻은 결과는 성능상 좋지 못하다. 사실 일반적인 상황에서 String의 matches 메소드를 사용하는게 엄청나게 성능에 문제를 주는 경우는 별로 없으나, 습관이 중요한데다가, 실제로 이런 코드들이 쌓여 문제를 발생하는 경우도 있으니 좋은 습관을 들이는 게 좋다. 이펙티브 자바는 String.matches를 사용하는 것보다 더 고급지고어렵고 성능이 좋은 방법을 알고 있다.
Pattern 클래스를 사용해 보자
바로 Pattern클래스를 사용해 같은 일을 더 성능 좋게 사용할 수 있다. 사실 위 예제의 코드는 메소드가 실행 될때마다 내부적으로 Pattern 인스턴스를 만들고 사용 후 버리는 작업을 수행하게 되는데, 이 Pattern을 final static 객체로 미리 선언해두고 사용하게 되면 메소드가 호출될 때마다 새로 생성하고 버리는 작업이 없어지게 된다. 아래 코드를 보자
Spring boot 에서는 application.yml (또는 application.properties) 파일의 내용을 빈의 변수에 바인딩하도록 도와주는 어노테이션이 있다. @Value("${property.value}") 뭐 이런식으로 사용하는데 변수가 늘어남에 따라 어노테이션이 많아져서 가독성을 해치는 경우가 있고, 일일히 지정해주기가 귀찮을 경우 쓸 수 있는 방법인 @ConfigurationProperties 어노테이션에 대해서 간단히 적어 보려 한다.
사용방법
@ConfigurationProperties 는 클래스에 선언하는 어노테이션이다. 간단히 아래 예시와 같이 사용한다.
값들을 사용하고자 하는 클래스에 @ConfigurationProperties 어노테이션을 추가한다. 여기서 prefix도 설정할 수 있다. (user.conf는 예시를 위해 작성해 놓은 것이고, prefix는 다른 값으로도 사용할 수 있다.) 주의할 점은 @Value 어노테이션을 활용해 값을 바인딩 하는것과 다르게, 반드시 setter 메소드를 필요로 한다. @ConfigurationProperties는 setter 메소드를 사용해 설정값을 바인딩 하기 때문이다. 여기서는 클래스에 @Setter 롬복 어노테이션을 사용해 한번에 정의했다.
나는 java 개발을 할 때 IntelliJ를 사용한다. 지금 다니고 있는 회사에 입사하기 전까지는 eclipse 만 사용해봤었고, IntelliJ는 사실 존재 자체도 모르고 있었다. 그러나 지금은 intelliJ 없이는 java개발을 할 수 없는 몸이 되어버렷!! 다.. IntelliJ는 여러 편의 기능을 번들로 제공하고 있는데 그 중 하나가 지금 이야기 하고자 하는 http client 툴이다.
사실 IntelliJ의 Http 툴의 사용방법을 설명한 글을 이전에 블로그에 한번 작성한 적이 있었으나 안타깝게도 블로그와 함께 날려먹었고, 이 툴에 관해 잘 설명해 놓은 글은 굳이 내가 정리하지 않더라도 많이 있다. 그럼에도 불구하고 또 이 툴에 대해서 정리하는 이유는 내가 잘 보려고
회사에서 개발 일을 하면서 많은 지식을 익히고 이 지식들로 코딩을 하지만, 돌아서고 나면 잊어버린다. 물론 코드에 작업 내용이 남아있어 다시 열어본다면 이해하고 동일한 코드를 만들 수 있지만, 사실 이 코드의 소유는 내가 아니라 회사다. 퇴사를 한다면?? 내가 동일한 코드를 만들 수 있을까? 그래서 내 것으로 만들기 위해 하나씩 정리 하려고 한다.
.http 소개
이 툴의 명칭은 HTTP Client 쯤 되는것 같다. (HTTP client in IntelliJ IDEA code editor) 안타깝게도 ultimate 딱지가 붙어 있는걸 봐서는 intelliJ 커뮤니티 에디션에서는 사용하지 못하는 듯 하다. 레퍼런스 페이지는 #여기
간단히 말해 http 호출을 해볼 수 있는 툴이다.
.http 를 쓰는 이유
익히지 않고 직관적으로 쓰기에는 물론 postman이 더 낫다. swagger도 많이 쓴다. 설치하기 귀찮으면 curl을 사용하기도 한다. 내가 .http 를 쓰는 가장 큰 이유는
Git을 통한 형상 관리
Git으로 팀원과 쉽게 공유가 가능
테스트 툴이므로 초록 막대를 보며 마음의 안정을 얻을 수 있다. (또는 빨간 막대를 볼수도..)
뭐 이 외에도 쓰다보면 여러 장점들을 느낄 수 있겠지만, 일단 이 세가지만으로도 충분히 좋다.
기본 사용법
intelliJ의 프로젝트 explorer에서 적당한 곳에 마우스 우클릭 > NEW > HTTP Request
적당한 파일명을 입력 후 엔터를 치면 .http 로 끝나는 파일이 생성 되고 에디터로 그 파일을 연다.
이 때 주의할 점 파일명을 status로는 하지 말자. 왠지 모르겠지만, status.http 파일에서는 http 테스트가 활성화가 되지 않는다.
이제부터 테스트를 만들면 된다. 아직 우리는 사용법을 잘 모르므로 Examples를 눌러보자. 그럼 친절하게 아래와 같은 내용의 파일이 열린다.
이 예제에서는 development, production 환경을 사용할 수 있고, 그 내부에 정의 돼있는 host, id-value 와 같은 값들을 미리 정의 해놨다고 이해하면 된다. 테스트 할때 위 예제에서 봤듯이 http://{{host}}/index.html 와 같은 형식으로 사용할 수 있다. 물론 이 값들은 url 뿐만 아니라 헤더나 request body 영역에서도 치환해서 사용할 수 있다.
username과 password는 비어두었는데, 개인정보 등 공유되어서는 안될 민감한 정보들을 별도로 정의하기 위해서 비워두었다. rest-client.private.env.json (또는 http-client.private.env.json) 라는 파일 명으로 별도로 정의하여 사용할 수 있는데, 이는 형상관리에서 기본으로 제외되도록 설정돼있다고 한다.
이렇게 환경변수를 설정하는 방법은 rest-client.env.json 파일을 통해 미리 정의하는 방법 말고 또 한가지가 존재한다. 바로 http 호출 후 response handler를 정의해서 변수로 설정하는 방법이다. 아래 예제를 살펴보자. (참고로 response handler는 javascript 문법을 사용한다. 또한 자동완성까지 지원한다. ㄴㅇㄱ)
1 2 3 4 5 6 7 8 9
POST http://localhost/oauth/token Content-Type: application/x-www-form-urlencoded
POST로 http://localhost/oauth/token를 호출하고 받는 response에서 response.body 의 access_token 값을 받아 client.global.set()이라는 함수로 변수 설정이 가능한데, 이 스크립트의 경우 “access_token”이라는 변수에 response.body 객체의 access_token 값을 할당 했다. (response.body 가 json형태일 경우다)
response 객체는 body 말고도 다른 속성들도 제공 해준다. 에디터에서 response.을 찍어서 우리의 친절한 intelliJ 자동완성의 도움을 받아 살펴보자.
body 외에 contentType, headers, status 값들을 제공한다.
이를 잘 활용하면 ouath 토큰을 발급받아서 환경변수에 넣는 스크립트를 만들고, 그 이후에 실행하는 스크립트에서 발급받은 토큰을 포함하여 request 테스트를 하는 등의 케이스에서 활용할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
### Get Token POST http://localhost/oauth/token Content-Type: application/x-www-form-urlencoded