아마존 corretto 윈도우 버전과, 아파치 maven, 이클립스가 오늘의 준비물

 

 

 

Corretto와 이클립스, maven을 해당 폴더에 압축을 푼다. 그리고 maven_repository 폴더와 eclipse-workspace 폴더를 만든다.

 

 

찾기에 시스템 환경 변수 편집에 들어가서 저 두개가 있는지 확인하고 없으면 새로 만들기로 추가

 

 

 

Path를 편집한다. 해당 주소를 추가한다

 

 

 

이클립스의 eclipse.ini 를 열고 해당 구문을 추가한다. 모든 파일을 UTF-8 형식으로 하겠다는 뜻. 그리고 닉네임은 본인이 원하는 닉네임으로 설정하면 된다.

 

 

 

 

maven의 레포시토리를 해당 폴더에 저장하고 싶으면 maven 해당 주소의 settings에 들어가서 다음과 같이 수정한다.

주석도 풀어준다.

 

 

 

 

이클립스 누르고 해당 워크스페이스로 주소 설정 후, 이클립스에 들어가서, window -> Preference 클릭

Maven의 유저셋팅를 다음과 같이 셋팅한다.

 

 

 

 

 

폰트도 다음처럼 원하는 대로

 

 

 

 

lombok.jar 를 다운로드 후 이클립스 폴더에 넣고

 

1.7이 아닌 17버전

'자바' 카테고리의 다른 글

[Java] JSON 변환하기 : json-simple  (0) 2024.12.03
[JAVA] 컬렉션(Collection) 정리  (0) 2024.09.04
[Java] DB 연결  (0) 2023.07.19
[Java] 익명객체  (0) 2023.07.18
[JAVA] HashMap  (0) 2023.05.17

주로 회원가입 부분을 만들 때, 우편번호나 도로명 주소를 검색하고 입력하는 기능을 추가하기도 한다. 요청, 허가 없이 누구나 쓸 수 있는 다음 주소 찾기 API를 사용하여, 회원가입의 우편번호 입력 기능을 구현해보자

 

 

 

 

 

일단 HTML과 CSS, JS로 회원가입 부분을 만들었다. 주목해야 할 곳은 우편번호 찾기 부분이다. 우편번호 찾기를 눌렀을 시, 검고 투명한 배경 그리고 x 표시와 함께 하얀색 네모박스를 생성하도록 만들었고, x 표시를 누르면 다시 사라지도록 했다. 우리는 하얀색 네모 박스 안에 다음 주소 API를 넣을 예정이다.

 

 

 

 

 

구글에 '다음 주소 찾기 api'를 검색하면 맨위에 뜨는 페이지가 있는데 클릭한다.

 

 

 

 

그리고 아래로 내려가면 이런 코드가 보이는데, 맨 위의 코드를 복사하고

 

 

 

HTML 파일의 head 부분에 붙여넣기 한다. 반드시 해당 HTML의 js보다 윗줄에 적어야 한다는 것을 명심

 

 

 

위에서 보여준 자바스크립트 코드의 API 부분이다. new daum.Postcode 안에 다음과 같이 적는데, oncomplete은 팝업에서 내가 주소를 클릭했을 때, 무엇을 실행할지를 적으면 된다.

 

일단 파라미터로 적은 data를 콘솔로 찍어 보면

 

주소를 클릭했을 시, 콘솔로 이렇게 나타난다. 우리가 선택한 data는 오브젝트 형식이다.

 

 

 

그럼 oncomplete 에서 저 오브젝트 부분의 값들을 회원가입 우편번호 텍스트 input 의 값으로 넣으면 된다. data의 'zonecode'는 우편번호, 'address'는 주소

 

 

 

 

 

확인해본 결과 값들이 input 텍스트 안에 불려져 왔다.

 

 

 

 

 

카카오 지도를 함께 사용하고 있을 경우 geocoder를 이용, 주소를 불러오면 해당 좌표로 이동해서 지도를 보여준다.

