Spring에서 ajax사용

유요한·2022년 7월 18일
0
post-custom-banner

ajax기본 사용법

Spring Ajax

	<dependency>
		    <groupId>com.fasterxml.jackson.core</groupId>
		    <artifactId>jackson-databind</artifactId>
		    <version>2.9.4</version>
		</dependency>
		
		
		<dependency>
		    <groupId>com.fasterxml.jackson.dataformat</groupId>
		    <artifactId>jackson-dataformat-xml</artifactId>
		    <version>2.9.4</version>
		</dependency>
		
		<!-- gson  java인스턴스를 JSN타입의 문자열로 변환해야하는 일 -->
		<dependency>
		    <groupId>com.google.code.gson</groupId>
		    <artifactId>gson</artifactId>
		    <version>2.8.2</version>
		</dependency>
	// 화장품, 상세정보 등록 아작스
var formdata = {'type':type,'brand':brand,'skinType':skinType,'price':price,'title':title
				,'content':content,'capacity':capacity,'period':period,'nation':nation,'useMethod':useMethod};
		
$.ajax({
	url: '${pageContext.request.contextPath}/cosmetic/cosmeticRegister', // 클라이언트가 요청을 보낼 서버의 URL 주소
	data: formdata,        // HTTP 요청과 함께 서버로 보낼 데이터
	type: 'POST',          // HTTP 요청 방식(GET, POST)
	dataType: 'html',      // 호출 했을 때 결과타입
	success : function(data) {
	}
});
		

// 첨부파일 등록 ajax
$.ajax({
	url: '${pageContext.request.contextPath}/cosmetic/AttachRegister', // 클라이언트가 요청을 보낼 서버의 URL 주소
	data: JSON.stringify(attachList),        // HTTP 요청과 함께 서버로 보낼 데이터
	type: 'POST',          // HTTP 요청 방식(GET, POST)
	dataType: 'json',      // 호출 했을 때 결과타입
	contentType: "application/json",
	success : function(data) {
	}
});
		@RequestMapping(value = "cosmeticRegister", method = RequestMethod.POST)
	@ResponseBody
	public ResponseEntity<String> cosmeticRegister(CosmeticVo cosmetic,  DescriptionVo description){
		ResponseEntity<String> r = null;
		
		log.info("cosmetic : "+cosmetic.toString());
		log.info("description : "+description.toString());
		
		// cno 값을 리턴해야함
		r= new ResponseEntity<>(HttpStatus.OK);
		return r;
	}
	
	@RequestMapping(value = "AttachRegister", method = RequestMethod.POST)
	@ResponseBody
	public ResponseEntity<String> AttachRegister(@RequestBody List<AttachFileVo> attachList ){ //Map<String, Object> params
		ResponseEntity<String> r = null;
		log.info("attach : "+attachList.toString());
		
		r= new ResponseEntity<>(HttpStatus.OK);
		return r;
	}

※ 주의점

컨트롤러의 파라미터앞에 @RequestBody 어노테이션을 넣어야 한다. 프론트에서 전달 한 json 데이터를 해당 파라미터에 매핑시킨다는 뜻. 

1번째 아작스와 2번째 아작스의 차이는 contentType  이다.  contentType 이 application/json 인 경우 json형식으로 데이터를 보낸다는 말이다. 따라서 아작스에서 데이터를 보낼때도 json형식으로 보내줘야한다. 그래서 JSON.stringify(attachList) 함수를 통해서 json형식으로 바꾸어주었다.


Ajax을 담을 DTO클래스

	public class Jamong {
    String name;
    int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    
}
  1. 기본

Ajax의 최소화 형태다.
data를 전송해서 필요한 로직들을 처리하고 값을 return한다.
여기서 @ReponseBody의 역할을 알아야 하는데, @RequestMapping으로 String type을 반환해주면, ViewResolver에서 정의한 prefix와 suffix가 return값에 추가되어 view로 이동이 된다. @ResponseBody를 사용해주면 view를 생성해주는 것이 아니라, JSON 혹은 Object 형태로 데이터를 넘겨준다.

