카테고리 없음

#84. Spring AJAX사용(JSON, GSON)

열하나요 2023. 11. 6. 09:48

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].필드명)으로 뽑을 수 있음