'API' 카테고리의 다른 글

[API] 포트원 API 사용하기 (Spring Boot)  (0) 2024.07.11
[API] 카카오 로그인 API 구현  (0) 2024.05.13
[API] 카카오 지도 API 추가하기  (0) 2024.03.25

XHR 이란?

자바스크립트의 XMLHttpRequest 객체를 통해 구현 할 수 있다. AJAX 라고 부르기도 한다. 페이지 새로고침 없이 , 비동기적으로 서버에 요청을 보내고 응답을 받아오기 위해 사용한다.

 

구조

 

 

속성과 메서드, 이벤트

정적 속성
- UNSENT : XHR 객체의 readyState 속성 값으로 0과 같고, XHR 객체가 객체화된 후 아무런 동작을 하지 않은 초기 상태이다.
- OPENED : XHR 객체의 readyState 속성 값으로 1과 같고, open 메서드 호출 후의 상태이다.
- HEADERS_RECEIVED : XHR 객체의 readyState 속성 값으로 2과 같고, send 메서드 호출 후 서버와의 연결을 수립한 상태이다.
- LOADING : XHR 객체의 readyState 속성 값으로 3과 같고, 서버의 응답이 수신되기 시작한 상태이다.
- DONE : XHR 객체의 readyState 속성 값으로 4과 같고, XHR 통신이 성공 여부와 관계 없이 종료되었음을 의미한다.(통신 성공 여부는
status 속성 값이 200 이상 300 미만인지의 여부로 판단해야 한다.)


객체 속성
- readyState : XHR 객체의 대기 상태(숫자)이다.
- responseText : 서버가 응답으로 전송한 문자열 데이터이다.
- status : XHR 객체의 HTTP 상태 코드이다.
* 200 : OK . 정상상태 ( 200 이상 300 미만의 값을 정상 상태로 간주한다. )
* 400 : Bad Request . 서버가 요청하고 있는 데이터를 클라이언트가 누락하였거나 그 데이터의 형태가 잘못되었음을 의미한다.
* 404 : Not Found . 해당 경로에 대한 맵핑(엔드포인트)이 서버에 존재하지 않는다는 의미이다.
* 405 : Method Not Allowed . 경로는 존재하지만 해당 요청 방식(Method)으로 접근할 수 없다는 의미이다.
* 500 : Internal Server Error . 요청을 처리하는 도중 서버 내부에서 오류가 발생하였다는 의미이다.


객체 메서드
- abort( ) : send 메서드 호출 이후 요청에 대한 응답 대기를 취소한다.
- open(m, u) : 요청을 보낼 준비를 하기 위해 호출한다. 요청을 보낼 방식(Method)인 문자열을 m, 주소인 문자열을 u 에 전달한다.
- send(d) : 요청을 실질적으로 전송한다. 이 때 d 는 요청에 함께 보낼 데이터이며, 보낼 데이터가 없다면, 생략가능하다. 단 요청방식
  (open 메서드의 m 인자)이 GET 일 경우 데이터 인자( d ) 전달이 불가능하다.


객체 이벤트
- onabort : 응답 대기 상태에서 abort 메서드가 호출되었을 때 실행할 이벤트 함수
- onerror : 요청 도중 오류가 발생하였을 때 실행할 이벤트 함수
- onprogress : 서버로 부터 데이터를 수신 받을 때 마다 실행할 이벤트 함수
- onreadystatechange : XHR 객체의 readyState 속성 값이 변할 때 마다 실행할 이벤트 함수
- ontimeout : 응답 대기 시간이 지정한 제한 시간을 초과하엿을 때 실행할 이벤트 함수

 

 

 

실습

 

요청을 하기 위해 보낼 준비를 하는 메서드 open 부분의 저 주소는 현재 내 컴퓨터의 아이피 주소를 반환하는 주소이다.

xhr.readyState는 주로 0,1, 2, 3, 4를 리턴하는데, 이는 정적 속성 부분을 나타내는 숫자이다. 호출, 호출 수 수신 등등

