Spring에서 Ajax를 사용해 보자
0️⃣ Project 생성 및 기본 설정
1) 새로운 Spring Legacy Project 생성
2) Project name: Ajax_Project 설정 후 Template 중 Spring MVC Project 클릭 후 Next
3) top-level 설정
👉🏻 두 번째 level까지는 도메인 역순
👉🏻 세 번째 level은 contextPath
4) HomeConroller, Home.jsp 삭제
👉🏻 top-level로 지정한 경로 기준으로 스프링이 자동 생성해 주는 Controller와 메인 페이지
👉🏻 우리가 직접 페이지나 Controller를 만들었을 때 충돌이 날 위험이 있으므로 삭제함
💡 여기서 잠깐 참고!
Spring_Project에서는 자바 버전 1.8을 썼지만 기본 설정은 1.6임
자바 버전에 따라 사용법도 약간 다르기 때문에 여러 버전을 체험하기 위해 이번에는 1.6을 사용해 보자
즉, pom.xml는 건드리지 않음!
5) index.jsp 생성
6) 서버에 프로젝트 올리기
7) 메인 페이지 접속해 보기
🙋🏻♀️ 엥... 저 코드 건드린 것도 없는데 왜 500 오류가 나나요?
🙆🏻♀️ taglib를 쓸 수 없는 상태라서 그렇습니다 lib 폴더를 잘 가지고 왔나요?
개똥아
똥쌌니
아니요
👉🏻 Spring_Project에서 lib 폴더 통째로 복사 후
👉🏻 Ajax_Project의 WEB-INF 폴더 내에 붙여넣기
👉🏻 저장 후 서버 Restart 해 보면 잘 뜸!
8) index.jsp에 jQuery 라이브러리 추가해 주기
<!-- jQuery 라이브러리 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
📍 여기서 주의할 점!
👉🏻 제이쿼리 라이브러리는 3가지가 있는데 가장 압축된 버전인 slim 버전은 ajax가 적용되지 않음을 주의할 것
💻 index.jsp 폼 만들어 주기
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- jQuery 라이브러리 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<h1>Spring에서의 AJAX 사용법</h1>
<!-- 응답 페이지가 아닌 응답 데이터만 넘어오도록 하는 비동기 방식인 Ajax -->
<h3>1. 요청 시 값 전달, 응답 결과 받아보기</h3>
이름: <input type="text" id="name"> <br>
나이: <input type="number" id="age"> <br>
<button onclick="test1();">전송</button>
<script>
function test1() {
$.ajax({
url : "ajax1.do",
type : "get",
data : {
name : $("#name").val(),
age : $("#age").val()
},
success : function() {
},
error : function() {
console.log("ajax 통신 실패!");
}
});
}
</script>
</body>
</html>
넘길 이름과 나이를 입력 후 전송 버튼을 눌러 보면 콘솔에 오류 창이 뜸
⌨️ 콘솔 내용 해석 👉🏻 너 지금 요청을 받아 주는 Controller가 없어
WARN : org.springframework.web.servlet.PageNotFoun
- No mapping found for HTTP request with URI [/ajax/ajax1.do] in DispatcherServlet with name 'appServlet'
👉🏻 즉, 요청 자체는 잘 들어갔어!
💻 AjaxController 생성 후 도착 확인
👉🏻 패키지를 한 번 더 세분화해서 controller 패키지 안에 넣어 줄 것!
package com.kh.ajax.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class AjaxController {
@RequestMapping("ajax1.do")
public void ajaxMethod1() {
System.out.println("잘 호출되나");
}
}
스프링의 법을 따라 어노테이션과 Mapping값을 맞춰 춤
다시 한 번 서버 리스타트 후 콘솔을 확인해 보면
아직 코드를 받아서 처리하지는 않았지만 jsp에서 Controller로 잘 도착했음을 확인 가능
💻 AjaxController 응답 데이터가 잘 출력되는지 확인
@Controller
public class AjaxController {
@RequestMapping("ajax1.do")
public void ajaxMethod1(String name, int age, HttpServletResponse response) throws IOException {
System.out.println(name);
System.out.println(age);
}
}
JSP에서 보낸 이름과 나이에 대한 데이터가 Controller에서 띄운 콘솔창에 잘 출력됨
1️⃣ HttpServletResponse 객체로 응답데이터 응답하기
👉🏻 기존의 jsp / Servlet 때 썼던 Stream을 이용한 방식
⌨️ index.jsp
👉🏻 Controller에서 보낸 값을 function의 매개변수 result로 받아 주기
<h3>1. 요청 시 값 전달, 응답 결과 받아보기</h3>
이름: <input type="text" id="name"> <br>
나이: <input type="number" id="age"> <br>
<button onclick="test1();">전송</button>
<script>
function test1() {
$.ajax({
url : "ajax1.do",
type : "get",
data : {
name : $("#name").val(),
age : $("#age").val()
},
success : function(result) {
console.log(result);
},
error : function() {
console.log("ajax 통신 실패!");
}
});
}
</script>
💻 AjaxController
👉🏻 Servlet 때는 doGet() 메소드 정의 부분에 throws 구문이 추가되어 있었음
👉🏻 스프링에서는 이 메소드를 호출했던 DispatcherServlet이 처리하게끔 떠넘기기
@RequestMapping("ajax1.do")
public void ajaxMethod1(String name, int age, HttpServletResponse response) throws IOException {
// System.out.println(name);
// System.out.println(age);
// 요청 처리를 위해 서비스 - DAO 호출
// 요청 처리가 다 되었다는 가정 하에
// 요청한 그 페이지에 응답할 데이터가 있을 경우
String responseData = "응답 문자열: " + name + "님은 " + age + "살입니다.";
// response로 응답 데이터 넘기기
response.setContentType("text/html; charset=UTF-8");
response.getWriter().print(responseData);
}
💻 결과값을 입력창 밑에 뜨도록 위치를 선정해 준 공통 index.jsp
👉🏻 결과값을 뜨게 하고 싶은 곳에 div 태그를 만들고 id값을 준 뒤 ajax 통신이 성공했을 때 그곳으로 응답하기!
<h3>1. 요청 시 값 전달, 응답 결과 받아보기</h3>
이름: <input type="text" id="name"> <br>
나이: <input type="number" id="age"> <br>
<button onclick="test1();">전송</button>
<div id="result1"></div>
<script>
function test1() {
$.ajax({
url : "ajax1.do",
type : "get",
data : {
name : $("#name").val(),
age : $("#age").val()
},
success : function(result) {
// console.log(result);
$("#result1").text(result);
},
error : function() {
console.log("ajax 통신 실패!");
}
});
}
</script>
2️⃣ 응답할 데이터를 문자열 타입으로 반환 (HttpServletResponse를 안 써도 됨)
👉🏻 단, 문자열을 리턴하면 원래는 포워딩 방식을 의미했었음
그냥 문자열을 리턴하면 DispatcherServlet에 의해 해당 화면이 포워딩됨
👉🏻 prefix + responseData + suffix 해당 파일을 찾아 포워딩 시도가 일어남
👉🏻 "/WEB-INF/views/" + "응답 문자열: ~~~" + ".jsp"를 못 찾기 때문에 404 에러 발생
📍 즉, 문자열 리턴 시 응답페이지로 인식해서 해당 뷰 페이지를 찾을 것: 404 에러 발생
👉🏻 따라서 내가 리턴하는 문자열이 응답 페이지가 아닌 응답 데이터임을 선언하는 어노테이션 @ResponseBody를 써 줘야 함
👉🏻 추가적으로 응답 데이터에 한글이 포함될 경우에는 아래와 같이 @RequsetMapping 어노테이션에 produces 속성을 설정해 줘야 함
📍 @RequestMapping에 생략했던 value= 기재하고, produces 속성 추가
📍 @ResponseBody로 페이지가 아닌 응답 데이터를 넘길 것임을 알려 주기
⌨️ 인코딩 설정 전 AjaxController
👉🏻 반환형을 String으로 바꾸고 String 타입의 변수를 반환
👉🏻 이것이 응답페이지가 아닌 응답 데이터라는 것을 명시해 주는 @ResponseBody 어노테이션을 써 준 상태
@ResponseBody
@RequestMapping("ajax1.do")
public String ajaxMethod1(String name, int age) {
String responseData = "응답 문자열: " + name + "님은 " + age + "살입니다.";
return responseData;
}
인코딩 머꼬...?
📍 주의할 점
👉🏻 이 과정까지 해 줬을 때, 응답 데이터가 잘 넘어오나 인코딩이 깨짐
응답 데이터에 한글이 있다면 response.setContentType() 메소드에서 지정한 설정 (@RequestMapping의 produces 속성 지정)
💻 인코딩 설정을 해 준 AjaxController
👉🏻 @RequestMapping에 produces 속성 추가!
👉🏻 내가 return하는 값에 대한 데이터 형식을 지정해 주는 꼴임
👉🏻 produces 속성이 추가되었기 때문에 생략하였던 value=도 추가해 줘야 함
@ResponseBody
@RequestMapping(value="ajax1.do", produces="text/html; charset=UTF-8")
public String ajaxMethod1(String name, int age) {
String responseData = "응답 문자열: " + name + "님은 " + age + "살입니다.";
return responseData;
}