ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 패스트캠퍼스 챌린지 3일차
    JAVA/Spring 2021. 11. 3. 19:48

    1. Null Safety

    Null Safety는 Null 연관성을 높이는 법이다.

    • 아래와 같은 코드를 만들지 않는 방법
    • 혹은 아래와 같은 널 체크를 하지 않아서 발생하는 NPE(Null Pointer Exception)을 방지하는 방법
    • 완벽한 방법은 아니지만 IDE에서 경고를 표시함으로써 1차적인 문제를 방지하고, 정확한 에러 위치를 확인할 수 있도록 도움
    public void method(String request) {
    	if(request == null) return;
        
    	// normal process
    	System.out.println(request.toUpperCase());
    }

    @NonNull Annotation

    • 해당 값이나 함수 등이 Null이 아님을 나타내는 어노테이션
    • org.springframework.lang.NonNull 사용
    • 메서드 파라미터에 붙이는 경우 : null이라는 데이터가 들어오는 것을 사전에 방지함
     public void method(@NonNull String request) {
        // 이 부분에 Condition "request == null" is always "false" 라는 경고가 뜬다.
        if(request == null) return;
        
        // normal process
        System.out.println(request.toUpperCase());
     }
    • 프로퍼티에 붙이는 경우 : null을 저장하는 경우 경고
     @NonNull
     public String request = "REQUEST";
     
     public void method() {
        // normal process
        System.out.println(request.toUpperCase());
        
        // "null" is assigned to a variable that is annotated with @NotNull 이라는 경고 메시지 뜸
        request = null;
     }
    • 메서드에 붙이는 경우 : null을 리턴하는 경우 경고, 응답값을 저장하거나 활용하는 쪽도 NonNull이라고 신뢰하고 사용한다.
    @NonNull
    public void method() {
        // normal process
        System.out.println(request.toUpperCase());
        
        // 'null' is returnd by the method declared as @NonNull 이라는 경고가 뜸
        return null;
    }

    @Nullable Annotation

    • @NonNull과 반대로 해당 데이터가 null일 수 있음을 명시함
    • 해당 어노테이션이 붙은 값을 사용하는 경우 null check를 항상 수행하도록 경고
    @Nullable
    public String request = "REQUEST";
    
    public void method() {
        // normal process
        // Method invocation 'toUppserCase' may produce 'NullPointerException' 이라는 경고가 뜸
        System.out.println(request.toUpperCase());
    }

    2. 롬복 (lombok)

    롬복은 보일러 플레이트 코드들(프로젝트 생성 시 반복적으로 작성해야 하는 코드들)을 간편하게 자동으로 생성해주는 라이브러리이다.

     

    @Getter, @Setter

    아래 코드를 보면 클래스에 정의된 프로퍼티들에 대해 getter와 setter가 정의되어 있다.

    public class DevDto {
        String name;
        Integer age;
        LocalDateTime startAt;
    
        public String getName() {
            return this.name;
        }
    
        public Integer getAge() {
            return this.age;
        }
    
        public LocalDateTime getStartAt() {
            return this.startAt;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        public void setStartAt(LocalDateTime startAt) {
            this.startAt = startAt;
        }
    }

    그러나 롬복을 이용하면 아래와 같이 반복적으로 getter와 setter를 정의하는 수고를 들이지 않아도 된다.

    @Setter
    @Getter
    public class DevDto {
        String name;
        Integer age;
        LocalDateTime startAt;
    }

     

    @ToString

    setter와 getter 외에도 toString 어노테이션을 붙여서 해당 클래스의 프로퍼티 값들을 String화할 수 있다.

    @ToString
    public class DevDto {
        String firstName;
        Integer age;
        LocalDateTime startAt;
    }
    
    // JUnit을 통한 Test
    class DevDtoTest {
        @Test
        void test() {
            DevDto devDto = new DevDto();
    
            devDto.setFirstName("Harry");
            System.out.println(devDto.getFirstName());
            devDto.setAge(21);
            devDto.setStartAt(LocalDateTime.now());
    		
            // 통상적으로 devDto에 toString()을 붙여줘야함 
            // 하지만 ToString 어노테이션을 붙이면서 생략 가능
            System.out.println(devDto); // DevDto(firstName=Harry, age=21, startAt=2021-11-03T17:36:57.201)
        }
    }

     

    @NoArgsConstructor, @AllArgsConstructor, @RequiredArgsConstructor

    생성자의 arguments를 제어하는 어노테이션도 존재한다.

    // arguments가 없는 생성자를 만든다.
    @NoArgsConstructor
    
    // 모든 arguments를 포함하는 생성자를 만든다.
    @AllArgsConstructor
    
    // 요구되는 arguments(final 혹은 @NonNull이 붙은 프로퍼티)를 포함하는 생성자를 만든다.
    @RequiredArgsConstructor
    public class DevDto {
        String firstName;
        Integer age;
        LocalDateTime startAt;
    }

     

    @Data

    위에서 언급한 어노테이션들 대부분을 포함하는 어노테이션인 @Data도 존재한다.

    // @Getter @Setter @RequiredArgsConstructor @ToString @EqualsAndHashCode를 붙인 것과 동일.
    @Data
    public class DevDto {
        String firstName;
        Integer age;
        LocalDateTime startAt;
    }

    그러나 @Dadta 어노테이션의 사용은 왠만해서는 피하는 것이 좋다. @ToString 어노테이션을 포함하고 있기에 원치 않는 경우에도 class가 String화되는 경우가 발생하기 때문이다.

     

    @Builder

    @Setter와 @Getter 어노테이션 대신 @Builder 어노테이션을 사용하는 방법도 있다. @Builder를 사용할 경우 코드의 응집력을 높여주고 변동성을 줄여주기 때문에 @Builder 사용을 권장한다고 한다.

    // Lombok 덕분에 Builder를 손쉽게 사용할 수 있게 되었다.
    @Builder
    public class DevDto {
        String firstName;
        Integer age;
        LocalDateTime startAt;
    }
    
    ========================================
    
    // JUnit 테스트 코드
    class DevDtoTest {
        @Test
        void test() {
        	// setFirstName, setAge 등으로 정의할 필요 없이 선언 시 정의가 가능
            final DevDto devDto = DevDto.builder()
                    .firstName("Harry")
                    .age(31)
                    .startAt(LocalDateTime.now())
                    .build();
    
            System.out.println(devDto);
        }
    }

     

    @Slf4j

    @Slf4j 어노테이션을 이용하여 쉽게 로그를 출력하는 것도 가능하다.

    @Slf4j
    public class DevDto {
        String firstName;
        Integer age;
        LocalDateTime startAt;
    
        public void printLog() {
            log.debug(getFirstName());
        }
    }
    
    ==================================
    // JUnit 테스트 코드
    
    
    class DevDtoTest {
        @Test
        void test() {
            final DevDto devDto = DevDto.builder()
                    .firstName("Harry")
                    .age(31)
                    .startAt(LocalDateTime.now())
                    .build();
    
            devDto.printLog(); // [Test worker] DEBUG com.example.devmaker.devmaker.dto.DevDto - Harry
        }
    }

     

    @UtilityClass

    개발에 쓰이는 여러 Utility적인 성격을 가지는 (포맷 변환, 계산 등) 메소드들을 모아둔 클래스를 정적으로 만들어주는 어노테이션

    -> 상속을 못 받게 하고 private으로 쓰이게끔

    @UtilityClass
    public class DevUtil {
        public static void printLog() {
            System.out.println(LocalDateTime.of(2021, 11, 3, 3, 15));
        }
    
        public static void printNow() {
            System.out.println(LocalDateTime.now());
        }
    }

    3. HTTP 스펙

    • 그냥 문자가 아닌 HyperText를 전송하는 데에 활용하는 프로토콜

    HTTP Request 메시지 스펙

    • 첫째 줄 : 요청라인 (HTTP 메서드 : GET, PUT, POST, DELETE 등)
    • 두번째 줄부터 줄바꿈이 나오기 전까지 : Header (User-Agent, Accept 등)
    • Header에서 줄바꿈 이후 : Request Body
    POST / create-developer HTTP/1.1
    Content-Type: application/json
    Accept: application/json
    
    {
        "developerLevel": "JUNIOR",
        "developerSkillType": "FULL_STACK",
        "experienceYears": 2,
        "memberId": "sunny.flower",
        "name": "sun",
        "age": 36
    }
    
    // GET 요청일 때는 Request Body를 넣지 않고 POST 요청일 때는 QueryString을 통해 값들을 전달하기로 약속됨
    // (넣어도 상관은 없음)

    HTTP Response 메시지 스펙

    • 첫째줄 : 상태라인 (200, 500 등)
    • 두번째 줄부터 줄바꿈 나오기 전까지 : Header
    • 헤더에서 줄바꿈 이후 : Response Body
    HTTP/1.1 200 OK
    Content-Type: application/json
    Transfer-Encoding: chunked
    Date: Sat, 17 Jul 2021 15:33:34 GMT
    Keep-Alive: timeout=60
    Connection: keep-alive
    
    {
        "developerLevel": "JUNIOR",
        "developerSkillType": "FULL_STACK",
        "experienceYears": 2,
        "memberId": "sunny.flower",
        "name": "sun",
        "age": 36
    }

    4. 1 Layer 구조의 어플리케이션

    오직 Controller만을 생성해 동작하는 Application 예시이다.

     

    com.fastcampus.programming.dmaker.controller.DMakerController

    // 해당 class를 RestController라는 Bean으로 등록!
    // 가장 기본이 되는 Controller는 그냥 @Controller이지만 REST타입의 요청을 받을 수 있도록 @RestController를 준다.
    // (DmakerApplication이라는 레고 판에 Bean들을 하나씩 조립시키는 것인데 RestController 타입의 Bean을 조립시키는 것)
    @Slf4j
    @RestController
    public class DMakerController {
    
        @GetMapping("/developers")
        public List<String> getAllDeveleopers() {
            // GET /developers HTTP/1.1
    
          log.info("GET /developers HTTP/1.1");
    
          return Arrays.asList("Harry", "Paul", "Ashe");
        }
    }

    해당 Controller를 생성 후 Application을 실행시킨 다음 localhost:8080/developers로 접속하면

    아래와 같은 화면을 볼 수 있다.

    localhost:8080/developers


     

    본 포스팅은 패스트 캠퍼스 환급 챌린지 참여를 위해 작성되었습니다.
    https://bit.ly/3FVdhDa

     

    수강료 100% 환급 챌린지 | 패스트캠퍼스

    딱 5일간 진행되는 환급챌린지로 수강료 100% 환급받으세요! 더 늦기전에 자기계발 막차 탑승!

    fastcampus.co.kr

     

    'JAVA > Spring' 카테고리의 다른 글

    패스트캠퍼스 챌린지 8일차  (0) 2021.11.08
    패스트캠퍼스 챌린지 7일차  (0) 2021.11.07
    패스트캠퍼스 챌린지 6일차  (0) 2021.11.06
    패스트캠퍼스 챌린지 5일차  (0) 2021.11.05
    패스트캠퍼스 챌린지 4일차  (0) 2021.11.04

    댓글

Designed by Tistory.