xhr.status는 XHR 객체의 대기 상태인데, 200일 경우 요청 성공, 그 외에는 요청 실패이다.

xhr.responseText는 불러온 요청을 문자열로 반환된 상태이다. 

 

 

 

버튼을 누르고 네트워크에 가면, json 형식의 요청이 왔는데, 응답 부분을 누르면 오브젝트 형식의 값이 뜬다.

저 값을 문자열로 반환된 상태로 불러오는 것이 xhr.responseText이다. 이를 풀기 위해서는 JSON.parse( ) 메서드를 쓰면 된다.

 

 

댓글 사진 기능을 구현하는 중, 오류가 발생하였다. 그 이유는 용량이 작은 이미지들은 아무 문제없이 잘 업로드 됐었는데,

용량이 큰 이미지들을 업로드하자 오류가 발생했던 것이었다.

 

해결점을 찾아보던 중 application.properties 파일을 수정하면 된다는 것을 알았다.

 

spring.servlet.multipart.enabled=true
spring.servlet.multipart.max-file-size=3145728000
spring.servlet.multipart.max-request-size=47185920000
spring.webflux.multipart.headers-charset=UTF-8

 

첫번째는 파일 업로드 가능 여부이다, true 로 설정해준다.

두번째는 파일 하나의 최대 크기이다.

세번째는 한번에 최대 업로드 가능 용량이다.

네번째는 한글 파일명 깨짐을 방지하기 위해 UTF-8로 인코딩 설정한다.

 

 

이런식으로 파일 용량 부분을 수정하였더니 용량이 큰 이미지들도 오류 없이 업로드 되었다.

나는 팝업창을 이용하여 비밀번호가 맞으면 해당 게시물을 삭제하는 방식으로 게시물 삭제 기능을 만들었다. BUT 문제는 로그인 사용자가 게시물을 삭제했을 경우 해당 서버가 리다이렉트 되어서 해당 게시판으로 이동되었을 시, 삭제된 게시물은 더이상 보여지지 않았으나 익명 사용자가 게시물을 삭제했을 시, 자바스크립트로만 부모 창이 이동했을 뿐, 리다이렉트가 되지 않아서 삭제된 게시물이 게시판에 그대로 나타나게 되었다는 것이 문제였다.

 

그래서 이 방법을 해결하기 위해 찾아본 결과.. 간단했다. 

그냥 해당 부모창에서 reload를 시전하면 되는 것이었다.

 

이런 식으로 해당 게시판 창을 reload 하면 자동으로 새로고침이 되어서 삭제된 해당 게시물이 더이상 게시판 목록에 나타나지 않는다.

 

 

 

 

 

 

 

실험해 본 결과 제대로 동작하였다.

이 전에 페이징을 구현해 본 적 있지만, 자바스크립트에서 구현했기 때문에, HTML 타임리프로는 어떻게 구현해야 할지 고민했었다. 하지만 오히려 자바스크립트에서 구현한 것보다 더 간단했다.

 

 

 

이렇게 게시물 조회 쿼리는 ORDER BY문과 LIMIT문을 추가한다. 한 페이지에 15개의 게시물을 나타내려 한다.

그리고 해당 게시판의 게시물 총 갯수를 구하는 쿼리도 사용한다.

 

 

지난번에 썼던 페이징 클래스

 

 

 

그 전에 해당 게시판으로 가는 경우 page라는 파라미터를 주소에 넣는다. 그리고 값은 1을 설정한다. 이 경로들에 전부 파라미터를 추가해야만 했었다.

 

 

 

그럼 page 파라미터가 불려저온다. 해당 게시판의 게시물 갯수를 우선 구하고, 페이징 클래스의 생성자의 파라미터에 현재 페이지, 한 페이지에 표시할 데이터의 수, 전체 데이터 갯수를 집어넣어, 페이징 계산을 한다.

 

