이전에 JDBC Template을 통해 SQL을 실행하였다면 Mybatis는 해당 흐름을 전용 라이브러리를 통해 대체하여 동작한다고 생각하면 된다.
Mybatis 동작구조
* 위 객체사용객체는 mybatis-x.x.x.jar 파일에 존 재
Mybatis 라이브러리 다운 및 연동
Mybatis.3.4.5 버전을 다운로드 한다.
Mybatis 라이브러리 다운 및 연동
다운로드가 완료되면 압축을 해제하고 mybatis-3.4.5.jar 라 이브러리를 프로젝트 내 WEB-INF/lib/ 경로 안에 추가한다.
ibatis와 Mybatis
기존에 Apache project 에서 ibatis를 운영하던 팀이 2010년 5월 9일에 Google 팀으로 이 동하면서 Mybatis로 이름을 바꾸었다. Mybatis는 기존의 ibatis의 한계점이었던 동적 쿼리와 어노테이션 처리를 보강하여 더 나은 기능을 제공하고 있다. 반대로 ibatis는 현재 비활성화 상태이며, 기존에 ibatis로 만들어진 애플리케이션의 지원을 위해 라이브러리만 제공하고 있다.
ibatis와 Mybatis의 차이점
1. Java 요구 버전
: iBatis는 JDK 1.4 이상, MyBatis에서는 JDK 1.5 이상 사용이 가능하다.
Libraries 탭을 클릭한 후 > Classpath 클릭 > 오른쪽상단의 Add JARs... 클릭하여 > 미리 붙여넣기 해준 파일 두개를 추가 해 준다.
추가된 모습
section01.Application
import org.apache.ibatis.datasource.pooled.PooledDataSource;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
public class Application {
private static String DRIVER = "oracle.jdbc.driver.OracleDriver";
private static String URL = "jdbc:oracle:thin:@localhost:1521:xe";
private static String USER = "C##GREEDY";
private static String PASSWORD = "GREEDY";
public static void main(String[] args) {
/* DB 접속에 관한 환경 설정
* --------------------------------------------
* JdbcTransctionFactory : 수동 커밋
* ManagedTransactionFactory : 자동 커밋
* --------------------------------------------
* PooledDataSource : ConnectionPool 사용
* UnPooledDataSource : ConnectionPool 미사용
* --------------------------------------------
* */
Environment environment =
new Environment("dev"
//환경 정보 이름
, new JdbcTransactionFactory()
//트랜잭션 매니저 종류 결정
, new PooledDataSource(DRIVER, URL, USER, PASSWORD));
//Connection Pool 사용 유무
/* 생성한 환경 설정 정보를 가지고 마이바티스 설정 객체 생성 */
Configuration configuration = new Configuration(environment);
/* 설정 객체에 매퍼 등록 */
configuration.addMapper(Mapper.class);
/* SqlSessionFactory : SqlSession 객체를 생성하기 위한 팩토리
역할을 수행하는 인터페이스
* SqlSessionFactoryBuilder : SqlSessionFactory 인터페이스
타입의 하위 구현 객체를 생성하기 위한 빌드 역할 수행
* build() : 설정에 대한 정보를 담고 있는 Configuration 타입의
객체 혹은 외부 설정 파일과 연결 된 스트림을 매개변수로 전달하면
* SqlSessionFactory 인터페이스 타입의 객체를 반환하는 메소드
* */
SqlSessionFactory sqlSessionFactory
= new SqlSessionFactoryBuilder().build(configuration);
/* opneSession() : SqlSession 인터페이스 타입의 객체를 반환하는 메소드,
boolean 타입을 인자로 전달
* false : Connection 인터페이스 타입 객체로 DML 수행 후 auto commit
에 대한 옵션을 false로 지정(권장)
* true : Connection 인터페이스 타입 객체로 DML 수행 후 auto commit에
대한 옵션을 true로 지정
* */
SqlSession sqlSession = sqlSessionFactory.openSession(false);
/* getMapper() : Configuration에 등록 된 매퍼를 동일 타입에 대해
반환하는 메소드 */
Mapper mapper = sqlSession.getMapper(Mapper.class);
/* Mapper 인터페이스에 작성 된 메소드를 호출하여 쿼리 실행 */
java.util.Date date = mapper.selectSysdate();
System.out.println(date);
/* close() : SqlSession 객체 반납 */
sqlSession.close();
}
}
interface Mapper
import org.apache.ibatis.annotations.Select;
public interface Mapper {
@Select("SELECT SYSDATE FROM DUAL")
java.util.Date selectSysdate();
}
Location URI에 Clone 할 원격 저장소의 URI 입력 후 Authentication에 GitHub 계정 정보 입력하여 Next 원격 저장소에 존재하는 master branch 체크 된 상태로 Next 사용할 지역 저장소 경로 Directory에서 지정 후 Finish
Clone 완료 된 상태
지역 저장소의 Project를 Eclipse Workspace로 Import
Finish 누르고 Import 된 상태의 프로젝트
각자 별도의 Branch를 만들어서 작업해서 Push하기 위해 Team > Switch To > New Branch 창을 열고 Branch name 입력 후 Finish
새로운 Branch로 바뀐 상태
새로운 Branch로 작업 한 내용을 원격 저장소에 반영 시키기 위해 우클릭 > Team > Add to Index 클릭
작업을 통해 변경이 있거나 추가 된 파일이 Staged Changes로 올라감 .class 등의 파일은 컴파일 된 결과물로 원격 저장소에서 관리할 필요가 없는 파일이므로 –로 제거
Git에서 특정 파일을 추적하지 않게 하고 싶다면 프로젝트 최상위에 .gitignore라는 파일을 추가
Use or create repository in parent folder of project 체크박스 클릭 > Create Repository 버튼 클릭 > Finish 하여 프로젝트 최상위에 .git(지역 저장소) 폴더 생성하기
.git(지역 저장소) 폴더 생성 시 프로젝트 모습 ( ? -> 추적 안됨(untracked)을 의미)
Team > Add to Index 클릭 시 모습 ( + -> 새롭게 추가 된 파일이 스테이지 됨)
Window > Show View > Git > Git Staging 탭을 통해 Add to Index로 새롭게 추가 된 모든 파일이 Staged Changes 에 올라가 있음을 확인함.
그 중 Commit을 원치 않는 파일이 있다면 –를 클릭해서 Unstatged Changes로 이동 시켜 Commit에서 제외 시킬 수 있음. 또한 Add to Index를 하지 않더라도 Unstatged Changes에서 직접 파일을 선택하여 +를 클릭해서 Add 시킬 수도 있음.
Commit Message를 작성하여 Commit and Push 클릭
Commit and Push : 지역 저장소에 commit을 만듦과 동시에 해당 commit을 원격 저장소로 Push Commit : 지역 저장소에 commit을 만듦
Push Branch master 창에서 사용할 원격 저장소 uri 복사해서 붙여넣음.
Authentication 에는 GitHub 계정의 Email, Password를 입력하고 체크박스를 체크하여 비밀번호를 기억 함으로써 다음에 비밀번호를 다시 입력하지 않아도 되게 함.
Next > Finish 버튼 등을 눌러 지역 저장소의 master 브랜치에서 원격 저장소의 master 브랜치로 Push Push가 끝나면 Push Result 창이 뜸
원격 저장소에 접속하면 first commit의 결과가 올라와 있는 것을 확인할 수 있음
원격 저장소의 settings > Manage access > collaborator로 팀원 초대 초대 받은 팀원은 Email을 확인하여 accept invitation 하면 해당 원격 저장소의 collaborator가 됨
Eclipse에서 Window > Show View > Git Repositories 탭 열고 Clone a Git repository 클릭
* url은 필수 입력, 나머지 매개변수 생략가능 * url제외한 나머지를 생략할 경우 servlet이나 document에서 응답한 값을 선택자로 선택된 태그의 텍스트 노드에 출력(get방식) / 페이지 변경 * data입력시(post방식)
예시
<script>
function test(url)
{
$(‘.pp’).load(url); //get방식으로 전달하고 class pp에 응답한
값을 출력 쿼리 스트링으로 값 전달
$(‘.pp’).load(url,{id:’홍길동’,pw:0000}); //post방식전달
$(‘.pp’).load(url,{id:’홍길동’,pw:0000}, responseFunc());
}
function responseFunc(data, status)
{
var test=data+status; $(‘.pp’).text(test);
}
</script>
<button onclick=“test(‘ajaxtest?id=??&pw=00’)”>데이터전송</button>
<div class=‘pp’></div>
<p class=‘pp’></p>
<span class=‘pp’></span>
$.get() / $.post()
파라미터
사용법
* 응답처리에 관한 페이지 변경은 function에서 수행
$.ajax()
처리절차
1. url 속성을 통해 전송할 URL 주소 선언
2. data 속성을 통해 전달할 데이터 설정
3. 성공, 실패 시 처리할 로직을 함수로 선언
4. 반드시 처리할 로직을 선언
$.ajax() 주요 속성 정보
예시
//서블릿을 호출하여 String 값을 전달
$.ajax({
url : "test", // 1. 전달할 servlet url mapping
data : {name : "hongGD"}, // 2. 전달할 데이터
type : "get",
// 전달할 방식 지정
success : function(data){ // 3-1. 성공 시 처리할 절차
console.log("성공 "+data);
},
error : function(request,status,error) {
// 3-2. 에러 발생 시 처리할 절차
alert("code:"+request.status+"\n"+
"message:"+request.responseText+"\n"+"error:"+error);
},
complete : function(data){ // 4. 반드시 처리할 절차
console.log("무조건 호출 되는 로직");
}
});
▼ 코드로 예시 확인▼
chap03-index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>simple ajax</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<h1 align="center">ajax 요청 후 stream을 이용한 문자열 응답</h1>
<h2>1. GET 방식의 데이터 요청</h2>
<h3>1-1. 데이터 전송 없이 문자열 반환</h3>
<button id="send-get-1">전송</button>
<script>
$("#send-get-1").click(function(){
$.ajax({
url : "/chap03/first/receive",
type : "get",
success : function(data){
alert(data);
},
error : function(xhr) {
console.log(xhr);
}
});
});
</script>
<h3>1-2. data로 값 전송 후 문자열 반환</h3>
<input type="text" id="message-get-2"><button id="send-get-2">
메세지 전송</button>
<script>
$("#send-get-2").click(function(){
const message = $("#message-get-2").val();
$.ajax({
url : "/chap03/first/message",
type : "get",
data : { message : message },
success : function(data){
alert(data);
},
error : function(xhr) {
console.log(xhr);
}
});
});
</script>
<h2>2. POST 방식의 데이터 요청</h2>
<h3>2-1. 데이터 전송 없이 문자열 반환</h3>
<button id="send-post-1">전송</button>
<script>
$("#send-post-1").click(function(){
$.ajax({
url : "/chap03/first/receive",
type : "post",
success : function(data){
alert(data);
},
error : function(xhr) {
console.log(xhr);
}
});
});
</script>
<h3>2-2. data로 값 전송 후 문자열 반환</h3>
<input type="text" id="message-post-2"><button id="send-post-2">
메세지 전송</button>
<script>
$("#send-post-2").click(function(){
const message = $("#message-post-2").val();
$.ajax({
url : "/chap03/first/message",
type : "post",
data : { message : message },
success : function(data){
alert(data);
},
error : function(xhr) {
console.log(xhr);
}
});
});
</script>
</body>
</html>
FirstMessageAjaxServlet extends HttpServlet
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/first/message")
public class FirstMessageAjaxServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
/* 전달 된 파라미터를 꺼낼 때는 request의 getParameter 메소드를 이용한다.
* 마찬가지로 응답 데이터에 한글이 포함되어 있는 경우 응답에 대한
인코딩 설정을 해 주어야 한다.
* 이 때 반환하는 데이터의 기본 형태는 text/plain이다.
* */
String message = request.getParameter("message");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.print("I'm get!!" + message + "안녕하세요!");
out.flush();
out.close();
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/* POST 방식으로 요청 시에 인코딩 설정을 별도로 해주지 않아도 한글 데이터는
깨지지 않는다. => Request에 대한 설명
* $.ajax() 로 요청하면 contentType이 application/x-www-form-urlencoded로 설정되며
* 기본 인코딩 방식은 UTF-8로 인코딩 된 데이터가 전송 된다.
* */
String message = request.getParameter("message");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.print("I'm post!!" + message + "안녕하세요!");
out.flush();
out.close();
}
}
FirstReceiveAjaxServlet extends HttpServlet
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/first/receive")
public class FirstReceiveAjaxServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
/* 응답하는 데이터가 단순 문자열인 경우 문자열만 내보낼 수 있다.
* 이 때 기본 응답 데이터는 text/plain이다. 또한 인코딩 설정도 되어 있지 않다.
* 한글 데이터를 응답하려면 인코딩 설정을 해주어야 한다.
* */
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.print("I'm get!! insert value!!! 안녕하세요!");
out.flush();
out.close();
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
/* post 방식 요청도 같은 방식으로 응답한다. */
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.print("I'm post!! insert value!!! 안녕하세요!");
out.flush();
out.close();
}
}
04-index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>json string</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
</head>
<body>
<h1 align="center">ajax 요청 후 stream을 이용한
json 응답(simple json string)</h1>
<h2>JSON 데이터 요청</h2>
<h3>1-1. 데이터 전송 없이 json 반환</h3>
<button id="send-get-1">전송</button>
<script>
$("#send-get-1").click(function(){
$.ajax({
url : "/chap04/receive/json",
type : "get",
success : function(data){
console.log(data);
/* json 형태의 문자열을 Object 타입의 객체로
파싱할 때 사용하는 메소드이다. */
let jsonObject = JSON.parse(data);
console.log(jsonObject);
console.table(jsonObject);
},
error : function(xhr) {
console.log(xhr);
}
});
});
</script>
<h3>1-2. 데이터 전송 없이 jsonArray 반환</h3>
<button id="send-get-2">전송</button>
<script>
$("#send-get-2").click(function(){
$.ajax({
url : "/chap04/receive/array",
type : "get",
success : function(data){
console.log(data);
/* json 형태의 문자열을 Object 타입의
객체로 파싱할 때 사용하는 메소드이다. */
let jsonObject = JSON.parse(data);
console.log(jsonObject);
console.table(jsonObject);
},
error : function(xhr) {
console.log(xhr);
}
});
});
</script>
<h3>1-3. 데이터 전송 없이 응답 헤더 설정 후 jsonArray 반환</h3>
<button id="send-get-3">전송</button>
<script>
$("#send-get-3").click(function(){
$.ajax({
url : "/chap04/receive/jsonarray",
type : "get",
success : function(data){
/* 응답 헤더의 content-type 설정을 application/json으로
하게 되면 JSON.parse()를 하지 않아도
object로 인식한다. */
console.log(data);
console.table(data);
},
error : function(xhr){
console.log(xhr);
}
});
});
</script>
</body>
</html>
ReceiveJsonStringServlet extends HttpServlet
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/receive/json")
public class ReceiveJsonStringServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
/* ajax 응답은 단 한 번의 문자열 응답만 할 수 있다.
* 따라서 여러 개의 값을 전달하기 위해서는 특수한 방법을 이용한다.
* java에서 이용하는 object는 javascript에서 이해할 수 없다.
* 따라서 자바스크립트에서 이해할 수 있는 object 타입으로 변환을 해 주어야 한다.
* 이 떄 json이라는 object 타입으로 변환할 수 있는 문자열 형태로
가공하여 응답을 해주게 되면
* javascript에서 object로 취급할 수 있다.
* json 데이터의 규칙은 key와 value를 : 으로 구분하며,
여러 개 key value set은 , 로 구분한다.
* 이 때 키는 문자열 형태로 ""로 감싸져야 하며, 문자열에
해당하는 값 또한 ""로 감싸져야 한다.
* */
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.print("{\"type\":\"get\",\"firstName\":\"gildong\"
,\"lastName\":\"hong\",\"age\":20}");
out.flush();
out.close();
}
}
ReceiveArrayStringServlet extends HttpServlet
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/receive/array")
public class ReceiveArrayStringServlet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
/* json으로 javascript object로 변환시키기 위해서는 array의 경우
대괄호 []로 감싸고 각 인덱스의 구분은 , 로 한다. */
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.print("[{\"type\":\"get\",\"firstName\":\"gildong\"
,\"lastName\":\"hong\",\"age\":20},"
+ "{\"type\":\"get\",\"firstName\":\"gwansoon\"
,\"lastName\":\"yoo\",\"age\":16}]");
out.flush();
out.close();
}
}
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.greedy.model.dto.MemberDTO;
@WebServlet("/gson/test4")
public class GsonTestServlet4 extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String jsonString = request.getParameter("jsonString");
System.out.println(jsonString);
// Gson gson = new Gson();
/* 포맷 변경 테스트
* java object -> json의 경우 포맷 적용 된다.
* json -> java object의 경우 포맷이 적용되지 않아 Exception이 발생한다.
* 따라서 별도로 날짜 포맷에 대한 설정을 지정해야 한다.
* => GsonBuilder를 통해 Gson에 대한 설정을 한다.
특히 날짜 포맷의 경우 setDateFormat() 메소드를 이용할 수 있다.
* */
Gson gson = new GsonBuilder().setDateFormat("yyyy/MM/dd").create();
String dateTest = gson.toJson(new java.sql.Date(System.currentTimeMillis()));
System.out.println(dateTest);
/* json의 key와 필드가 다른 경우 클래스 필드 부분에
@SerializedName("memberCode")를 달아주면
* 직렬화 혹은 역직렬화시 json key와 필드를 매핑해주게 된다. */
MemberDTO member = gson.fromJson(jsonString, MemberDTO.class);
System.out.println(member);
response.setContentType("application/json; charset=UTF-8");
PrintWriter out = response.getWriter();
out.print(gson.toJson(member));
out.flush();
out.close();
}
}
GsonTestServlet5 extends HttpServlet
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.greedy.model.dto.MemberDTO;
@WebServlet("/gson/test5")
public class GsonTestServlet5 extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
MemberDTO member = new MemberDTO("M01", "<h1>길동</h1>",
null, 20, new java.sql.Date(System.currentTimeMillis()));
Gson gson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd hh:mm:ss:SSS")
// 날짜 포맷 설정
.setPrettyPrinting()
// 프린트 포맷을 예쁘게 - 개행
// .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES)
//필드 이름으로 json key 값 네이밍 설정을 할 때 사용하는 옵션
.serializeNulls()
// 필드 값이 null이여도 직렬화 한다
.disableHtmlEscaping()
// 직렬화 시 escape 시퀀스 처리 하지 않는다
.create();
String jsonString = gson.toJson(member);
System.out.println(jsonString);
response.setContentType("application/json; charset=UTF-8");
PrintWriter out = response.getWriter();
out.print(jsonString);
out.flush();
out.close();
}
}
서버로부터 데이터를 가져와 전체 페이지를 새로 고치지 않고 일부만 로드 할 수 있게 하는 기법으로 비동기식 요청을 보내는데 필요한 기술을 말함
장단점
장점
비동기식 방식으로 웹서버의 응답을 기다리지 않고 데이터를 빠르게 처리하는 개발기법
페이지 리로딩 없이 처리됨
예) 실시간 검색어, 검색어자동 완성
단점
한 페이지에 지속적으로 사용시 리소스가 계속 쌓여 페이지가 느려짐
스크립트로 되어 있어 에러 발생시 디버깅이 어려움
비동기식/동기식 처리
비동기식 처리모델
페이지가 로드 되는 동안 브라우저는 먼저 서버에 데이터를 요청 script문 실행한 후 페이지의 나머지를 계속 로드하고 페이지와 사용자의 상호작용을 처리하며 브라우저는 요청한 데이터를 기다리지 않는다. 그리고 요청한 데이터가 도착을 하면 그때 이벤트가 발생하면서 지정된 함수가 호출되어 실행되는 방식. (넌블로킹 모델)
동기식 처리모델
페이지가 로드 되는 동안 브라우저는 script문을 실행되면 그 실행이 종료될때 까지 나머지 페이지를 로드하지 않고 기다리고 있다가 그 script문이 처리가 종료가 되면 페이지의 나머지 부분을 로드 하는 방식
Javascript(Ajax)
처리구조
처리절차
1. script문에 요청을 위한 XMLHttpRequest객체 생성
2. 서버의 응답을 처리할 함수 생성 및 지정 ☞ onreadystatechange에 함수지정
3. open메소드로 요청할 방법 및 요청할 대상(Server)선정 ☞ 요청메소드, 요청주소, 동기/비동기 설정, 아이디, 패스워드 설정
5. 응답상태에 따라 상태확인 ☞ readyState(데이터응답) / status(처리결과) 값을 이용
6. 응답완료 reponseText / reponseXML이용 응답처리
XMLHttpRequest
XMLHttpRequest란?
비동기식으로 서버에 요청(Requset)을 보내기 위한 객체로 요청 및 응답을 처리함
속성
참고
readyState속성 값
status속성 값
200 (OK) : 요청성공
404 (Not Found) : 페이지 없음
500 (Internal Server Error) : 서버오류발생 등
추가 참조 https://www.w3schools.com/tags/ref_httpmessages.asp
매소드
참고- Header속성값
ajax 요청/응답처리
1. 객체생성
생성방법
IE7이상, safari, firefox, opera, chrome
var httpRequest = new XMLHttpRequest();
IE5이나 6 이하의 버전
var httpRequest = new ActiveXObject(Microsoft.XMLHTTP);
예시
<script>
var httpRequest;
function getHttpRequest(){
//브라우저가 IE일 경우
if(window.ActiveXObject){
try{ //신버전 9버전 이후
return new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try{ //그 이전 버전
return new ActiveXObject("Microsoft.XMLHTTP");
} catch (ex) {
return null
}
}
//그 외의 브라우저일 경우
} else if(window.XMLHttpRequest) return new XMLHttpRequest();
else return null;
}
</script>
2. 응답처리 함수 설정
객체생성 후 속성값에 함수를 설정
var httpRequest= getHttpRequest();
httpRequest.onreadystatechange = 실행할 함수명;
또는
httpRequest.onreadystatechange = function(){
// 처리 로직
}
예시
<script>
var httpRequest= getHttpRequest();
httpRequest.onreadystatechange=test;
function test()
{
if(httpRequest.readyState===4) //전송상태확인
{
if(httpRequest.status===200) //완료상태확인
{
doucument.getElementById(“ex”).innerHTML
=httpRequest.responseText; //응답값처리
}
}
}
</script>
응답상태를 기준으로 처리 로직을 구성
3. 요청대상설정 / 요청처리
객체생성 후 매서드이용 요청대상 설정/요청처리
var httpRequest= getHttpRequest();
httpRequest.open(전송방법, 요청페이지 또는 파일,
비동기식/동기식 설정, id값, password값)
httpRequest.send();
또는
httpRequest.send(“param값”);
☞ param설정 : 명칭=값 형식으로 표현하고 여러 값일 경우 &를 사용
☞ 전송방법 및 페이지 외 생략 가능 / 비동기 설정이 default값
예시
<script>
var httpRequest= getHttpRequest();
httpRequest.onreadystatechange=test;
httpRequest.open(“get”,”test?name=hongGD&age=15”,true);
httpRequest.send();
또는
httpRequest.open(“post”,”test”,true);
httpRequest.send(“name=hongGD&age=15”);
</script>
4. 응답처리
객체생성 후 속성값으로 응답처리(text)
var httpRequest= getHttpRequest();
var value=httpRequest.responseText;
또는
document.getElementById(“test”).innerHTML
=httpRequest.responseText;
* 문자 인코딩에 주의(servlet/jsp에서 응답시 코딩처리)
예시
<script>
var httpRequest= getHttpRequest();
httpRequest.onreadystatechange=test;
function test()
{
if(httpRequest.readyState===4)
{
if(httpRequest.status===200)
{
doucument.getElementById(“ex”).innerHTML
=httpRequest.responseText; //특정 태그에 응답 받은 데이터 처리
}
}
}
</script>
4. 응답처리
객체생성 후 속성값으로 응답처리(xml)
var httpRequest= getHttpRequest();
var xmldoc=httpRequest.responseXML;
var xml=xmldoc.getElementsByTagName(“태그명칭”);
var text=“”;
for(i=0;i<xml.length;i++)
{
text+=xml[i].childNodes[0].nodeValue+”<br>”;//노드값불러오기
}
document.getElementById(“명칭”).innerHTML=text;
* 문자 인코딩에 주의(servlet / jsp에서 응답시 코딩처리)
예시
var httpRequest= getHttpRequest();
httpRequest.onreadystatechange=test;
function test()
{
if(httpRequest.readyState===4)
{
if(httpRequest.status===200)
{
var xmldoc=httpRequest.responseXML;
var xml=xmldoc.getElementsByTagName(“태그명칭”);
var text=“”;
for(i=0;i<xml.length;i++)
{ text+=xml[i].childNodes[0].nodeValue+”<br>”; }
document.getElementById(“test”).innerHTML=text;
}
}
}
▼ 코드로 예시 확인▼
chap01-index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>javascript ajax</title>
</head>
<body>
<h1 align="center">javascript ajax</h1>
<h3>개요</h3>
<p>
AJAX는 대화형 웹 응용프로그램을 만들기 위한 웹 개발 기술이다.<br>
기존 웹 애플리케이션은 동기 요청을 사용하여 서버와 정보를 전송한다.<br>
폼 양식을 작성하고 제출을 누르면 서버의 새 정보가 있는 새 페이지로
이동한다는 의미이다.<br>
하지만 AJAX를 사용한다면 자바스크림트가 서버에 요청하여 결과를 해석하여
현재 화면을 업데이트 하게 된다.<br>
클라이언트는 이러한 화면 갱신 없이 데이터가 서버로 전송되었다는 사실을
알지 못해도 서버 데이터를 수신할 수 있게 된다.<br>
AJAX는 서버 소프트웨어와는 별개의 독립적인 웹 브라우저 기술이며 기술
자체로는 프론트엔드로 분류가 된다.<br>
하지만 서버 전송 이후 back-end와 연동 되기 때문에 back-end와 혼동할
수 있다.<br>
자바스크립트는 서버와 비동기 상호작용을 수행하기 위한 XMLHttpRequest
객체를 이용한다.<br>
AJAX의 장단점<br>
장점<br>
1. 웹 페이지의 속도 향상 (전체 갱신이 아닌 필요한 데이터만 받아서
처리하기에 동기 방식보다 속도가 빠르다.) <br>
2. 서버에서 데이터만 전송하면 되므로 응답에 대한 코드 작성 양이 줄게 된다. <br>
3. 기존 웹에서 불가능했던 다양한 기능을 가능하게 한다. (무한 스크롤,
아이디 중복확인 등) <br>
<br>
단점<br>
1. 연속적으로 데이터를 요청하면 서버 부하를 증가시킬 수 있다.<br>
2. AJAX를 쓸 수 없는 브라우저에 대한 이슈가 있다.<br>
</p>
<h3>simple string ajax</h3>
<input type="text" name="name" id="param">
<button onclick="sendName();">서버로 전송</button>
<br>
<p id="result"></p>
<script>
function sendName(){
/* HttpRequest를 전송할 수 있는 객체를 생성한다.
지역 변수로 작성하는 것이 좋다. */
const httpRequest = new XMLHttpRequest();
const serverAddress = "/chap01/javascript";
httpRequest.onreadystatechange = function(){
/* 서버의 응답에 따른 로직을 여기 작성한다. */
if(httpRequest.readyState === XMLHttpRequest.DONE) {
/*
0 : request가 초기화 되지 않음
1 : 서버와 연결이 성사 됨
2 : 서버가 request를 받음
3 : request 요청을 처리하는 중
4 : request에 대한 처리가 끝났으며 응답할 준비가 완료 됨(DONE)
*/
if(httpRequest.status === 200) {
/* 응답 상태가 성공인 경우 */
document.getElementById('result').innerText
= httpRequest.responseText;
} else {
/* 요구를 처리하는 과정에서 문제가 발생 되었음
404 or 500에 대한 처리를 주로 함 */
document.getElementById('result').innerText
= '요청 응답에 실패하였습니다.';
}
}
};
let name = document.getElementById('param').value;
/* 요청 방식, 요청 url, 비동기 방식 사용 여부(true 기본값) */
httpRequest.open('GET', serverAddress + '?name=' + name);
httpRequest.send();
/* 지원 브라우저 여부나 이 외에도 다양하게 신경써서 처리하야 하는 것들이 많다.
그래서 직접 javascript를 이용한다기 보다는 jquery를 이용하는 편이다.
*/
}
</script>
</body>
</html>
<c:set
var="now"
value="<%= new java.util.Date() %>"/>
<fmt:timeZone value="America/New_York">
뉴욕 : <fmt:formatDate value="${ now }" type="both" dateStyle="full" timeStyle="full"/>
</fmt:timeZone>
<br>
<fmt:timeZone value="Europe/London">
런던 : <fmt:formatDate value="${ now }" type="both" dateStyle="full" timeStyle="full"/>
</fmt:timeZone>
<fmt:setTimeZone>
fmt:timeZone과 동일하나, 시작과 끝 태그에 영향을 미치는 것이 아닌, 선언한 이후의 모든 태그에 영향을 미친다.
사용 예
<c:set var="now" value="<%= new java.util.Date() %>"/>
<fmt:setTimeZone value="America/New_York" />
뉴욕 : <fmt:formatDate value="${ now }" type="both" />
<br>
<fmt:setTimeZone value="Europe/London" />
런던 : <fmt:formatDate value="${ now }" type="both" />
<fmt:formatNumber>
표현하고자 하는 숫자의 포맷을 통화 기호, ‘ , ’ 표시, %표시 등 원하는 쓰임에 맞게 지정할 수 있다.
사용 예
<p> 포맷 방식 세자리 구분 : <fmt:formatNumber value=“${number}”
type=“number” groupingUsed =“true” /></p> <!–- 12,300.12 -->
<p> 포맷 방식 통화 기호 : <fmt:formatNumber value=“${number}”
type=“currency” /></p> <!–- \12,300 -->
<p> 포맷 방식 백분율 : <fmt:formatNumber value=“${number}”
type=“percent” /></p> <!–- 012% -->
<fmt:formatNumber> 속성 정리
<fmt:formatNumber>
maxIntegerDigits 및 minIntegerDigits의 속성으로 표시하고자 하는 수의 단위를 표현할 수 있다.
숫자가 지정한 최대값을 초과할 경우 해당 자릿수 만큼만 표시된다.
사용 예
<fmt : formatNumber>
minFractionalDigits 및 maxFractionalDigits의 속성은 소수 자릿수를 지정할 수 있으며, 숫자가 최소 자릿수를 초과 할 시 자동 반올림이 된다.
패턴 속성을 사용하여 숫자 포맷 방법을 지정할 수 있다.
사용 예
<fmt:parseNumber>
특정 문자열을 값으로 받아 원하는 방식의 숫자 표현으로 변환 시킨다.
사용 예
<c:set var = "balance" value = "123000.123" />
<fmt:parseNumber var = "i" type = "number" value = "${balance}" />
<p>숫자 변환 테스트 1 : ${i}</p> <!-- 123000.123 -->
<fmt:parseNumber var = "i" integerOnly = "true" type = "number" value = "${balance}" />
<p>숫자 변환 테스트 2 : ${i}</p> <!-- 123000 -->
<fmt:parseNumber> 속성 정리
<fmt:formatDate>
날짜나 시간의 포맷방식을 지정하여 화면에 보여줄 때 사용한다.
value 속성으로는 java.util.Date() 객체를 사용해야 한다.
type 지정 방식에 따라 날짜, 시간, 둘 모두를 표시할 수 있고,
dateStyle, timeStyle 속성으로 보여줄 포맷의 표기 방식을 설정할 수 있다.
사용 문법
<fmt:formatDate> 속성 정리
Date Style 별 표현 방식
Time Style 별 표현 방식
<fmt:formatDate> 사용 예
<fmt:formatDate type="time" value="${Date}" />
<br> 오전 1:01:00
<fmt:formatDate type="date" value="${Date}" />
<br> 2018. 1. 01
<fmt:formatDate type="both" value="${Date}" />
<br> 2018. 1. 01 오전 1:01:00
<fmt:formatDate type="both" dateStyle="short" timeStyle="short" value="${Date}" />
<br> 18. 1. 01 오전 1:01
<fmt:formatDate type="both" dateStyle="medium" timeStyle="medium" value="${Date}" />
<br> 2018. 1. 01 오전 1:01:00
<fmt:formatDate type="both" dateStyle="long" timeStyle="long" value="${Date}" />
<br> 2018년 1월 1일 (월) 오전 1시 1분 00초
<fmt:parseDate>
문자열로 표시된 날짜 및 시간 값을 java.util.Date로 변환하여 화면에 표시할 때 사용한다
사용 예
<fmt:parseDate> 속성 정리
JSTL Function
JSTL Function 종류
JSTL Function
문자열 처리에 관한 메소드들을 EL 형식에서 사용할 수 있게 제공하는 라이브러리
다른 JSTL 태그들과는 다르게 ${fn:메소드명(문자열)} 의 형식으로 EL 태그에 직접 대입하여 사용한다.
선언 방식
예시
<c:set var = "theString" value = "I am a test String"/>
<c:if test = "${fn:contains(theString, 'test')}">
<p>Found test string<p>
</c:if>