JSP - 7. 마셜링, JSP 기본

갓김치·2020년 11월 26일
0

JSP+Spring

목록 보기
8/43

복습

user-agent + enum

  • enum 문법을 잘 활용하게되면 '가능하면 수정사항을 발생시키지말자' 라는 프로그래밍 원칙을 잘 지킬 수 있음

accept-langugae + client's locale

  • 클라이언트가 선택한 locale 이나 클라이언트의 기본 locale 을 통한 메세지 전달
  • ResourceBundle 사용시 주의점
    • basename 시작점은 클래스패스
    • basename 은 로케일(_en, _kr, ...), 확장자 포함x



accept

  • 사용자가 원하는 데이터타입에 맞춰 서버에서 보내주기
$.ajax({
  url: "<%=request.getContextPath()%>/02/getMessage.jsp"
  ,data: { lang : language } // lang에 "" 없는 이유: js객체이기때문에 알아서 식별해줌
  ,method:"get" // 기본이니 생략가능
  ,dataType:"text" // -> 리퀘스트헤더의 mime을 결정 | response의 Content-Type과 한쌍
  // dataType: "json" -> Accept : application/json  
  ,success: function(resp) { // jqeury 컨텍스트가 콜백함수호출, dataType에따라 resp타입 달라짐
    $("#resultArea").text(resp);
  }
  ,error: function(xhr) { // 비동기요청시 기존사용했던 api객체(XMLHttpRequest) 이용하기때문에 에러보기위해 요청,응답정보 다시가져옴
    console.log(xhr.status);
  }
});
  • ajax는 문자열 기반 함수
    • 원칙적으로 파일업로드는 불가능함
    • dataType이 설정되어있다면 문자열기반이라고 가정하세요
  • dataType: mime을 결정하는 상수들
    • text = text/plain
    • json = application/json
    • 이것은 request header의 accept와 같음 -> response header의 Content-Type과 한쌍
  • 마샬링, 언마샬링 (뒤에서 다시 설명)
    • json이 ajax로 넘어오면 이제 js객체가 된다
  • 요청이 어느 방식이냐가 중요한게아니고 요청이 무엇이냐가 중요한거다
    • 동기, 비동기 방식에 관계없이 요청이라는건 변하지않음

getMessage.jsp를 서블릿으로 분리하기

  • 기존 getMessage.jsp 에 있던 스크립틀릿 소스
  • GetMessageServlet.java로 분리
<%
response.setContentType("text/plain;charset=UTF-8");
String language = request.getParameter("lang");
String acceptLanguage = request.getHeader("accept-language");
Locale locale = request.getLocale();
if(language!=null && !language.isEmpty()) {
  locale = Locale.forLanguageTag(language.toLowerCase());
}
ResourceBundle bundle = ResourceBundle.getBundle("kr.or.ddit.msg.message", locale);
String message = bundle.getString("bow");
%>
<%= message%>
  • 분리하는 이유
  1. jsp내의 자바 코드 존재의 이유는 단지 message라는 데이터를 위해 존재하고있음
  2. ui와 직접적으로 관련되어있지 않기때문에 굳이 서블릿이 아닌 jsp에 존재해야할 필요 없음
    -> 응답데이터 형태가 html이 아니라면 굳이 jsp로 만들 필요 x

getMessage.jsp 이동 -> /WEB-INF/views

  • 옮기는 이유
  1. 요청을 직접적으로 받지 않고 자신의 역할만 수행하도록
  2. 보안때문에 (/WEB-INF/ 폴더는 외부에서 접근 불가능)

GetMessageServlet.java

enum 활용해 mime type 결정하기

  • 서블릿 내의 내부클래스
// 비동기 요청의 dataType을 상수로 만들기
public static enum MimeType{ 

  HTML("text/html;charset=UTF-8"), PLAIN("text/plain;charset=UTF-8"),
  JAVASCRIPT("text/javascript;charset=UTF-8"),
  XML("application/xml;charset=UTF-8"), JSON("application/json;charset=UTF-8");
//XML("text/xml;charset=UTF-8"), JSON("text/json;charset=UTF-8"),
//XML과 JSON이 텍스트 기반이기때문에 메인타입을 text로 써줘도 문제는 없지만 규칙은 application 임

  private String mime;

  private MimeType(String mime) {
    this.mime = mime;
  }

  public String getMime() {
    return mime;
  }

  @Override
  public String toString() {
    return getMime();
  }