page 파라미터는 곧 현재 페이지를 의미하고, 여기서 2, 3, 4 등등 숫자가 변하면 해당 페이지의 게시물들을 불러오는 방식이다. offset을 위한 계산을 한다. 현재 페이지가 1페이지인데, 여기서 1페이지-1을 하면 0이고 0 * 15는 0이므로 LIMIT 0, 15의 게시물들이 불려져 올 것이다. 2페이지면 또다시 계산대로 LIMIT 15, 15의 게시물이 불려져 올 것이고...

 

그리고 현재 페이지 넘버, 해당 페이지의 게시물들, 페이징 정보들을 Model로 뷰에 보낸다.

 

 

 

여기는 HTML, 게시물 쪽 HTML은 이미 맞게 작성되어 있었기 때문에 수정하지 않았다. 페이징 부분을 다음과 같이 수정했다. 그리고 현재 페이지를 값으로 둔 히든 input을 생성한다.

 

타임리프 문법을 이용했다. 만약 showPrev(이전표시여부)가 참일 경우 해당 태그를 나타내고, 거짓일 경우 해당 태그를 나타내지 않는다. showNext(이후표시여부) 역시 마찬가지로 한다.

 

each문을 이용하여 시작 페이지수와 끝 페이지수까지 버튼을 만든다. 그리고 그  버튼의 태그에 해당 수를 이름으로한 클래스를 걸어둔다. (표시를 위해)

 

그리고 마지막으로 전체 페이지수(totalPage)가 없다면.. (즉 게시물이 하나도 없다면) 페이징 태그들을 모두 나타내지 않는다.

 

 

 

 

 

마지막으로 자바스크립트로 가서 , 현재 페이지를 값으로 둔 hidden input을 불러오고 그렇게 불러온 현재 페이지의 수 값으로 현재 페이지 버튼을 클래스로 하여금 찾게 한다. 그리고 그 버튼의 스타일을 수정한다.

 

 

 

 

페이징이 잘 되는 것을 확인할 수 있었다.

 

익명 유저일 경우 닉네임 앞에 "(익명)"을 추가해서 데이터에 넣는 방식으로 구현하였는데, 이후 댓글 삭제 버튼을 누를 시 오류가 생겼다.

 

자바스크립트 오류로 onclick에서 String 파라미터를 넘겨야 하는데 못 넘겨서 발생한 오류이다.

이는 따움표로 감싸주지 않아서 발생한다.

 

 

\'  파라미터  \'

이런식으로 따옴표를 감싸주면 오류가 해결된다.

 

 

나는 로그인 유저일 경우 바로 삭제가 되도록 새로운 삭제 서버를 만들어서, 매핑을 시켰다. 제대로 한 것 같은데, 제목과 같은 에러가 떴다. 그래서 찾아보니, 리다이렉트로 넘어간 곳이 getMapping 부분이었는데, 로직이 꼬여서 저런 현상이 발생한 것이었다.

 

 

 

해결 방법

문제는 다음과 같이 해결하였다.

게시판에 들어가면 게시물 table에 저장된 자료들을 foreach문으로 나열해 놓은 모습이다. 그러나 하나가 빠졌다. 바로 추천 부분.. 추천 부분은 따로 설정하지 않고 0으로 해놨다. 지난번에 포스팅해서 알겠지만 추천 테이블을 따로 있다. 그래서 이를 조인하여 추천 수 count를 추출하는 방식으로 하려 했으나 잘 되지 않았다. 결국 db 관련 정보들을 찾아본 결과 방법을 알아냈다.

 

 

board 테이블과, board_post 테이블은 이미 조인되어 있었던 상황이었다.(게시판 이름(board)에 매칭되는 게시물들(board_post)을 조회해야 했기 때문) 나는 그 쿼리문을 다음과 같이 수정했다.

 