● Client
	  $('#btn1').on('click', function(){
        var form = {
                name: "jamong",
                age: 23
        }
        $.ajax({
            url: "requestObject",
            type: "POST",
            data: form,
            success: function(data){
                $('#result').text(data);
            },
            error: function(){
                alert("simpleWithObject err");
            }
        });
    });
● Server
	 @RequestMapping(value="/requestObject", method=RequestMethod.POST)
    @ResponseBody
    public String simpleWithObject(Jamong jamong) {
        //필요한 로직 처리
        return jamong.getName() + jamong.getAge();
    }
● View
	<body>
    <button id="btn1">simpleAJAX</button>
    <div id="result"></div>
</body>
  1. 폼 파라미터 넘기기

폼의 파라미터를 넘기기 위해 serialize() 함수를 사용한다.
필요한 로직 처리를 하고 마찬가지로 @ResponseBody Annotation을 사용하여 Object형태로 넘긴다.

● Client
	
    $('#btn2').on('click', function(){
        $.ajax({
            url: "serialize",
            type: "POST",
            data: $("#frm").serialize(),
            success: function(data){
                $('#result').text(data);
            },
            error: function(){
                alert("serialize err");
            }
        });
    });
● Server
	  @RequestMapping(value="/serialize", method=RequestMethod.POST)
    @ResponseBody
    public String serialize(Jamong jamong) {
        //필요한 로직 처리   
        return jamong.getName() + jamong.getAge();
    }
● View
	<body>
<form id="frm">
    name : <input type="text" name="name" id="name"><br>
    age : <input type="text" name="age" id="age">
</form>
    <button id="btn2">serialize</button>
    <div id="result"></div>
</body>
  1. JSON.stringify()

Ajax에는 dataType이라는 옵션이 있다. 설정을 안해주면 MIME타입에 의해 자동으로 설정이 된다. JSON 형태로 보내고 싶으면 JSON.stringify() 함수를 많이 사용한다. 이 함수는 JSON 타입을 String 객체로 변환시켜주는 역할을 한다. 서버쪽으로 데이터를 넘길때, String객체로 변환시켜주지 않으면 url의 get파리미터 형싱(?a=1&b=2)처럼 넘겨버린다.

여기서 jackson 라이브러리를 추가안해주면 오류가 뜬다.
그렇기 때문에 pom.xml에 추가해줘야 한다.

● pom.xml
	     <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.5</version>
        </dependency>

코드를 보기 이전에 이번에는 @RequestBody에 대해서 알아야한다.

클라이언트쪽에서 데이터 형태를 JSON으로 보내주면, 서버쪽에서도 JSON으로 받아줘야한다.

JSON형태로 받게해주는 Annotation이 @RequestBody이다.

● Client
	    $('#btn3').on('click', function(){
        var form = {
                name: "jamong",
                age: 23
        }
        $.ajax({
            url: " stringify",
            type: "POST",
            data: JSON.stringify(form),
            contentType: "application/json; charset=utf-8;",
            dataType: "json",
            success: function(data){
                var txt = data.name + data.age;
                $('#result').text(txt);
            },
            error: function(){
                alert("stringify err");
            }
        });
    });
● Server
	  @RequestMapping(value="/stringify", method=RequestMethod.POST)
    @ResponseBody
    public Object stringify(@RequestBody Jamong jamong) {
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("name", jamong.getName());
        map.put("age", jamong.getAge());
        return map;
    }
● View
	<body>
    <button id="btn3">stringify</button>
    <div id="result"></div>
</body>
  1. @RestController

다음은 @Controller가 아닌 @RestController에서 JSON타입으로 데이터를 주고받을거다.

