🔔 DAO는 따로 구현하지 않았고 Ajax 사용법만 다루었습니다.
Ajax를 사용해 회원가입할 때 주로 사용하는 아이디 중복확인 기능을 구현해보자!
개발환경
STS 4
jdk 14.0.2
Java Compile version 1.6
Ajax 기본 형식
<script>
function request(){
var fruit = {
name: "사과",
price: 2000,
introduce: "안녕"
}
$.ajax({
url: "./register.do", /* 서버에 요청할 경로를 지정합니다 */
type: "POST", /* 어떤 방식으로 요청할 것인지 > 주로 GET or POST */
data : JSON.stringify(fruit), /* 전송할 데이터 */
contentType: "application/json; charset=utf-8", /* Controller로 어떤 형식의 데이터를 보낼지 정합니다 */
dataType:'text', /* Controller로부터 리턴받을 타입을 지정합니다.*/
async: true , /* Ajax를 동기로 사용할지 비동기로 사용할지 > Ajax는 비동기 처리를 위해 사용하지만 가끔은 동기로 사용해야할 경우가 있습니다
Ajax를 통해 서버측에 데이터를 요청하고, 이 데이터의 결과를 모두 수신 받은 다음 단계로 진행하도록 하는 경우가 있을 수 있다는 이야기입니다. */
/* Controller에서 데이터를 잘 넘겨받았을 경우 호출*/
success : function(data){
},
/* 400, 404, 415에러 발생, Controller에서 데이터를 넘겨받지 못했을 경우 호출*/
error :function(){
}
});
}
</script>
필수로 지정해야할 요소는 url, type, data, success 함수 입니다
contentType과 dataType, async는 필수는 아니지만 json 형식의 데이터를 서버에 전송할때는
반드시 contentType을 "application/json; charset=utf-8" 로 지정해야 415 에러가 발생하지 않습니다.
네트워크 탭 에서 요청한 url인 register.do 를 클릭하면
요청한 url 주소와 상태코드, 어떤 형태의 데이터를 전송했는지, 데이터의 내용들을 볼 수 있습니다.
1. pom.xml 수정
pom.xml <dependencies> 내부에 Dependency 추가
<dependencies>
<!-- jackson은 버전들이 스프링과 맞아야 한다 -->
<!-- Java용 json 라이브러리(XML/YAML/CSV) data processing 툴 -->
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.json/json -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20200518</version>
</dependency>
</dependencies>
jackson 라이브러리 추가할 때는 꼭!!!!!!!!!! 스프링 버전과 맞는 버전이어야합니다
안그러면 '415 Unsupported Media Type' 에러뜨면서 ajax의 늪에서 헤어나올수 없어요.. 진짜 이거 너무 중요
제 pom.xml <properties> 내부의 프로젝트 버전 정보는 다음과 같습니다 참고하세용 (◍´▽`◍)
<properties>
<java-version>1.6</java-version>
<org.springframework-version>5.2.3.RELEASE</org.springframework-version>
<org.spring-security-version>4.2.16.RELEASE</org.spring-security-version>
<org.aspectj-version>1.9.5</org.aspectj-version>
<org.slf4j-version>1.7.30</org.slf4j-version>
</properties>
2. Controller
package com.mindi.ajax;
import java.text.DateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* Handles requests for the application home page.
*/
@Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
/**
* Simply selects the home view to render by returning its name.
*/
@RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
return "idcheck";
}
@RequestMapping(value="/idcheck.do", method = RequestMethod.POST)
@ResponseBody
public Map<String, Object> idCheck(int problem_id) throws Exception {
logger.info("idCheck: " + problem_id);
Map<String, Object> map = new HashMap<String, Object>();
/* 테스트를 위해 임의로 false를 대입했습니다. */
boolean flag = false;
/* 중복인지 아닌지 검사해 반환하는 함수를 만들어주세요.
* 중복확인 로직은 DAO에서 selectOne()으로 구현합니다.
* 이 함수는 하나라도 있으면 1, 없으면 0을 반환합니다 */
map.put("flag", flag);
return map;
}
}
3. idcheck.jsp
jquery를 사용했습니다.
<!-- idcheck.jsp -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>""</title>
<meta charset="utf-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1, user-scalable=no" />
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script> <!-- jquery 사용 -->
</head>
<body>
번호 <input type="text" id="problem_id" style="width: 70px;"/>
<input type="button" onclick="id_check(event)" value="중복확인">
<span id="id_check_alert" style="color:red;">
중복확인 안됨</span>
<script>
let check = false;
async function id_check(e) {
e.preventDefault();
var problem_id = $('#problem_id').val();
/* alert(problem_id); */
if(problem_id == ""){
return false;
}
await $.ajax({
url: "idcheck.do",
type: "POST",
data: {
"problem_id": problem_id
},
success: function(data){
// 있는 문제
if(data.flag){
alert("이미 등록된 문제입니다.");
$("#id_check_alert").html("이미 등록된 문제입니다.");
$("#id_check_alert").css("color","red");
problem_id.value = "";
check = false;
}
// 없는 문제
else {
alert("등록 가능한 문제입니다.");
$("#id_check_alert").html("중복확인 완료");
$("#id_check_alert").css("color","#7BC379");
check = true;
}
console.log("checkDuplicating success!");
},
error: function(){ /* 404, 415, 400등 이런 에러 발생 시 실행 */
console.log("checkDuplicating error!");
}
});
}
</script>
</body>
</html>
await와 async를 쓰는 이유는
joshua1988.github.io/web-development/javascript/js-async-await/
joshua1988.github.io/web-development/javascript/javascript-asynchronous-operation/
이 분이 이부분에 대해 설명을 잘해주셔서 올린다. 꼭 한번 읽어보시길!