  public static MimeType parseAcceptToMimeType(HttpServletRequest req) {
    // 클라이언트가 요청한 mime확인
    String accept = req.getHeader("Accept");		
    MimeType mime = MimeType.HTML; // 기본값 셋팅 = 웹이니 html
    for(MimeType tmp : values()) {
      if(accept.toUpperCase().contains(tmp.name())) {
        mime = tmp;
        break;
      }
    }
    return mime;
  }
}

doGet()

  • jsp에 있던 소스와 다를 바 없으나 각 데이터타입에 맞게 응답데이터를 송출할 수 있도록 처리해 주었음
    • 서버는 클라이언트가 어떤 방식으로 데이터를 요청해도 accept 헤더에 맞는 데이터를 넘겨줄 수 있어야한다.
  • mime 타입에 따른 데이터 송출방식
    • plain: 그대로 out으로 송출
    • json, xml: 마샬링을 거쳐 맞는 형태로 만들어준 다음 직렬화 하여송출
    • html: 웹상 언어의 기본은 HTML이기때문에 else문에 이 코드를 위치
      • 스코프를 이용해 getMessage.jsp로 송출

JSON: JavaScript Object Notation

= 서로 다른 언어 간의 데이터 교환을 위한 형식

  • 참고: json.org
  • xml과 json은 영어와 같은 세계공용어
    • json은 xml보다 경량 (닫힘태그 x)
  • A collection of name/value pairs.

Syntax Diagram

object

  • { }
  • { "name"(string) : value }
  • { "name"(string) : value
    ,"name"(string) : value
    ,"name"(string) : value
    }
  • value: number, string, object, array, boolean, null

array

  • [] : length=0
  • [ value ]
  • [ value, value ]

value: 데이터 종류

  • A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested.

string

  • A string is a sequence of zero or more Unicode characters, wrapped in double quotes, using backslash escapes. A character is represented as a single character string. A string is very much like a C or Java string.

number

  • A number is very much like a C or Java number, except that the octal and hexadecimal formats are not used.

whitespace

  • Whitespace can be inserted between any pair of tokens. Excepting a few encoding details, that completely describes the language.

Marshalling & Serialization

  • GetMessageServlet.java
  • messageLocale.jsp

마셜링 vs. 언마셜링

비교

  • response에 담겨있는 것: json 로우데이터
  • preivew: 크롬이 언마샬링한 js객체 == success: function의 매개변수 resp

xml


트리구조 만들어짐

직렬화 vs. 역직렬화

사칙연산기 w/ enum

장점

  • 사칙연산을 5칙연산으로 바꿀거야 나머지연산자 추가
    • jsp, 서블릿 바꿀필요 x , enum만 수정하면됨

calculaterForm.jsp

CalculateServlet.java

1) enum 생성 전 코드

switch (opParam) {
case "PLUS":
	result = leftOp + rightOp;
	break;
case "MINUS":
	result = leftOp - rightOp;
	break;
case "MULTIPLY":
	result = leftOp * rightOp;
	break;
case "DIVIDE":
	result = leftOp / rightOp;
	break;
default:
	break;
}

2) enum 생성 후에도 서블릿에서 연산하는 코드

  • 이때 정의했던 enum 클래스가 간단하게 기호만 가지고 있던 enum이었음
switch (operator) {
case PLUS:
	result = leftOp + rightOp;
	break;
case MINUS:
	result = leftOp - rightOp;
	break;
case MULTIPLY:
	result = leftOp * rightOp;
	break;
case DIVIDE:
	result = leftOp / rightOp;
	break;
}

3) enum 내 코드

public enum OperateType {
// () -> {} 함수 객체 자체가 realoperator의 인스턴스임
PLUS('+', (l, r)->{return l + r;}), // 람다식도 결국 jvm에 의해 익명객체로 바뀜
MINUS('-', (l, r)->{return l - r;}),
MULTIPLY('*', (l, r)->{return l * r;}),
DIVIDE('/', (l, r)->{return l / r;}),
MODULAR('%', new RealOperator() { // 람다식 사용 못할 때 쓰는 익명객체
      public int operate(int l, int r) {
        return l % r;
      };
});

@FunctionalInterface
private static interface RealOperator {
  // 인터페이스 1개당 1개의 메서드 => 기능적 함수형 인터페이스
  public int operate(int leftOp, int rightOp);
}

private char sign;
private RealOperator realOperator;

// 생성자는 상수 정의시에만 결정됨
private OperateType(char sign, RealOperator realOperator) {
  this.sign = sign;
  this.realOperator = realOperator;
}

public char getSign() {
  return sign;
}

/*
 * 연산 원리: 내 타입의 인스턴스가 MINUS라면 MINUS 연산
 * 그러나 무슨 연산을 할 것인지는 이 메서드내에서 결정될 수 없음. enum의 생성자 (ex. plus()) 에서 결정 되어야함.
 * -> 상수에 의해 객체 상태가 결정될 때 객체가 하는 일도 결정이 되어야함
 *    하지만 자바의 원칙적 문법에서는 행위 자체를 파라미터로 넘기는게 불가능함
 * => 그래서 정의하는게 Functional Interface!
 */
public int operator (int leftOp, int rightOp) {
  return realOperator.operate(leftOp, rightOp);
  // => 연산에 대한 책임을 realOperator에게 떠넘김
}



} // enum