먼저 게시물 추천 테이블인 board_post_like 테이블을 LEFT OUTER JOIN 한다. 추천 되어있지 않은 게시물 또한 조회해야 하기 때문이다. 그리고 특정 컬럼을 조회하는 select 뒷 부분에 서브쿼리를 하나 넣는다(괄호로 된 부분)

 

서브쿼리를 해석 해 보자면, 해당 게시물의 넘버에 매칭되는 해당 추천 테이블들의 갯수 값을 조회한다. fk로 걸어 놓은 컬럼의 갯수가 2개라면 2개, 1개라면 1개 이런식... 그리고 AS문을 이용하여 이 서브쿼리로 만든 컬럼의 이름을 지정한다(post_like_count)

 

마지막으로 중요한 것... LEFT OUTER JOIN을 했기 때문에, 만약 추천 테이블의 행이 2개라면 해당 게시물은 2개로 나타나게 된다. 그래서 SELECT 뒤에 DISTINCT를 걸어서 같은 행이 나올 경우 생략을 하도록 하였다.

 

 

 

 

그럼 이런 식으로 테이블이 생성된다. 맨 오른쪽을 보면 post_like_count 컬럼이 정상적으로 조회되는 걸 확인할 수 있다. 이제 이 테이블을 뷰에 보여지도록 하자..

 

 

 

솔직히 약간 해맸다. 서브쿼리 부분으로 만든 컬럼값을 DTO에 어떻게 담아낼지 알지 못했기 때문.. 하지만 그 동안에 배웠던 논리들을 적용시켜서 해봤다.

먼저 추천수 테이블을 나타내는 VO에 들어가서 서브쿼리로 만든 컬럼 이름 (int postLikeCount) 을 추가한다.

 

 

 

Xml에 와서 이미 만들어져 있는 쿼리를 다음과 같이 수정한다. resultMap도 추천수 테이블의 association을 추가한다.

 

 

 

조인을 했으니까 dto 역시 postLikeVO를 추가

 

 

 

log.info로 해당 게시판 정보를 조회한 결과, postLikeVO 부분에 맨 끝에 보면 postLikeCount 값이 제대로 불려저오는 걸 확인할 수 있다.

 

 

 

마지막으로 뷰에 가서 0으로 되어 있는 추천 수를 이런식으로 수정하면 끝

 

 

 

 

이제 실험해볼 차례, 추천 수 부분이 정상적으로 조회되는 걸 확인할 수 있다.

보통 게시물 추천을 누를 시, db의 테이블에 해당 게시물의 고유 넘버와 추천을 누른 사람의 아이디나 익명일 경우 아이피를 저장한다. 그리고 보통 해당 유저는 해당 게시물에 추천을 한번씩만 할 수 있게 한다.

 

그럴 경우 게시물의 고유 넘버인 post_no && 해당 게시물을 누른 유저 user_id 이렇게 두개의 컬럼값이 중복된 row가 있을 경우, 더이상 db에 저장을 할 수 없도록 한다. 그럴 경우 어떻게 해야 할까?

 

Insert IGNORE 문은 이를 해결하지 못했다. IGNORE문은 PK 값이 Unique 일 경우에만 적용이 된다. 다른 컬럼이 중복일 경우에는 적용이 되지 않는다.

 

그래서 나는

Insert + NOT EXIST

이걸 이용하기로 하였다.

 

이 SQL문은 넣고자 하는 Data를 이미 포함하지 않는, 즉 중복되지 않도록 하는 DUAL 이라는 임의의 Table을 통해 중복을 제거하여 Insert문을 실행하도록 한다.

 

DUAL Table 이란?

DUAL Table이란  실제 Table에 존재하지 않는 Data 혹은 임의의 계산 결과를 출력할 때 사용하는 임의의 Table

 

 

 

프로젝트에 적용해 보았다.

 

 

추천 버튼을 누를시 해당 유저는 해당 게시물에 한번만 추천을 할 수 있다.

 

 

db를 확인해보면 중복된 값 없이 저장되어 있는 걸 확인할 수 있다.

+ Recent posts