@RestController Annotation을 사용하면, @ResponseBody Annotation을 빼고 사용하면된다.

@RestController가 알아서 JSON형태로 return해준다.

@Controller 와 @RestController차이
Spring에서 컨트롤러를 지정해주기 위한 어노테이션은 @Controller와 @RestController가 있습니다.
전통적인 Spring MVC 컨트롤러인 @Controller와 RESTful 웹 서비스의 컨트롤러인 @RestController의 주요한 차이점은 HTTP Response Body가 생성되는 방식입니다.
@Controller의 역할은 Model 객체를 만들어 데이터를 담고 View를 반환하는 것이고,
@RestController는 단순히 객체만을 반환하고 객체 데이터는 JSON 또는 XML 형식으로 HTTP 응답에 담아 전송합니다.
물론 @Controller도 @ResponseBody를 사용해서 만들 수 있지만 이런 방식은 RESTful 웹 서비스의 기본 동작이기 때문에 Spring은 @Controller와 @ResponseBody의 동작을 조합한 @RestController를 도입했습니다.
@RestController는 @Controller와 @ResponseBody의 동작을 하나로 결합한 컨트롤러라 보시면 됩니다.




여기서 추가시

	<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

	<!-- Spring MVC annotation(주석문)을 사용하기 위한 설정 -->
	<context:annotation-config/>
	
	<!-- xml 객체 생성 -->
	<!-- ViewResolver 설정(사용자의 view의 위치, 확장자명)-->
	<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/"></property> <!-- 경로 -->
		<property name="suffix" value=".jsp"></property>
	</bean>
	
	<!-- 사용자지정 -->
	<!-- java의 공통 패키지 -->
	<context:component-scan base-package="bit.com.a"/>
	
	<!-- Ajax 주석문 허가 -->
	<mvc:annotation-driven/>
	<!-- 스프링에서 처리할 수 없는 요청은 tomcat에 위임 -->
	<mvc:default-servlet-handler/>

</beans>

또한 Ajax 통신시 컨트롤러 부분에서 무조건 @ResponseBody를 사용해야 한다.

● hello.jsp
	<%@page import="bit.com.a.model.MyClass"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
</head>
<body>

	<!-- 1 -->
	<%
		MyClass cls = (MyClass) request.getAttribute("myCls");
	%>
	number:<%=cls.getNumber()%><br> name:<%=cls.getName()%><br>

	<!--2 -->
	<br>
	<br> number:${myCls.number}
	<br> name: ${myCls.name }

	<!-- 3 -->
	<form>
		아이디:<input type="text" id="checkid"><br> <br>
		<button type="button" id="_check" onclick="idcheck()">id 체크</button>
	</form>

	<script>
		function idcheck() {
			alert("idCheck");

			$.ajax({
				url : "./idCheck.do",
				type : "get",
				data : "id=" + $("#checkid").val(),
				success : function(data) {
					alert("되요ㅋ");
					alert(data);
				},
				error : function() {
					alert("에러나요");
				}
			})
		}
	</script>

	<!-- 4 -->
	<form method="post">
		이름: <input type="text" id="_name" value="홍길동"><br> 전화: <input
			type="text" id="_phone" value="123-4567-789"><br> 이메일: <input
			type="text" id="_email" value="http200@kakao.com"><br>
		생년월일: <input type="text" id="_birth" value="2001/11/23"><br>
		<button type="button" id="account">account</button>
	</form>

	<script type="text/javascript">
		$("#account").click(function() {
			//alert("click");

			var human = {
				name : $("#_name").val(),
				tel : $("#_phone").val(),
				email : $("#_email").val(),
				birth : $("#_birth").val()
			};
			console.log(human);
			$.ajax({
				url : "./account.do",
				data : human,
				type : "post",
				dataType : "json",
				async : true,
				success : function(resp) {
					alert("success");
					alert(resp.msg);
					alert(resp.name);

				},
				error : function() {
					alert("error")
				}
			});
		});
	</script>

	<br>
	<br>
	<br>
	<!-- 5 -->

	이름:
	<input type="text" id="_name1" value="정수동">
	<br> 전화:
	<input type="text" id="_phone1" value="123-4567-589">
	<br> 이메일:
	<input type="text" id="_email1" value="http200@kakao.com">
	<br> 생년월일:
	<input type="text" id="_birth1" value="2001-11-21">
	<button type="button" id="account1">account</button>
	<br>

	<script>
		/* Json -> Map */

		$("#account1").on("click", function() {
			//alert("account1")
			var data = {};

			data["name"] = $("#_name1").val();
			data["tel"] = $("#_phone1").val();
			data["email"] = $("#_email1").val();

			var birth = $("#_birth1").val();
			data["birth"] = birth.replace(/-/g, "");
			//alert(data["birth"]);

			$.ajax({
				contentType : 'application/json',
				dataType : 'json',
				url : "updateUser.do",
				type : 'post',
				data : JSON.stringify(data), // json -> string <-> parse
				success : function(resp) {
					alert("success")
				},
				error : function() {
					alert("error");
				}
			});
		});
	</script>

