JAVA-WEB January 02, 2021

JSP-09 AJAX 실전 (2)

Words count 18k Reading time 16 mins.

AJAX 실전 (2)

AJAX를 사용하기 위한 설정

My Batis의 DBService.java 객체 생성

sqlmap-config.xml, member.xml 설정

mybatis/config/DBService.java

package mybatis.config;

import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class DBService {

    // DBService: SqlSessionFactory 만들어서 반환하는 클래스

    // 필드
    private SqlSessionFactory factory;

    // 생성자: Singleton
    private DBService() {
        try {
            String resource = "mybatis/config/sqlmap-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            factory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private static DBService service = new DBService();
    public static DBService getInstance() {
        return service;
    }

    // 메소드
    public SqlSessionFactory getFactory() {
        return factory;
    }

}

sqlmap-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration 
PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-config.dtd" >

<configuration>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
                <property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
                <property name="username" value="spring"/>
                <property name="password" value="oracle"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="mybatis/mapper/member.xml"/>
    </mappers>

</configuration>

mapper.xml(member)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper 
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >

<mapper namespace="mybatis.mapper.member">
</mapper>

DataBase를 준비한다.

db/black.sql

DROP TABLE BLACK;
CREATE TABLE BLACK
(
    NAME VARCHAR2(100),
    AGE NUMBER,
    GENDER VARCHAR2(10),
    PHONE VARCHAR2(100),
    ADDRESS VARCHAR2(100)
);

INSERT INTO BLACK VALUES ('에밀리', 20, '여', '010-1111-1111', '서울');
INSERT INTO BLACK VALUES ('제임스', 21, '남', '010-2222-1111', '독도');
INSERT INTO BLACK VALUES ('앨리스', 22, '여', '010-3333-1111', '충청');
INSERT INTO BLACK VALUES ('데이빗', 23, '남', '010-4444-1111', '강원');
INSERT INTO BLACK VALUES ('아만다', 24, '여', '010-5555-1111', '제주');

Dto 만들기

dto/BlackDto.java

package dto;

public class BlackDto {

    private String name;
    private int age;
    private String gender;
    private String phone;
    private String address;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }

}

Dao 만들기

dao/BlackDao.java

package dao;

import org.apache.ibatis.session.SqlSessionFactory;

import mybatis.config.DBService;

public class BlackDao {

    // 필드: SqlSessionFactory
    // 모든 메소드는 factory에서 SqlSession을 생성하고
    // SqlSession으로 DB 처리를 한다.

    private SqlSessionFactory factory;

    // Dao는 항상 Singleton 처리한다.
    private BlackDao() {
        factory = DBService.getInstance().getFactory();
    }
    private static BlackDao blackDao = new BlackDao();
    public static BlackDao getInstance() {
        return blackDao;
    }


    // DB처리 메소드

}

Common 에 PathNRedirect 만들기

PathNRedirect.java

package common;

public class PathNRedirect {

    private String path;
    private boolean isRedirect;

    public String getPath() {
        return path;
    }
    public void setPath(String path) {
        this.path = path;
    }
    public boolean isRedirect() {
        return isRedirect;
    }
    public void setRedirect(boolean isRedirect) {
        this.isRedirect = isRedirect;
    }

}

Command 만들기

BlackCommand.java


package command;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import common.PathNRedirect;

public interface BlackCommand {

    /* 일반 Command */
    // public PathNRedirect execute(HttpServletRequest request, HttpServletResponse response);

    /* AJAX Command */
    // 요청한 JSP로 값을 반환하므로 path, redirect/forward가 필요 없다.
    // 반환 값이 실제 데이터이다.
    // 모든 반환 값은 String 타입으로 반환한다.
    public String execute(HttpServletRequest request, HttpServletResponse response);

}

BlackJsonCommand.java

package command;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

import dao.BlackDao;
import dto.BlackDto;

public class BlackJSONCommand implements BlackCommand {

    @Override
    public String execute(HttpServletRequest request, HttpServletResponse response) {

        /* 동작 확인용(DB를 사용 안 함) */
        /*
        JSONObject obj = new JSONObject();    // simple-json-1.1.1.jar(lib)
        obj.put("name","james");
        obj.put("age", 20);
        obj.put("gender","여");
        obj.put("phone","010-1111-1111");
        obj.put("address","속초");

        return obj.toJSONString();
        */

        /* DB에 들어가 데이터 가져오기 */
        List<BlackDto> list = BlackDao.getInstance().list();

        // list를 JSON으로 만들기
        // JSONObject를 BlackDto로 보면 되기 때문에
        // list는 JSONArray로 보면 된다.
        JSONArray jsonArray = new JSONArray();

        for (BlackDto blackDto : list) {
            JSONObject obj = new JSONObject();
            obj.put("name", blackDto.getName());
            obj.put("age", blackDto.getAge());
            obj.put("gender", blackDto.getGender());
            obj.put("phone", blackDto.getPhone());
            obj.put("address", blackDto.getAddress());

            jsonArray.add(obj);    // JSONArray는 ArrayList처럼 사용한다.
        }
        return jsonArray.toJSONString();
    }

}

BlackStringCommand.java

package command;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import dao.BlackDao;
import dto.BlackDto;

public class BlackStringCommand implements BlackCommand {

    @Override
    public String execute(HttpServletRequest request, HttpServletResponse response) {
        // DB 사용 안 하고 출력 
        // return "<tr><td colspan=\"5\">AJAX통신결과</td></tr>";

        List<BlackDto> list = BlackDao.getInstance().list();
        String result = "";
        for (BlackDto blackDto : list) {
            result += "<tr>";
            result += "<td>" + blackDto.getName() + "</td>";
            result += "<td>" + blackDto.getAge() + "</td>";
            result += "<td>" + blackDto.getGender() + "</td>";
            result += "<td>" + blackDto.getPhone() + "</td>";
            result += "<td>" + blackDto.getAddress() + "</td>";
            result += "</tr>";
        }
        return result;
    }

}

Controller 만들기

BlackController.java

package controller;

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 command.BlackCommand;
import command.BlackJSONCommand;
import command.BlackStringCommand;

@WebServlet("*.black")
public class BlackController extends HttpServlet {
    private static final long serialVersionUID = 1L;
    public BlackController() {
        super();
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        request.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=UTF-8");

        String requestURI = request.getRequestURI();
        String contextPath = request.getContextPath();
        String cmd = requestURI.substring(contextPath.length());
        /*
            AJAX를 처리하는 Controller는 PathNRedirect가 필요하지 않다.
            PathNRedirect pathNRedirect = null;

            AJAX는 실제 데이터를 String 타입으로 반환하므로  String result가 필요하다.
        */
        String result = null;

        BlackCommand command = null;

        switch (cmd) {

        case "/getString.black":
            command = new BlackStringCommand();
            result = command.execute(request, response);
            break;

        case "/getJSON.black":
            command = new BlackJSONCommand();
            result = command.execute(request, response);
            break;
        }
        /* AJAX를 처리하는 Controller는 PathNRedirect가 필요하지 않다.
        String path = pathNRedirect.getPath();
        boolean isRedirect = pathNRedirect.isRedirect();

        if (isRedirect) {
            response.sendRedirect(path);
        } else {
            request.getRequestDispatcher(path).forward(request, response);
        }
        */

        // 반환 값(결과)을 요청한 곳으로 보내면 된다.
        // 응답
        PrintWriter out = response.getWriter();
        out.println(result);    // AJAX 통신이 성공하면 succes: function(data) {...}의 data로 result가 전달된다.
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

화면구성(프론트)

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- AJAX 사용을 위한 script -->
<script 
    src="https://code.jquery.com/jquery-3.5.1.min.js" 
    integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" 
    crossorigin="anonymous">
</script>
<script type="text/javascript">

    // 페이지 로드 이벤트 (페이지 다 읽어서 id 먼저 파악하기)
    // 1. $(document).ready(function(){});
    // 2. $(funtion(){});
    $(document).ready(function(){
        fn_getString();
        fn_getJSON();
    });

    // 처리 함수
    function fn_getString() {

        // id=btn1을 클릭하면 function(){} 실행
        // 1. $('#btn1').click(function(){});
        // 2. $('body').on('click', '#btn1', function(){});

        // 동작 확인 예제
        /*
        $('#btn1').click(function(){
            var str = '<tr><td colspan="5">동작확인 예제입니다.</td></tr>';
            $('#content').append(str);    // 기존 요소를 살리고 추가    
            // $('#content').html(str);    // 기존 요소를 지우고 추가
        });
        */

        $('#btn1').click(function(){

            $.ajax({
                url: '/17_AJAX/getString.black', // 서버에 요청, 요청 URL: BlackStringCommand를 호출한다.
                type: 'get', // 요청방식: get, post
                dataType: 'text',    // 받는(응답) 결과의 타입
                success: function(responseText) {    // responseText: BlackStringCommand의 반환 값이 저장된다.
                    $('#content').empty();    // content 비우기
                    $('#content').append(responseText);
                },
                error: function() {
                    alert('AJAX 통신 실패');
                }
            });

        });

    }    // end fn_getString()

    function fn_getJSON() {
        $('#btn2').click(function() {
            $.ajax({
                url: '/17_AJAX/getJSON.black',
                type: 'get',
                dataType: 'JSON',  // 받는(응답) 결과의 타입(실제로는 JSON을 String으로 바꾼 결과를 받아온다.)
                success: function(responseJSONArray) {
                    var result = '';

                    $.each(responseJSONArray, function(index, responseJSON) {
                        result += '<tr>';
                        result += '<td>' + responseJSON.name + '</td>';
                        result += '<td>' + responseJSON.age + '</td>';
                        result += '<td>' + responseJSON.gender + '</td>';
                        result += '<td>' + responseJSON.phone + '</td>';
                        result += '<td>' + responseJSON.address + '</td>';
                        result += '</tr>';
                    }); 
                        $('#content').empty();
                        $('#content').append(result);
                },
                error: function() {
                    alert('AJAX 통신 실패');
                }
            })
        });
    }


</script>
</head>
<body>

    <h3>AJAX 통신버튼</h3>
    <input type="button" value="문자열" id="btn1" />
    <input type="button" value="JSON" id="btn2" />

    <h3>Black 테이블</h3>
    <table border="1">
        <thead>
            <tr>
                <td>이름</td>
                <td>나이</td>
                <td>성별</td>
                <td>전화</td>
                <td>주소</td>
            </tr>
        </thead>
        <tbody id="content">

        </tbody>
    </table>
</body>
</html>

결과화면

문자열을 눌렀을때

JSON 버튼 눌렀을때 각각 밑에가뜸

0%