JSP: Java Server Page

  • 서버사이드에서 페이지를 구성하기 위한 자바로 구성되어있느 녀석

JSP 소스 표준 구성 요소 (스펙)

1. 정적 텍스트 요소

  • HTML, JavaScript 등의 클라이언트 스크립트 언어를 포함한 정적 요소

2. 스크립트 구성요소 (동적)

  • JSP 스크립트 기호를 사용한 스크립트 소스 요소

1) 스크립틀릿(Scriptlet)

  • <% //java code %>

2) 표현식(Expression)

  • <%="출력데이터" %>
  • 리터럴이나 변수

3) 지시자(Directive)

  • <%--@ 설정정보 --%>
  • 실행코드에 영향미치지않는 설정정보가 들어감

    buffer, autoFlush
    응답데이터가 1byte씩 스트림으로 나가게 되면 에러처리불가
    -> 이미 한바이트씩 읽으면서 200 라고 처리했기떄문에
    -> 이럴 때 디렉티브의 buffer속성이용해서 처리할수있음

    • buffer="8kb" autoFlush="true" default
      • 장점: 전송 속도 빠름, 응답 데이터 나가기 전에 중간에 예외 발생하면 톰캣이 버퍼내용 싹회수해서 비우기때문에 중간에 예외 발생하더라도 온전하게 상태코드 내보낼수있음
    • buffer="1kb" autoFlush="true"
      • 버퍼가 한번 방출되면 브라우저가 받아 화면을 그리기 시작함 500글자 내보낸 후, 600번째글자에서 오류가나면 이미 상태코드가 200으로만 나갔기때문에 에러를 못 보냄.
      • 나중에 프레임웤에서 페이지 모듈화에서 문제가 됨
    • buffer="1kb" autoFlush="false"
      • 하지만 flush를 false로 두면 에러를 내보낼수있음
  • buffer와 flush의 특성 , 지시자의 의미와 지시자 특성★

4) 선언부(Declaration)

  • <%! //전역 멤버 %>
  • 스크립틀릿 안에서는 지역코드여서 전역멤버를 따로 뺌
  • 하지만 별 의미 없어서 스코프를 사용함
    • 이유: 전역멤버를 사용하는 이유는 외부에서 쓰기위한 것임. 하지만 서블릿 객체생성은 컨테이너인 톰캣의 영역이기때문에 객체를 건드릴 수 없음.

5) 주석(Comment)

  • <%-- --%> : 서버사이드 주석
    • 응답 데이터에 포함되지 않음
    • 서버사이드 주석(java, jsp)을 써야하는 이유
      • 개발과 관련된 정보를 클.사 주석으로 넣으면 고스란히 응답데이터로 나가버림
      • 클.사 주석은 응답데이터에도 나감, 많이 쓰면 응답데이터가 무거워짐
      • 시큐어 코딩 가이드 라인: 에러페이지로 stack trace 안보이도록, 서버의 정보 감추기
  • <!-- --> : 클라이언트사이드 주석
    • 클라이언트 사이드 주석(html, css, js)은 브라우저에서 보임
    • 서버사이드에서는 그냥 스트링이지만, 브라우저에서 응답데이터 번역시점에 주석으로 번역되어 보이게됨

3. 기본객체(내장객체)

4. 액션 태그(jsp action tag)

5. 표현 언어(EL: Expression Language)

6. JSTL(tag library)

과제

읽어볼것

https://www.json.org/json-en.html
책37쪽 읽어보고 실습
차시별학습안내서에 나온 내용과 교재페이지를 복습할것

profile
갈 길이 멀다

0개의 댓글