블로그
전체 4#카테고리
- 백엔드
#태그
- 과제
- 어노테이션

2024. 02. 23.
좋아요수0
5일차 미션(클린코드)
public class Main { private static final int MAX_NUMBER = 6; public static void main(String[] args) { System.out.print("숫자를 입력하세요: "); Scanner scanner = new Scanner(System.in); int totalRolls = scanner.nextInt(); int[] counts = new int[MAX_NUMBER]; for (int i = 0; i 변수명 개선, if문 대신 배열을 사용하여 반복을 줄임, 함수를 추출해서 가독성을 향상시킴, 상수를 사용함
과제

2024. 02. 21.
좋아요수0
질문
DTO에 어떤 생성자를 추가해야되는지 궁금합니다. 1번RequestDTO에 기본 생성자가 없을 때(매개변수가 있는 생성자만 있었을 때) 오류 안남 3번RequestDTO에 기본 생성자가 없을 때(매개변수가 있는 생성자만 있었을 때) 오류남기본생성자를 추가하니까 API가 잘 작동함 1번은 GET이고 3번은 POST라서 이런 차이가 있는건가 싶은 생각이드는데정확한 이유를 모르겠습니다.원인이 무엇이고 생성자에 어떤식으로 맵핑?이 되는건가요? 1번 코드 @GetMapping("/api/v1/calc") public CalcResponse calc(CalcRequest request){ // @RequestParam // return new CalcResponse(request.getNum1() + request.getNum2(), // request.getNum1() - request.getNum2(), // request.getNum1() * request.getNum2()); return new CalcResponse(request.getNum1(), request.getNum2()); } package com.group.libraryapp.assignment.dto.request; public class CalcRequest { private int num1; private int num2; public CalcRequest(int num1, int num2) { this.num1 = num1; this.num2 = num2; } public int getNum1() { return num1; } public int getNum2() { return num2; } } package com.group.libraryapp.assignment.dto.response; public class CalcResponse { private int add; private int minus; private int multiply; // public CalcResponse(int add, int minus, int multiply) { // this.add = add; // this.minus = minus; // this.multiply = multiply; // } public CalcResponse(int num1, int num2){ this.add = num1 + num2; this.minus = num1 - num2; this.multiply = num1 * num2; } public int getAdd() { return add; } public int getMinus() { return minus; } public int getMultiply() { return multiply; } } ======================3번 @PostMapping("/api/v1/nums-sum") public Integer sum(@RequestBody SumRequest nums){ Integer result = 0; for(Integer num : nums.getNums()){ result += num; } return result; }package com.group.libraryapp.assignment.dto.request; import java.util.List; public class SumRequest { private List nums; public SumRequest(List nums) { this.nums = nums; } public List getNums() { return nums; } } 위의 코드는 기본생성자가 없어서 500에러 뜸 아래 코드와 같이 기본 생성자 추가하니까 성공package com.group.libraryapp.assignment.dto.request; import java.util.List; public class SumRequest { private List nums; // *********** 추가 ***************** public SumRequest() { } public SumRequest(List nums) { this.nums = nums; } public List getNums() { return nums; } }

2024. 02. 20.
좋아요수0
2일차 미션(API 만들기)
과제문제1 : 생성자 없어서 틀렸었음 AssignmentApplication.java@RestController public class AssignmentApplication { @GetMapping("/api/v1/calc") public CalcResponse calc(CalcRequest request){ // @RequestParam System.out.println(request.getNum1() + " // " + request.getNum2()); // return new CalcResponse(request.getNum1() + request.getNum2(), // request.getNum1() - request.getNum2(), // request.getNum1() * request.getNum2()); return new CalcResponse(request.getNum1(), request.getNum2()); } } CalcRequest.javapackage com.group.libraryapp.assignment.dto.request; public class CalcRequest { private int num1; private int num2; // 생성자가 없으면 객체를 생성할때 값을 주입하지 못한다. public CalcRequest(int num1, int num2) { this.num1 = num1; this.num2 = num2; } public int getNum1() { return num1; } public int getNum2() { return num2; } } CalcResponse.javapackage com.group.libraryapp.assignment.dto.response; public class CalcResponse { private int add; private int minus; private int multiply; // public CalcResponse(int add, int minus, int multiply) { // this.add = add; // this.minus = minus; // this.multiply = multiply; // } public CalcResponse(int num1, int num2){ this.add = num1 + num2; this.minus = num1 - num2; this.multiply = num1 * num2; } public int getAdd() { return add; } public int getMinus() { return minus; } public int getMultiply() { return multiply; } } 쿼리에 2023-01-01 String으로 입력받음 → DayResponse 응답 객체를 생성해서 return함객체를 생성하고 초기화 할 때 입력받은 날짜를 요일로 변경해야함 입력받은 String을 LocalDateTime 으로 변경함. 이 때 변경은 String을 잘라서 년,월,일,시간,분으로 나눔(0시 0분으로 임의설정) 변경된 LocalDateTime에서 getDayOfWeek함수로 요일을 얻고 String으로 변경해서 반환 @GetMapping("/api/v1/day-of-the-week") public DayResponse day(String date){ return new DayResponse(date); } package com.group.libraryapp.assignment.dto.response; import java.time.LocalDateTime; public class DayResponse { String dayOfTheWeek; public DayResponse(String dayOfTheWeek) { LocalDateTime localDateTime = LocalDateTime.of(Integer.parseInt(dayOfTheWeek.substring(0,4)), Integer.parseInt(dayOfTheWeek.substring(5,7)), Integer.parseInt(dayOfTheWeek.substring(8)),0,0); this.dayOfTheWeek = localDateTime.getDayOfWeek().toString(); } public String getDayOfTheWeek() { return dayOfTheWeek; } } API에서 받는 Body라고 해서 POST 설정함, 처음에 @ReqeustBody를 안해서 입력받은 배열이 null로 떴었음. RequestDto에 모든 인자가 있는 생성자 한개만 있는 상태에서는 결과가 안나왔음. 기본 생성자를 만들어주니까 답이 바르게 나옴 언제 기본생성자를 써주고 언제 매개변수가 있는 생성자를 써줘야할까? @PostMapping("/api/v1/nums-sum") public Integer sum(@RequestBody SumRequest nums){ Integer result = 0; for(Integer num : nums.getNums()){ result += num; } return result; } package com.group.libraryapp.assignment.dto.request; import java.util.List; public class SumRequest { private List nums; public SumRequest() { } public SumRequest(List nums) { this.nums = nums; } public List getNums() { return nums; } }
백엔드
・
과제

2024. 02. 19.
좋아요수0
1일차 미션(어노테이션)
맨 아래에 미션 내용이 있습니다.(미션을 하면서 학습한 내용을 함께 작성하였습니다.) Annotations어노테이션은 메타데이터의 형태로 프로그램에 대한 데이터를 제공한다. 어노테이션은 코드의 작동에 직접적인 영향을 미치지 않는다.어노테이션은 다음과 같은 사용을 한다.컴파일러에게 정보 제공 - 어노테이션은 컴파일러가 에러나 경고를 막기위해 사용된다.컴파일 시 및 배포 시 처리 - 소프트웨어 도구는 어노테이션 정보를 가지고 코드, XML 파일 등을 생성할 수 있다.런타임 처리 - 일부 어노테이션은 런타임 시(실행 시) 확인될 수 있고, 이를 기반으로 추가적인 동작이나 처리를 수행할 수 있다.Annotation 기본사항@Annotation 형태@는 뒤에 오는 내용이 어노테이션임을 컴파일러에게 나타낸다.element가 한개인 경우 name을 생략할 수 있다. element가 없는 경우 @Override처럼 괄호를 생략할 수 있다.@Author( name = "Benjamin Franklin", date = "3/27/2003" ) class MyClass { ... } or @SuppressWarnings(value = "unchecked") void myMethod() { ... } @SuppressWarnings("unchecked") void myMethod() { ... } 여러개의 어노테이션을 사용할 수 있다.@Author(name = "Jane Doe") @EBook class MyClass { ... } 같은 타입을 가지는 어노테이션들을 repeating 어노테이션이라 한다. 자바 8버전부터 지원@Author(name = "Jane Doe") @Author(name = "John Smith") class MyClass { ... } 어디서 어노테이션이 사용되는가?어노테이션은 클래스, 필드, 메소드, 다른 프로그램의 요소 선언에 적용될 수 있다.클래스 객체 생성 표현식 (new @Interned MyObject(); ) , 형변환, implements 절, 발생한 예외 선언 절에서도 사용된다. 이러한 형태의 어노테이션은 “타입 어노테이션”이라 한다. 자바 8에서 생겨남어노테이션 타입 선언어노테이션으로 코드 내의 주석들을 대체할 수 있다.예를들어서 ‘모든 클래스 시작에 아래와 같이 중요한 주석들을 단다’ 라는 규칙이 있다고 생각해보자.public class Generation3List extends Generation2List { // Author: John Doe // Date: 3/17/2002 // Current revision: 6 // Last modified: 4/12/2004 // By: Jane Doe // Reviewers: Alice, Bill, Cindy // class code goes here } To add t 어노테이션으로 동일한 내용의 메타데이터를 추가하기 위해서는, 사전에 아래와 같은 문법을 사용해서 어노테이션 타입을 정의해야한다.@interface ClassPreamble { String author(); String date(); int currentRevision() default 1; String lastModified() default "N/A"; String lastModifiedBy() default "N/A"; // Note use of array String[] reviewers(); } 어노테이션 선언 시 interface 키워드 앞에 @를 붙여야한다.어노테이션 타입은 인터페이스 형태이다.메소드와 비슷하게 어노테이션 타입 요소 선언이 포함되어있다. 이 때 기본값을 정의할 수 있다.어노테이션을 정의하면 아래와 같이 사용가능하다.@Documented : // 만약에 javadoc에 포함시키고싶으면 해당 어노테이션 추가 @ClassPreamble ( author = "John Doe", date = "3/17/2002", currentRevision = 6, lastModified = "4/12/2004", lastModifiedBy = "Jane Doe", // Note array notation reviewers = {"Alice", "Bob", "Cindy"} ) public class Generation3List extends Generation2List { // class code goes here } 미리 선언된 어노테이션 타입들자바 언어에서 사용되는 어노테이션@Deprecated@Override@SuppressWarnings (컴파일러가 생성할 특정 경고 억제)@SafeVarargs@FunctionalInterface다른 어노테이션에 적용되는 어노테이션 : 메타 어노테이션@Retention@Documented@Target@Inherited@RepeatableType Annotations and Pluggable Type Systems자바 8 이전에는 어노테이션을 선언에만 적용 가능이후에는 어떤 타입 사용에도 적용 가능반복 어노테이션동일한 어노테이션을 한 선언 또는 타입에서 여러번 사용ex) 타이머 서비스를 사용하는 코드에서 특정 메소드를 매월 마지막 날, 매주 금요일 오후 11시에 실행하도록 타이머를 설정하기 위해 @Schedule 어노테이션 두번 사용@Schedule(dayOfMonth="last") @Schedule(dayOfWeek="Fri", hour="23") public void doPeriodicCleanup() { ... } 사용법반복 가능한 어노테이션 타입 선언import java.lang.annotation.Repeatable; @Repeatable(Schedules.class) public @interface Schedule { String dayOfMonth() default "first"; String dayOfWeek() default "Mon"; int hour() default 12; } 컨테이닝 어노테이션 타입 선언 : @Schedules어노테이션은 Schedule 어노테이션을 array로 저장할 수 있는 value 요소를 가져야함public @interface Schedules { Schedule[] value(); } Lesson: Annotations (The Java™ Tutorials > Learning the Java Language)어노테이션을 직접 만들어 쓸 수 있다.@interface 어노테이션이름{ 타입 요소이름(); // 어노테이션의 요소를 선언한다. ... } @interface DateTime{ String yymmdd(); String hhmmss(); } 어노테이션의 메서드는 추상 메서드이며, 어노테이션을 적용할 때 지정(순서 X) 추상 메서드는 구현할 필요가 없음@interface TestInfo{ int count(); String testedBy(); String[] testTools(); TestType testType(); // enum TestType { FIRST, FINAL } DateTime testDate(); //자신이 아닌 다른 어노테이션 포함 가능 적용시 값을 지정하지 않으면, 사용될 수 있는 기본값 지정 가능(null제외)@interface TestInfo{ int count() default 1; } @TestInfo public class newClass{ ... } 요소가 하나이고 이름이 value일 때는 요소의 이름 생략가능@interface TestInfo{ String value(); } @TestInfo("passed") // @TestInfo(value="passed")와 동일 class newClass{ ... } 요소의 타입이 배열인 경우, 괄호{}를 사용해야 한다@interface TestInfo{ String[] testTools(); } @Test(testTools={"JUnit", "AutoTester"}) @Test(testTools="JUnit") @Test(testTools={}) // 값이 없을 때는 괄호{}가 반드시 필요 모든 어노테이션의 조상Annotation은 모든 어노테이션의 조상이지만 상속은 불가사실 Annotation은 인터페이스다.마커 어노테이션요소가 하나도 정의되지 않은 어노테이션@Test, @Deprecated어노테이션 요소의 규칙요소의 타입은 기본형, String, enum, 어노테이션, Class만 허용추상메서드의 괄호 ()안에 매개변수를 선언할 수 없다예외를 선언할 수 없다요소를 타입 매개변수로 정의할 수 없다. [자바의 정석 - 기초편] ch12-23,24 애너테이션실제로 직접 만들어서 사용할만한 어노테이션에는 뭐가 있을까?프로젝트를 하지 않아서 실제로 어떨 때 필요할 지 와닿지 않음지피티에게 물어본 결과@JsonField:해당 필드가 JSON 직렬화/역직렬화 대상임을 나타내는 어노테이션.javaCopy code public class MyObject { @JsonField private String name; @JsonField private int age; // ... } @NotNull:매개변수나 필드가 null이 아니어야 함을 나타내는 어노테이션.javaCopy code public void someMethod(@NotNull String parameter) { // 메서드 로직 } @RetryOnFailure:메서드나 함수가 실패할 경우 지정된 횟수만큼 자동으로 재시도하도록 하는 어노테이션.javaCopy code @RetryOnFailure(maxAttempts = 3) public void someOperation() { // 작업 로직 } @LogPerformance:메서드의 실행 시간을 로그에 기록하는 어노테이션.javaCopy code @LogPerformance public void performanceCriticalMethod() { // 성능 중요한 작업 로직 } @SecureAccess(role = "ADMIN"):특정 역할이나 권한을 요구하는 보안 접근을 나타내는 어노테이션.javaCopy code @SecureAccess(role = "ADMIN") public void adminOnlyOperation() { // 관리자 권한이 필요한 작업 로직 } 이러한 예시처럼 프로젝트의 특정 요구사항에 맞게 어노테이션을 설계하고 사용할 수 있습니다. 직접 만든 어노테이션을 사용하면 코드의 가독성을 높이고 개발자들 간의 일관성을 유지할 수 있습니다.어노테이션을 사용하는 이유 (효과) 는 무엇일까?개발자 관점에서 @Override와 같은 어노테이션을 사용하면 해당 메서드가 상위 클래스에서 오버라이드 된 것임을 확실하게 알 수 있다. 즉 코드를 읽을때 유용하고 의도를 명확하게 전달할 수 있다.컴파일러 관점에서 컴파일러가 @Override어노테이션 정보를 통해 상위 클래스에 해당 메서드가 존재하는지 확인하고, 아니면 오류를 발생시킬 수 있다. 즉즉 어노테이션은 개발자에게 코드 작성 시 명확한 정보를 제공하고, 컴파일러에게는 코드의 일관성과 정확성을 검증할 수 있는 수단으로 활용된다. 자바에서 어노테이션(Annotation)은 코드에 메타데이터를 추가하는 방법으로 사용됩니다. 어노테이션은 주석과는 다르게 컴파일러나 런타임 시에 코드에 대한 정보를 제공하며, 다양한 목적으로 활용됩니다. 몇 가지 주된 이유는 다음과 같습니다:코드 문서화 및 가독성 향상: 어노테이션을 사용하면 코드에 추가적인 정보를 주석으로 달지 않고도 문서화할 수 있습니다. 예를 들어, @Deprecated 어노테이션은 해당 메서드나 클래스가 더 이상 권장되지 않음을 나타냅니다.컴파일 타임 체크: 일부 어노테이션은 컴파일러에게 특정 경고나 오류를 생성하도록 알려줄 수 있습니다. 예를 들어, 널 포인터 예외를 방지하기 위해 사용되는 @NonNull 어노테이션 등이 있습니다.런타임 처리와 리플렉션: 몇몇 어노테이션은 런타임에 정보를 검색하거나 특정 동작을 수행할 수 있도록 해줍니다. 예를 들어, 스프링 프레임워크에서는 @Autowired 어노테이션을 사용하여 의존성 주입을 수행합니다.프레임워크와 라이브러리 통합: 어노테이션은 프레임워크나 라이브러리에서 특정 기능을 활성화하기 위한 힌트로 사용됩니다. 예를 들어, JUnit에서는 @Test 어노테이션을 사용하여 테스트 메서드를 식별하고 실행합니다.커스텀 마커 어노테이션: 프로그래머가 자신만의 어노테이션을 정의하여 특정 상황에 대한 힌트를 추가하거나, 프레임워크에서 사용할 수 있는 커스텀 마커로 활용할 수 있습니다.이러한 이유로 어노테이션은 자바의 다양한 분야에서 사용되며, 코드의 가독성과 유지보수성을 향상시키고 추가적인 기능을 제공합니다. 나만의 어노테이션은 어떻게 만들 수 있을까?@interface키워드를 사용하여 어노테이션을 정의한다요소를 정의한다 : 필요한 속성이나 요소 정의하고 기본값 설정적용한 어노테이션을 다른 코드에서 적용하여 사용하며, 필요한 경우 리플렉션을 활용하여 어노테이션의 정보를 읽을 수 있다.MyAnnotation.interfacepackage com.group.libraryapp.annotationTest; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MyAnnotation { String name(); String value() default "value의 기본 값"; } Class.javapackage com.group.libraryapp.annotationTest; public class Class { @MyAnnotation(name = "비둘기",value = "pigeon") public void doThis(){ } @MyAnnotation(name = "pigeon") public void doThat(){ } } MethodAnnotationExecutor.javapackage com.group.libraryapp.annotationTest; import java.lang.annotation.Annotation; import java.lang.reflect.Method; public class MethodAnnotationExecutor { public static void main(String[] args) throws NoSuchMethodException { Method method = Class.class.getMethod("doThis"); Annotation[] annotations = method.getDeclaredAnnotations(); for(Annotation annotation : annotations){ System.out.println(annotation); if(annotation instanceof MyAnnotation){ MyAnnotation myAnnotation = (MyAnnotation) annotation; System.out.println("name : " + myAnnotation.name()); System.out.println("value : " + myAnnotation.value()); } } } }
백엔드
・
어노테이션




