이제 서버 요청 페이지 get페이지가 아닌 사용자가 직접 요청하는 choose 페이지를 만들어보자.
우선. 당연하게도 매핑 자체는 POST로 던져야겠지.

그다음 ajax 또한 요청할 거니 ModelAndView 타입이 아니라 String 타입으로 responseJson.toString()을 쓰기 위해 String 타입으로 postAdd를 만들어주고 매핑되는 곳은 add로 다가 던져주자. 어차피 ModelAndView에다가 값을 넣어주는 게 아니기 때문에 value의 값은 add로 지정해줘도 딱히 상관없을 듯하다. 그다음 ajax 처리를 하기 위해 String 타입으로 지정해주기 전 비동기 처리 시 사용하는 어노테이션 또한 생각해줘야겠지 그것이 바로 ResponseBody어노테이션이다. 즉, 응답하는 본문을 controller에서 처리해줘야 되니 ResponseBody 어노테이션을 사용해주고 이제 프로필을 만들어보자. 프로필을 추가할 시 프로필을 만들어 주는 곳에는 기존의 유저가 로그인하면 프로필을 만들어주는 로직을 거의 비슷하게 가져오면 된다. 매개변수로 일단 로그인한 유저의 값을 알아야 되기 때문에 SessionAttribute를 사용해주고 ProfileEntity타입의 profile을 매개변수로 받아 프로필을 만들어주는 로직을 구현해주고 각각의 값들을 넣어주면 끝. 물론 당연히 result는 다이내믹 이 넘을 사용 해주고 마지막으로 Json을 이용해서 비동기 ajax 또한 작성해줄 것이니 org.json을 pom.xml에다가 넣어주자.
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20220320</version>
</dependency>
이거를 pom.xml에다가 추가해주고 JSON을 객체화 해준 뒤 그 값을 ex) result : success로 찍어 내거나 or result : failure로 찍을 것이니 responseJson에다가 put 해주고 앞에는 키의 값인 result를 우리가 만들어둔 상수 IResult. ATTRIBUTE_NAME을 통해 "result"를 키의 값으로 넣고 그다음 값으로는 각각의 enum의 결과 값을 나오게 해 주면 되니 result.name()을 이용 이렇게 하게 되면 받아오는 값이 SUCCESS이다. 이넘의 값은 대문자로 작성해줘야 되기 때문 이것을 소문자로 바꿔주려면 toLowerCase를 이용해서 소문자로 받아오면 된다. 그러면 이제 ajax 또한 작성하러 가보자.
const profileAddAnchor = window.document.getElementById('profileAddAnchor');
const profileAddDialog = window.document.getElementById('profileDialog');
const profileAddForm = window.document.getElementById('profileAddForm');
profileAddAnchor.addEventListener('click', e => {
e.preventDefault();
profileAddDialog.classList.remove('visible');
profileAddForm.classList.add('visible');
profileAddForm['isKids'].checked = false;
profileAddForm['name'].value = '';
profileAddForm['name'].focus();
});
profileAddForm['cancel'].addEventListener('click', () => {
profileAddDialog.classList.add('visible');
profileAddForm.classList.remove('visible');
});
profileAddForm.onsubmit = e => {
e.preventDefault();
if (profileAddForm['name'].value === '') {
profileAddForm['name'].focus();
return false;
}
const xhr = new XMLHttpRequest();
xhr.open('POST', 'add');
xhr.onreadystatechange = () => {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status >= 200 && xhr.status < 300) {
const responseJson = JSON.parse(xhr.responseText);
const result = responseJson['result'];
switch (result) {
case 'failure_duplicate_name':
alert(`해당 이름(${profileAddForm['name'].value})은 이미 사용 중입니다.`);
break;
case 'success':
window.location.href = 'choose';
break;
default:
alert('알 수 없는 이유로 프로필을 추가하지 못했습니다.\n\n잠시 후 다시 시도해주시거나 고객센터를 통해 문의해주세요.');
}
} else {
alert('서버와 통신하지 못하였습니다.\n\n잠시 후 다시 시도해주시거나 고객센터를 통해 문의해주세요.');
}
}
};
const data = new FormData();
data.append('name', profileAddForm['name'].value);
data.append('kids', profileAddForm['isKids'].checked);
xhr.send(data);
};
원래의 페이지에다가 +모양 누르면 그 페이지의 화면의 opacity가 1이 붙어진 visible을 만들어주는 처리 그리고 보이는 페이지 화면에서 다시 취소 버튼을 누르면 돌아가고 딱히 이거는 그냥 아무렇게 작성해도 상관은 없음. 저게 정답만은 아님. 여기서 핵심은 e.preventDefault와 ajax 처리이다. 우선 e.preventDefault는 우리가 a태그나 sumit의 태그는 고유의 동작으로 페이지를 이동시키거나, form안에 input 등을 전송하는 동작이 있다. 따라서 e.preventDefault는 그 동작을 중지시키는 역할을 한다. 이렇게 안 할 시 그 버튼을 누를 때 페이지가 리로드가 되는데 이렇게 되면 기존의 값들이 날아가서 보이지 않게 됨. 즉, 내가 적은 ajax를 form요청 시 e.preventDefault를 해주지 않으면 화면이 리로드 되면서 기존의 값들이 보이지가 않는 현상이 발생이 될 수 있음. 그래서 a 태그랑 sumit시에는 리로드 되는 것을 막기 위해 우리는 e.preventDefault를 매우 신경 써야 될 필요성이 있다.
그다음 ajax 작성인데 딱히 그렇게 어렵다고는 생각하지는 않지만 적는 방법이 숙달되지 않으면 못 적을 수 있다고 생각한다. 따라서 그냥 위에 적혀 있는 코드를 한번 더 적어보자. 성공이랑 실패 구현부를 다 적으라는 것이 아닌 틀을 만드는 게 ajax에서는 핵심이라고 할 수 있다.
const xhr = new XMLHttpRequest();
const data = new FormData();
xhr.open('POST', 'add');
xhr.onreadystatechange = () => {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status >= 200 && xhr.status < 300) {
const responseJson = JSON.parse(xhr.responseText);
switch (responseJson['result']) {
//성공 ~~
}
} else {
//서버쪽 실패
}
};
//RequestParam으로 받은 값을 Form데이타로 키와 값을 통해 쉽게 보낼 수 있음 여기서는 사용하는게 append 메서드를 이용하면 된다.
data.append('name', profileAddForm['name'].value);
xhr.send(data);
};
이름만 받게 다시 한번 그냥 적어봄. 헷갈릴 때 다시 한번 보는 용으로 괜찮을 듯.
'Spring Boot' 카테고리의 다른 글
미디어 관련 공부#2 (0) | 2022.08.30 |
---|---|
미디어 관련 공부#1(DB) (0) | 2022.08.30 |
프로필 생성관련 공부#1 (0) | 2022.08.21 |
Exception : Invalid bound statement (not found) (0) | 2022.08.18 |
Cookie (0) | 2022.08.18 |