</body>
</html>
● HelloController.java
	package bit.com.a;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;

import bit.com.a.model.Human;
import bit.com.a.model.MyClass;


@Controller
public class HelloController {
	
	private static Logger logger = LoggerFactory.getLogger(HelloController.class);
	
//	1
	@RequestMapping("hello.do")
	public String hello(Model model) {
		logger.info("HelloController hello" + new Date());
		
		MyClass cls = new MyClass(101, "일지매");
		model.addAttribute("myCls", cls);
		
		return "hello";
	}
	/* 2 controller -> controller */
	@RequestMapping(value="move.do", method = RequestMethod.GET)
	public String move() {
		logger.info("HelloController move " + new Date());
		
		//sendRedirect(컨트롤러에서 컨트롤러로 보낸다)
		return "redirect:/hello.do"; 
//		return "forward:/hello.do"; 데이터를 가져갈때는 forward
	}
	
//	3번
//	Ajax 용 return값은 ajax에서 가져오는 데이터 (넘겨줘야할 데이터)
	//Ajax사용시 @ResponseBody를 사용해야한다
	@ResponseBody
	@RequestMapping(value="idCheck.do", produces = "application/String; charset=utf-8")
	//적어주기만 하면 무조건 session에 넘어간다 (의존성)
	public String idCheck(String id, HttpSession session) {
		logger.info("HelloController idCheck " + new Date());
		logger.info("id:" + id);
		
		String str = "오케이";
		return str;	
	}
	
	
	//4
	@ResponseBody
	@RequestMapping(value="account.do" ,method = RequestMethod.POST)
	public  Map<String, Object> account(Human my){
		logger.info("HelloController account " + new Date());
		logger.info(my.toString());
		
		//DB 접근
		Map<String, Object> rmap = new HashMap<String, Object>();
		rmap.put("msg", "메시지입니다");
		rmap.put("name", "정수동");
		
		return rmap;
		
	}
	
    //5
	@ResponseBody
	@RequestMapping(value="updateUser.do", method = {RequestMethod.GET, RequestMethod.POST})
	//@RequestBody를 적어야 Map으로 값을 받아올 수 있다.
	public Map<String, Object> updateUser(@RequestBody Map<String, Object> map){
		logger.info("HelloController updateUser " + new Date());
		logger.info( map.get("name") + "");
		logger.info( map.get("tel") + "");
		logger.info( map.get("email") + "");
		logger.info( map.get("birth") + "");
		
		Map<String, Object> rmap = new HashMap<String, Object>();
		rmap.put("name", "일지매");
		rmap.put("age", "24");
		
		return rmap;
	}
	
	
	
}
profile
최선을 다하자!!
post-custom-banner

0개의 댓글