[LIKELION] 221027

고관운·2022년 10월 27일

회고

😄 느낀점

  • Java에 내장되어 있는 Hash 메서드 사용 연습이 필요하다.
  • HTTP 메서드이 무엇인지 배우고 구현했다. 각 메서드의 차이점과 구현 방법에 대한 복습이 필요하다.

😁 목표

  • 프로젝트 새로 빌드해서 Swagger적용까지 복습
  • 백준 알고리즘

알고리즘(Hash)

완주하지 못한 선수(프로그래머스)

문제

👀 문제 확인하기 👀

방법 1

  1. HashMap에 participant 모두 넣으면서 1로 초기화
  2. completion에 들어있는 이름을 key로 HashMap에 검색, 있으면 0으로 update
  3. memo를 한바퀴 돌면서 1인 값을 찾고 리턴

🔸 단, 이 방법에서는 동명이인에 대한 작업이 없기 때문에 문제 발생

import java.util.HashMap;
import java.util.Map;

class Solution {
    public String solution(String[] participant, String[] completion) {
        Map<String, Integer> memo = new HashMap<>();
        for (String eachParticipant : participant) {
            memo.put(eachParticipant, 1);
        }

        for (String eachCompletion : completion) {
            memo.put(eachCompletion, 0);
        }
        for (String key : memo.keySet()) {
            if (memo.get(key) == 1){
                return key;
            }
        }
        return null;
    }
}

방법 개선

  1. HashMap에 participant 모두 넣으면서 1로 초기화
    (단, 기존에 넣은 것이 있다면 value에 값을 불러온 후 +1)
  2. completion에 들어있는 이름을 key로 HashMap에 검색, 있으면 -1해주고 갱신
  3. memo를 한바퀴 돌면서 1인 값을 찾고 리턴

🟢 getOrDefault : key값이 없으면 default, 있으면 매핑되는 value 리턴

import java.util.HashMap;
import java.util.Map;

class Solution {
    public String solution(String[] participant, String[] completion) {
        Map<String, Integer> memo = new HashMap<>();
        for (String eachParticipant : participant) {
            memo.put(eachParticipant, memo.getOrDefault(eachParticipant, 0)+1);
        }

        for (String eachCompletion : completion) {
            memo.put(eachCompletion, memo.get(eachCompletion)-1);
        }
        for (String key : memo.keySet()) {
            if (memo.get(key) == 1){
                return key;
            }
        }
        return null;
    }
}

Git

Fork하는 방법

  1. 대상 레퍼지토리로 이동
  2. Fork 클릭
  3. 레퍼지토리명 변경 및 다른 설정 후 Create fork

Spring Boot

HTTP 메서드

  • get : select(/member) - selelct from member between, limit 100 -> list 목록 리턴
    /memeber/(id)) - select from member where id = ?
  • post : insert(/member) RequestBody
  • put : update(/member) RequestBody
  • delete : delete(/member)

GET

API 문서

API 문서 : API쓰는 법을 써놓은 문서

Github에 적용

  1. 👀 Github.api 👀 접속하면 원하는 api를 가져오는 법을 알 수 있음

  2. Commit api 가져오기
    https://api.github.com/repos/{OWNER}/{REPO}/commits의 형태로 적용
    ex) https://api.github.com/repos/KoKwanwun/LikeLion/commits

API 문서의 Path parameters, Query parameters 기능

  • Path parameters : 주소를 통해 값을 넘길 때 사용(@PathVariable)
    (주로 id 등 꼭 넣어주어야 하는 파라미터는 Path parameter로 만듦)
  • Query parameters : ?표 뒤로 전달하는 파라미터(@RequestParam)
    (ex. ?since=시간 : 시간 이후의 데이터만 보겠다)
    (Optional 있어도 되고 없어도 되는 파라미터는 Query parameters로 만듦)

@RequestParam 실습

  1. name, email, organization을 받아 출력
    http://localhost:8081/api/v1/get-api/request1?name=Kwanwun&email=dkfajflsla@naver.com&organization=likelion
    👉 ?뒤의 각 변수에 해당하는 값을 가져와서 출력(변수들끼리 연결할 때는 & 사용)
    @GetMapping(value = "/request1")
    public String getRequestParam1(@RequestParam String name,
                               @RequestParam String email,
                               @RequestParam String organization) {
        return name + " " + email + " " + organization;
    }

