동석쿠
프로그래밍 공부
동석쿠
전체 방문자
오늘
어제
  • 공부 (80)
    • 공부기록 (64)
      • 웹개발 (6)
      • Java (7)
      • cs 공부 (3)
      • http 웹 기본 지식 (8)
      • 자바 스프링 (20)
      • 개인 미니프로젝트 (3)
      • 알고리즘 공부 (6)
      • 면접준비 (2)
      • 프론트공부 (8)
      • 파이썬 플라스크 (1)
    • 항해99 기록 (14)
      • 회고록 (10)
      • 팀프로젝트 (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 스프링
  • 파이썬
  • 문법
  • 알고리즘
  • lombok
  • 항해99
  • Get
  • Post
  • 리스트
  • 리액트
  • 리프레시토큰
  • 스프링부트
  • JPA
  • Java
  • API
  • 자바
  • 자바스크립트
  • 프로그래머스
  • 상속
  • 리프레쉬토큰

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
동석쿠

프로그래밍 공부

스프링 아이템기능 구현, 단어 뒤집기, 파파고 API
공부기록/자바 스프링

스프링 아이템기능 구현, 단어 뒤집기, 파파고 API

2022. 3. 12. 15:18

프로젝트 기능중 채팅방에서 유저가 아이템을 쓸 수 있는 기능이 있다.

유저가 아이템을 사용하기 위해선 아이템을 구매할 수 있어야 한다.

 

@GetMapping("/mypage/{item}")
    @ApiOperation(value = "아이템 구매")
    public HashMap<String, Object> buyItem(@PathVariable String item, @AuthenticationPrincipal UserDetailsImpl userDetails) {
        User user = userDetails.getUser();
        itemService.buyItem(item, user);

        HashMap<String, Object> result = new HashMap<>();
        result.put("result", "true");
        return result;

컨트롤러에서 다음과같이 pathvariable로 item의 스트링 값을 받아온다.

public void buyItem(String item, User user) {
        Item buyitem = itemRepository.findById(user.getItem().getId()).orElseThrow(
                () -> new ItemNotFoundException("아이템이 없습니다")
        );

        switch (item) {
            case "onlyMe":
                buyitem.setOnlyMe(buyitem.getOnlyMe() + 1);
                itemRepository.save(buyitem);
                itemBuy(user, onlyMePrice, "나만 말하기");
                break;
            case "bigFont":
                buyitem.setBigFont(buyitem.getBigFont() + 1);
                itemRepository.save(buyitem);
                itemBuy(user, bigFontPrice, "내글자 크게하기");
                break;
            case "myName":
                buyitem.setMyName(buyitem.getMyName() + 1);
                itemRepository.save(buyitem);
                itemBuy(user, myNamePrice, "모두 내이름으로 바꾸기");
                break;
            case "papago":
                buyitem.setPapago(buyitem.getPapago() + 1);
                itemRepository.save(buyitem);
                itemBuy(user, papagoPrice, "파파고 랜덤 번역");
                break;
            case "reverse":
                buyitem.setReverse(buyitem.getReverse() + 1);
                itemRepository.save(buyitem);
                itemBuy(user, reversePrice, "글자 뒤집기");
                break;
            case "exBuy":
                user.setEx(user.getEx()+exBuyPrice);
                userRepository.save(user);
                itemBuy(user, Long.valueOf(exBuyPrice),"경험치");
                break;
        }
    }

각각의 케이스별로 아이템 구매시의 상황을 만들어 구매할 수 있게 해두었다.

//아이템 구매
    private void itemBuy(User user, Long price, String item) {
        if (user.getTotalPoint() >= price) {
            user.setTotalPoint(user.getTotalPoint()-price);
            userRepository.save(user);
            Point point = new Point(item + " 구매", -price, user.getTotalPoint(), user);
            pointRepository.save(point);
        } else {
            throw new LackPointException("보유한 포인트가 부족합니다");
        }
    }

 

@GetMapping("/chat/rooms/{item}")
    @ApiOperation(value = "아이템 사용")
    public HashMap<String, Object> userItem(@PathVariable String item, @AuthenticationPrincipal UserDetailsImpl userDetails) {
        User user = userDetails.getUser();
        itemService.useItem(item, user);

        HashMap<String, Object> result = new HashMap<>();
        result.put("result", "true");
        return result;
    }
//아이템 사용
    public void useItem(String item, User user) {
        Item useitem = itemRepository.findById(user.getItem().getId()).orElseThrow(
                () -> new ItemNotFoundException("아이템이 없습니다")
        );
        switch (item) {
            case "onlyMe":
                if(useitem.getOnlyMe()>=1) {
                    useitem.setOnlyMe(useitem.getOnlyMe() - 1);
                    itemRepository.save(useitem);
                }else {
                    throw  new ItemNotFoundException("아이템이 없습니다");
                }
                break;
            case "bigFont":
                if(useitem.getBigFont()>=1) {
                    useitem.setBigFont(useitem.getBigFont() - 1);
                    itemRepository.save(useitem);
                }else {
                    throw  new ItemNotFoundException("아이템이 없습니다");
                }
                break;
            case "myName":
                if(useitem.getMyName()>=1) {
                    useitem.setMyName(useitem.getMyName() - 1);
                    itemRepository.save(useitem);
                }else {
                    throw  new ItemNotFoundException("아이템이 없습니다");
                }
                break;
            case "papago":
                if(useitem.getPapago()>=1) {
                    useitem.setPapago(useitem.getPapago() - 1);
                    itemRepository.save(useitem);
                }else {
                    throw  new ItemNotFoundException("아이템이 없습니다");
                }
                break;
            case "reverse":
                if(useitem.getReverse()>=1) {
                    useitem.setReverse(useitem.getReverse() - 1);
                    itemRepository.save(useitem);
                }else {
                    throw  new ItemNotFoundException("아이템이 없습니다");
                }
                break;
        }
    }

아이템 사용도 아이템 구매와 같은 방식으로 이루어진다.

 

코드에 반복되는 부분이 너무 많고 이것들을 획기적으로 줄일수있는 아이디어가 있을거라 생각된다.

우선 기능구현을 목표로 코드를 짜두었고 기능을 먼저 만든다음에 리팩터링을 할 계획이다.

 

다음으로는 아이템 기능 구현이다. 내가 맡은부분은 papago아이템과 reverse아이템이다

reverse아이템은 나 이외의 다른 유저들이 채팅을 칠 경우 단어가 뒤집혀서 나가게 된다.

papago아이템은 나 이외의 다른 유저들이 채팅을 칠 경우 단어가 11개국어중 랜덤으로 번역되어서 나가게 된다.

user1이 각각 papago아이템과 reverse아이템을 사용한 결과

먼저 reverse 아이템의 경우

    //단어 거꾸로 하기
    public static String reverseWord(String word) {
        StringBuffer sb = new StringBuffer(word);
        return sb.reverse().toString();
    }

간단하게 reverse메소드를 이용해서 만들어주었다.

 

그다음 papago아이템의 경우 네이버 papago의 오픈 api를 이용하여 만들었는데

 //파파고
    public static String papago(String string) throws IOException, NoSuchAlgorithmException {
        String clientId = "";//애플리케이션 클라이언트 아이디값";
        String clientSecret = "";//애플리케이션 클라이언트 시크릿값";

        String apiURL = "https://openapi.naver.com/v1/papago/n2mt";
        String text;
        try {
            text = URLEncoder.encode(string, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("인코딩 실패", e);
        }

        Map<String, String> requestHeaders = new HashMap<>();
        requestHeaders.put("X-Naver-Client-Id", clientId);
        requestHeaders.put("X-Naver-Client-Secret", clientSecret);
        String responseBody = post(apiURL, requestHeaders, text); //74개 짜르기
        String text1 = responseBody.substring(responseBody.indexOf("translatedText")+17);
        return text1.substring(0, text1.indexOf("engineType")-4); //뒤에 점찍히는거 뺄거면 -4 넣을거면 -3
    }

    private static String post(String apiUrl, Map<String, String> requestHeaders, String text) throws IOException, NoSuchAlgorithmException {
        HttpURLConnection con = connect(apiUrl);
        Random random = SecureRandom.getInstanceStrong();
        int num = random.nextInt(11);
        String postParams;
        if (num == 1) {
            postParams = "source=ko&target=en&text=" + text;
        } else if(num==2) {
            postParams = "source=ko&target=ja&text=" + text;
        }else if(num==3) {
            postParams = "source=ko&target=zh-CN&text=" + text;
        }else if(num==4) {
            postParams = "source=ko&target=vi&text=" + text;
        }else if(num==5) {
            postParams = "source=ko&target=id&text=" + text;
        }else if(num==6) {
            postParams = "source=ko&target=th&text=" + text;
        }else if(num==7) {
            postParams = "source=ko&target=de&text=" + text;
        }else if(num==8) {
            postParams = "source=ko&target=ru&text=" + text;
        }else if(num==9) {
            postParams = "source=ko&target=es&text=" + text;
        }else if(num==10) {
            postParams = "source=ko&target=it&text=" + text;
        }else{
            postParams = "source=ko&target=fr&text=" + text;
        }
//        postParams = "source=ko&target=en&text=" + text; //원본언어: 한국어 (ko) -> 목적언어: 영어 (en)
        try {
            con.setRequestMethod("POST");
            for(Map.Entry<String, String> header :requestHeaders.entrySet()) {
                con.setRequestProperty(header.getKey(), header.getValue());
            }

            con.setDoOutput(true);
            try (DataOutputStream wr = new DataOutputStream(con.getOutputStream())) {
                wr.write(postParams.getBytes());
                wr.flush();
            }

            int responseCode = con.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) { // 정상 응답
                return readBody(con.getInputStream());
            } else {  // 에러 응답
                return readBody(con.getErrorStream());
            }
        } catch (IOException e) {
            throw new RuntimeException("API 요청과 응답 실패", e);
        } finally {
            con.disconnect();
        }
    }

    private static HttpURLConnection connect(String apiUrl){
        try {
            URL url = new URL(apiUrl);
            return (HttpURLConnection)url.openConnection();
        } catch (MalformedURLException e) {
            throw new RuntimeException("API URL이 잘못되었습니다. : " + apiUrl, e);
        } catch (IOException e) {
            throw new RuntimeException("연결이 실패했습니다. : " + apiUrl, e);
        }
    }

    private static String readBody(InputStream body){
        InputStreamReader streamReader = new InputStreamReader(body);

        try (BufferedReader lineReader = new BufferedReader(streamReader)) {
            StringBuilder responseBody = new StringBuilder();

            String line;
            while ((line = lineReader.readLine()) != null) {
                responseBody.append(line);
            }

            return responseBody.toString();
        } catch (IOException e) {
            throw new RuntimeException("API 응답을 읽는데 실패했습니다.", e);
        }
    }

파파고 api코드에 대한 정확한 이해는 하지 못하였으나 기능을 만들기 위해 사용하였다.

String post메소드에서 난수를 생성하여 랜덤으로 번역되서 나가게 설정해두었다 위 코드의 경우도 리팩터링을 통해

충분히 코드를 바꿀 수 있을거라 생각이 든다

'공부기록 > 자바 스프링' 카테고리의 다른 글

JPA 연관관계  (0) 2022.04.17
스프링 아이템기능 리팩터링  (0) 2022.03.19
스프링 룰렛기능 만들기 (가챠시스템), 자바 난수 설정, 확률설정  (0) 2022.03.09
스프링 배팅시스템 만들기 (트위치 배팅시스템 참고)  (0) 2022.03.08
스프링부트 JPA 중복검색 해결 <트러블 슈팅>  (0) 2022.03.07
    '공부기록/자바 스프링' 카테고리의 다른 글
    • JPA 연관관계
    • 스프링 아이템기능 리팩터링
    • 스프링 룰렛기능 만들기 (가챠시스템), 자바 난수 설정, 확률설정
    • 스프링 배팅시스템 만들기 (트위치 배팅시스템 참고)
    동석쿠
    동석쿠

    티스토리툴바