AJAX의
url에 매핑값을 적어주고
AJAX data의 key값으로 가져올 수 있음
data에 input요소의 value값을 적어주면 무조건 String으로 넘어감
=> Controller에서 int형으로 받게 된다면 NumberFormatException발생!
=> 그래도 자동파싱돼서 값은 잘 나오나, 빈문자열을 보낼 경우 파싱할 수 없음! => 400에러
하나의 데이터를 받을 경우
1. 기존방식(HttpSetvletResponse 객체 사용)
* 1. HttpServletResonse 객체로 응답데이터 응답하기(Stream을 이용한 방식)
*/
@RequestMapping("ajax1.do")
public void ajaxMethod1(String name, int age, HttpServletResponse response) throws IOException { // AJAX data의 key값으로 가져올 수 있음
System.out.println(name);
System.out.println(age);
// 요청 처리를 잘했다는 가정하에! 요청할 응답페이지에 반환할 데이터가 있다!!!
String responseData = "응답 데이터 : " + name + "은(는) " + age + "살 입니다.";
response.setContentType("text/html; charset=UTF-8");
response.getWriter().print(responseData); // IOException발생 => 원래는 Servlet만들면 throws가 자동으로 써있었는데 class파일이므로 직접 예외처리
}
2. @ResponseBody : return시 포워딩방식이 아닌 응답데이터에 포함시켜줄거다 알려줌
=> 인코딩이 안됨 (결국 response로 인코딩을 해줘야함)
=> RequestMapping의 produces의 속성값으로 타입형식을 적어줌
=> 그 때, 기존에 적었던 매핑값도 속성명(value=)을 적어줘야 함
=> @RequestMapping(value="ajax1.do", produces="text/html; charset=UTF-8")
/*
* 2. 응답할 데이터를 문자열로 반환
* => HttpServletResponse를 사용하지 않는 방법
* 단, 문자열을 반환하면 원하던 포워딩 방식 => 응답뷰의 논리적인 경로로 인식을 해서 뷰 리졸버로 전달~
*
* 따라서 내가 반환하는 String타입의 값이 뷰의 정보가 아니라 응답데이터다!!! 라는 것을 선언하는 애노테이션
* @ResponseBody
*/
@ResponseBody
@RequestMapping(value="ajax1.do", produces="text/html; charset=UTF-8")
public String ajaxMethod1(String name, int age) {
return "응답문자열 : " + name + "은(는) " + age + "살 입니다.";
// 포워딩 되어 /WEB-INF/views/응답문자열 : 홍길동은(는) 15살 입니다..jsp로 돌아감
}
다수의 응답데이터가 있는 경우
JSON(1.1.1버전 dependency에 추가)
// 다수의 응답데이터가 있을 경우
@RequestMapping("ajax1.do")
public void ajaxMethod1(String name, int age, HttpServletResponse response) throws IOException {
// 요청처리를 잘했다는 가정하에 데이터 응답
// response.setContentType("text/html; charset=UTF-8");
// response.getWriter().print(name);
// response.getWriter().print(age);
// 출력하는 데이터가 하나의 문자열로 쭉 이어져있음
// 홍길동15
// JSON(JavaScript Object Notation)형태로 담아서 응답~
// 똑같은 문자열인데 자바스크립트에서 활용이 가능하도록 배열로 파싱이 가능함
// { "속성명" : [{"속성명" : "속성값", "속성명" : "속성값"}] }
// JSONObject => {"속성":"값", "속성":"값", ...}
// JSONArray => ["값", "값", "값", ...]
// JSONArray
JSONArray jArr = new JSONArray();
jArr.add(name); // ["홍길동"]
jArr.add(age); // ["홍길동", 15]
response.setContentType("application/json; charset=UTF-8");
response.getWriter().print(jArr);
// JSONObject
// 대부분의 경우 인덱스를 사용하는 JSONArray보다 JSONObject를 사용한다.
JSONObject jObj = new JSONObject();
jObj.put("name", name); // {"name" : "홍길동"}
jObj.put("age", age); // {"name" : "홍길동", "age" : "15"};
response.setContentType("application/json; charset=UTF-8");
response.getWriter().print(jObj);
}
=> JSONArray로 보내면 돌아온 AJAX에서 result[i]로 값을 뽑을 수 있음
AJAX의 속성 중
async : false 는 ajax가 다 수행되고나서 아래있는 코드도 수행하겠다...???
JSON의 객체를 넘길 때,
1. String형으로 넘길거야 => JSONObject 객체의 toJSONString()함수를 이용하여 String으로 넘어가도 JSON형태로 받을 수 있게 넘겨준다.
2. return시 forwarding이 아닌 response 바디영역에 데이터로 포함시켜줄거다 => @ResponseBody
3. 인코딩 및 타입 설정 => @RequestMapping(value="ajax2.do", produces="application/json; charset=UTF-8")
@ResponseBody
@RequestMapping(value="ajax1.do", produces="application/json; charset=UTF-8")
public String ajaxMethod1(String name, int age) {
JSONObject jObj = new JSONObject();
jObj.put("name", name);
jObj.put("age", age);
return jObj.toJSONString(); // StringBuilder를 사용해서 요소들을 문자열로 만든 뒤 toString한 메소드를 반환 / JSONArray에서도 사용가능
}
@ResponseBody
@RequestMapping(value="ajax2.do", produces="application/json; charset=UTF-8")
public String ajaxMethod2(int num) {
// Member m = memberService.selectMember(userNo);
// 잘갔다왔다고 치고
Member m = new Member("user01", "pass01", "홍길동", 15, "010-1234-5678"); // DB에서 조회해온 내용
// JSON형태로 만들어서 응답
JSONObject jObj = new JSONObject();
// 배열로 가면 인덱스도 신경써야되고 번거로우니까 키-밸류 형태로 넘겨주자 => Map밖에 없음
/*
{
"userId" : "user01",
"userPwd" : "pass01",
"userName" : "홍길동",
"age" : 15,
"phoneNumber" : "010-1234-5678"
}
*/
jObj.put("userId", m.getUserId());
jObj.put("userPwd", m.getUserPwd());
jObj.put("userName", m.getUserName());
jObj.put("age", m.getAge());
jObj.put("phoneNumber", m.getPhoneNumber());
return jObj.toJSONString();
// return jObj.toString(); // 먼차이람
}
JavaScript에서 사용할 수 있는 형태로 넘겨주기 위해서
배열이나 객체 형태 등으로 넘겨주는데, 객체 형태로 넘겨줄 때, HashMap을 상속받고 있는 JSON에 put으로 키-밸류 형태로 데이터를 넣어줘야 하는데 그걸 GSON이 대신 해줌
일반 객체 넘기기
GSON( (2.8.5버전 dependency에 추가)
@ResponseBody
@RequestMapping(value="ajax2.do", produces="application/json; charset=UTF-8")
public String ajaxMethod2(int num) {
Member m = new Member("user01", "pass01", "홍길동", 15, "010-1234-5678");
return new Gson().toJson(m);
}
=> 이렇게 하면 JavaScript에서 즉, 돌아온 AJAX에서 result.키값 (==result.필드명)으로 뽑을 수 있음
객체 배열 넘기기
@ResponseBody
@RequestMapping(value="ajax3.do", produces="application/json; charset=UTF-8")
public String ajaxMethod3() {
// ArrayList<Member> list = memberService.selectMemberList();
// DB 잘 갔다왔다고 치고
ArrayList<Member> list = new ArrayList();
list.add(new Member("user01", "pass01", "홍길동", 10, "010-1111-1111"));
list.add(new Member("user02", "pass02", "김개똥", 20, "010-2222-2222"));
list.add(new Member("user03", "pass03", "랄랄랄", 20, "010-3333-3333"));
return new Gson().toJson(list);
}
=> 이렇게 하면 JavaScript에서 즉, 돌아온 AJAX에서 result[인덱스].키값 (==result[i].필드명)으로 뽑을 수 있음