🔸 Talend에서 QUERY PARAMETERS 기능을 사용하면 조금 더 쉽게 입력 가능

  1. Map<String, String> 형식으로 받아 모든 값 출력
    🔸 미리 key를 지정하지 않아도 되는 장점이 있음
    👉 uri형식만 맞춘다면 변수를 계속 추가할 수 있음
    @GetMapping(value = "/request2")
    public String getRequestParam2(@RequestParam Map<String, String> param) {
        StringBuilder sb = new StringBuilder();

        param.entrySet().forEach(map -> {
            sb.append(map.getKey() + " : " + map.getValue() + "\n");
        });

        return sb.toString();
    }
  1. 클래스를 따로 생성하여 객체를 받아 출력

    실습 전 개념

    • DTO(Data Transfer Object)
    • VO(Value Object) : 값이 들어있는 클래스
    • DAO(Data Access Object)
      (ex. UserDao -> 데이터를 insert, findById, getCount, deleteAll(Create Update Delete)

    실습
    MemberDto를 VO로 하나 만듦

public class MemberDto {
    private String name;
    private String email;
    private String organization;

    public MemberDto(String name, String email, String organization) {
        this.name = name;
        this.email = email;
        this.organization = organization;
    }

    public String getName() {
        return name;
    }

    public String getEmail() {
        return email;
    }

    public String getOrganization() {
        return organization;
    }

    @Override
    public String toString() {
        return String.format("%s %s %s", this.name, this.email, this.organization);
    }
}

🔸 객체를 입력받고 오버라이딩된 toString으로 출력
🔴 이 방법을 사용할 때는 @RequestParam을 쓰지 않음.

    @GetMapping(value = "/request3")
    public String getRequestParam3(MemberDto memberDto) {
        return memberDto.toString();
    }

방법별 @RequestParam 사용유무 정리

  • @RequestParam : 단일 변수 앞에만 사용(Map 앞에도 가능)(생략도 가능)
  • VO 앞에는 무조건 생략해야함

POST

GET VS POST

  • HTTP 요청을 할 때 파라미터를 path나 쿼리파라미터를 쓰지 않고 Request Body에 보냄(GET은 URI에, POST는 HTTP 바디에)
  • 주로 회원가입 등 Http전송 중 노출되면 안되는 정보를 보낼 때 Post를 사용
  • Get이 디폴트

JSON

JavaScript Object Notation(자바스크립트에서 Object(Class) 표현법)

{"name":"Kwanwun", "email":"dkfajflsla@naver.com"}으로 표현

JSON 코드

let user = {"name":"Kwanwun", "email":"dkfajflsla@naver.com"}
user['email']

👉 dkfajflsla@naver.com

@RequestBody

  • Post에서는 @RequestBody를 주로 사용함
  • json(등) 형식으로 넘어온 데이터를 사용할 수 있게 해줌.
    (어떤 타입으로 데이터가 들어올지 모르기 때문에 Object로 처리하는 것)

실습

  1. Map<String, String> 형식으로 받아 모든 값 출력
    @PostMapping(value = "/member")
    public String postMember(@RequestBody Map<String, String> postData){
        StringBuilder sb = new StringBuilder();

        postData.entrySet().forEach(map -> {
            sb.append(map.getKey() + " : " + map.getValue() + "\n");
        });

        return sb.toString();
    }

🔸 Body 부분에 json 형식으로 넣어 해당 정보를 출력하도록

  1. 클래스를 따로 생성하여 객체를 받아 출력
    @PostMapping(value = "/member2")
    public String postMemberDto(@RequestBody MemberDto memberDto){
        return memberDto.toString();
    }

Put

Put이란

put은 post와 비슷하지만 주로 Update하는데 사용함

@ResponseEntity

  • ResponseEntity는 get, post, put, delete, patch 모두 사용할 수 있음
  • Http Response Header와 Body를 구성하기 쉽게 해줌
  • .status(HttpStatus.ACCEPTED) : 응답코드가 202로 변경됨

실습

import com.springboot.springbootcoreguide.domain.dto.MemberDto;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/v1/put-api")
public class PutController {
    @PutMapping(value = "/member3")
    public ResponseEntity<MemberDto> putMemberDto3(@RequestBody MemberDto memberDto){
        return ResponseEntity
                .status(HttpStatus.ACCEPTED)
                .body(memberDto);
    }
}

🔸 ResponseEntity 사용 유무 차이

  • 사용X : content-type : text/plain
  • 사용O : content-type : application/json

Swagger

Swagger란?

해당 API가 어떤 로직을 수행하는지 설명하고 어떤 값을 요청하며, 이에 따른 응답값으로는 무엇을 받을 수 있는지를 정리하여 보여주는 오픈소스 프로젝트

Swagger 적용 절차

1.pom.xml에서 Alt + Enter로 Add Dependency(🔸 단, dependencies 사이에 넣기)
2. springfox-boot-starter, springfox-swagger-ui 추가 후 새로 고침
3. 실행 후 http://localhost:8081/swagger-ui/ 접속
(자신의 포트가 8080이면 8080으로 변경 후 사용)
4. 아래 화면과 같이 뜨면 성공!

진행간 오류사항

  1. dependencies추가 후 오류
    <artifactId>spring-boot-maven-plugin</artifactId> 이 코드에서 오류가 난다면
    👉 <version>${parent.version}</version> 코드를 아래 코드 위치에 추가
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>${parent.version}</version>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
  1. 실행하면 오류 발생 (SpringBoot 2.5.X이상에서 발생하는 것 같음)
    1. application.propertiesapplication.yml로 이름 변경 필요
    2. application.yml에 아래와 같이 추가

    spring:
     mvc:
       pathmatch:
         matching-strategy: ant_path_matcher

    (기존 포트 변경 코드를 살리고 싶다면)

    server:
      port: 8081
    
    spring:
      mvc:
        pathmatch:
          matching-strategy: ant_path_matcher

0개의 댓글