<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;
}
}
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>
폼의 파라미터를 넘기기 위해 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>
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>
다음은 @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;
}
}