$.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);
}
});
<%
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%>
// 비동기 요청의 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;
}
}
= 서로 다른 언어 간의 데이터 교환을 위한 형식
트리구조 만들어짐
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;
}
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;
}
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
<% //java code %>
<%="출력데이터" %>
<%--@ 설정정보 --%>
buffer, autoFlush
응답데이터가 1byte씩 스트림으로 나가게 되면 에러처리불가
-> 이미 한바이트씩 읽으면서 200 라고 처리했기떄문에
-> 이럴 때 디렉티브의 buffer속성이용해서 처리할수있음
- buffer="8kb" autoFlush="true" default
- 장점: 전송 속도 빠름, 응답 데이터 나가기 전에 중간에 예외 발생하면 톰캣이 버퍼내용 싹회수해서 비우기때문에 중간에 예외 발생하더라도 온전하게 상태코드 내보낼수있음
- buffer="1kb" autoFlush="true"
- 버퍼가 한번 방출되면 브라우저가 받아 화면을 그리기 시작함 500글자 내보낸 후, 600번째글자에서 오류가나면 이미 상태코드가 200으로만 나갔기때문에 에러를 못 보냄.
- 나중에 프레임웤에서 페이지 모듈화에서 문제가 됨
- buffer="1kb" autoFlush="false"
- 하지만 flush를 false로 두면 에러를 내보낼수있음
<%! //전역 멤버 %>
<%-- --%>
: 서버사이드 주석<!-- -->
: 클라이언트사이드 주석https://www.json.org/json-en.html
책37쪽 읽어보고 실습
차시별학습안내서에 나온 내용과 교재페이지를 복습할것