JSP - 8. ajax 데이터 처리 + 캘린더

갓김치·2020년 11월 27일
0

JSP+Spring

목록 보기
9/43

복습

마셜링+언마셜링 / 직렬화+역직렬화

  • 클라이언트→(마 셜 링 ▶ 직 렬 화)→네트워크→(역직렬화 ▶ 언마셜링)→서버
  • 클라이언트←(언마셜링 ◀ 역직렬화)←네트워크←(직 렬 화 ◀ 마 셜 링)←서버

사칙연산기 복습

  • calculateForm.jsp
  • CalculateServlet.java
  • 비동기 요청에서의 데이터 처리 추가됨 (html+json)
  • request header의 accept와 response header의 contenttype고려
$(function() { // 인터프리터방식의 언어에서 코드  실행순서를 바꾸는 역할
  /*
   * resultArea와 now의 전역변수화
   * - 결과값을 넣을 객체에 대한 정보를 success 내 지역변수로 설정할 시,
   *   클라이언트 요청이 성공할 때마다 dom전체를 돌아다니며 해당id값을 가진 객체를 찾아야함
   *   이를 방지하기 위해 전역변수화한 것.
   */
  let resultArea = $("#resultArea");
  let now = $("#now");

  /*
   * ajaxError를 공통적으로 처리하기 위함
   */
  $(document).ajaxError(function(xhr) { // xhr: 응답, 요청에 대한 모든 정보가 들어있음
    console.log(xhr);
  });

  $("form").on("submit", function(event) { // submit 이벤트가 일어나는 객체는 button이 아닌 form
    event.preventDefault(); // return false와 함께 사용하면 더 안전
    console.log(this);
    console.log($(this));
    // 요청을 보내기 위한 설정
    let url = this.action ? this.action : "" ; // whitespace -> ajax가 브라우저 현재 주소를 사용
    let data = $(this).serialize(); // jQuery가 제공하는 직렬화기능
    let method = this.method ? this.method : "get" ; 

    // 응답을 처리하기 위한 설정
    let dataType = "json";
    let success = function(resp) { // js에서는 함수도 변수에 담을 수 있음 => 함수도 하나의 객체이기때문
      resultArea.html(resp.data);
      now.html(resp.now);
    }
    let options = {
      url: url
      , data: data
      , method: method
      , dataType: dataType
      , success: success
      // error는 공통으로 처리
    }
    $.ajax(options);

    return false;
  });
})

js 관련

html dom으로서의 this vs. jQuery의 this

$("form").on("submit", function(event) {
  event.preventDefault(); 
  console.log(this); // html dom
  console.log($(this)); // jquery
});

비동기요청(ajax)시 발생하는 상황에 대한 일괄적 처리

button의 타입: submit, reset, button

  • event.preventDefault()하지 않는 이상 return true;를 해줘도 이벤트 이미 발생
  • submit과 reset의 이벤트가 일어나는 것은 button이 아닌 button이 속한 form태그임
  • 맞음: $("form").on(submit,function(){})
  • 틀림: $("button").on(submit,function(){})

Maven: 빌드관리툴의 저장공간

  • mvn repository
  • jar파일이 필요하다면 찾으러 돌아다니지 말고 일로왕
  • 스프링에서는 gson쓰지않고 jackson-databind 사용함
  • 2.11.2 버전 다운로드받을 것

  • 얘네 둘도 버전 눌러서 다운 ㄱㄱ
  • 배포시 jar는 web-inf 밑 lib만 해당됨
    • 다른 폴더 만들어서 넣어봤자 소용없음

모델 2

기존에 서블릿에서 사용했던 코드

  • jackson.api 사용하지않음
  Enumeration<String> names = req.getAttributeNames();

  String ptrn = " \"%s\" : \"%s\" "; // json 형식
  StringBuffer json = new StringBuffer();
  json.append("{");
  while (names.hasMoreElements()) {
    String name = (String) names.nextElement(); // name: json property의 name
    Object value = req.getAttribute(name)
    json.append(String.format(ptrn, name, value));
    json.append(",");
  }
  int lastIdx = json.lastIndexOf(",");
  json.deleteCharAt(lastIdx);
  json.append("}");

  try (
    PrintWriter out = resp.getWriter();
  ) {
    out.println(json.toString());
  }

json으로 응답데이터 처리하는 유틸

  • JsonResponseUtils.java
  • jackson.api사용
public class JsonResponseUtils {
  public static void toJsonResponse(HttpServletRequest res, HttpServletResponse resp) throws IOException {
    Enumeration<String> names = req.getAttributeNames();

    Map<String, Object> dataMap = new HashMap<>();
    while (names.hasMoreElements()) {
      String name = (String) names.nextElement();
      Object value = req.getAttribute(name);
      dataMap.put(name, value);
      // req 객체 내 모든 attr이 dataMap에 저장됨
      // => req의 객체들 중 dataMap만 마셜링하면 됨
      //    (req는 헤더 정보와 같은 다른 객체도 가지고있기때문에 필요한 것만 마셜링해야함)
    }

    ObjectMapper mapper = new ObjectMapper();
    // 마샬링 write / 언마샬링 read
//  String json = mapper.writeValueAsString(dataMap); // 마샬링과 직렬화를 따로 하는 경우

    String contentType = resp.getContentType();
    if(contentType == null) {
      resp.setContentType(MimeType.JSON.toString());
    }
    try(
    ){
      mapper.writeValue(out, dataMap); // 마샬링과 직렬화를 함께
    }
  }
} // class
  • 모델2에서 흔히 하는 착각
    • 반드시 '서블릿'만 요청을 처리하고 'jsp'만 응답을 처리할 수 있다고만 생각함
    • 서블릿도 응답을 처리할 수 있고, jsp도 요청을 처리할 수있음
    • 서블릿, jsp 외에도 utils메서드와 같이 다른 방식으로 요청을 처리할 수도 있음
    • ==> 어찌됐든 요청, 응답 이라는 책임이 분리되어있기때문에 모델2구조
  • 결론
    • 서블릿이냐 jsp냐 중요한게아니고 요청과 응답 책임이 분리되어있느냐 완전독립되었느냐가 중요
  • 예시
      • CalculateServlet.java에서 응답데이터를 jsp를 통해서 내보내는 것이 아닌 jackson을 사용한 유틸 메서드로 내보냄
    • 서블릿은 응답데이터 책임 지지 않고, Utils가 책임지고 있음
    • Utils = 기존 /WEB-INF/views/jsp의 역할

캘린더

문제분석

  • 요청이 없으면 현재 달력을 제공
  • 이전달 + 다음달의 링크 제공
  • year, month 선택시 임의의 연도, 월 선택시 해당 달력을 제공
  • 로케일(언어)선택시 해당언어 달력 제공
  • timezone 선택시 해당 타임존에 맞는 오늘 날짜 제공

쌤의 목적

  • 스크립틀릿 활용
  • 폼태그

문제풀이

  • static import (JDK1.7이상)
    • <%@page import="static java.util.Calendar.*"%>

달력 기본 형식

  • 해당 달의 첫쨋날의 요일이 언제냐에 따라 시작점이 달라짐
  • 자바에서는 일요일이 1
profile
갈 길이 멀다

0개의 댓글