주소 검색 구현

심야·2023년 9월 4일
0

웹 개발

목록 보기
46/46
post-custom-banner

모의 해킹에 사용할 게시판 회원가입 주소 검색 구현


search.js

검색할 주소를 입력 후 검색 버튼을 클릭하면 fetch 함수가 컨트롤러에 전달한다.
주소가 존재하면 주소 버튼을 생성해 선택을 유도한다.

function inputHTML() {
    const buttons = document.querySelectorAll("#search-contents button");
    // input 태그 선택
    const input = document.querySelector("#address");
    // 각 버튼에 클릭 이벤트 리스너 등록
    buttons.forEach((button) => {
        button.addEventListener("click", () => {
            // 클릭된 버튼의 innerHTML 값을 가져와 input 태그에 반영
            input.value = button.innerHTML;
        });
    });
}

function search_form() {
    // form
    const form = document.getElementById("search-form");

    form.addEventListener("submit", (event) => {
        event.preventDefault(); // 기본 제출 동작 막기
        const formData = new FormData(form);
        const address = formData.get("address");
        const encodedURL = encodeURIComponent(address);
        const url = "/hackthebox/searchprocess?address=" + encodedURL;
        fetch(url, {
            method: "GET",
        })
            .then((response) => {
                if (!response.ok) {
                    throw new Error("Network response was not ok");
                }
                return response.json();
            })
            .then((result) => {
                if (result.search === "success") {
                    const searchContents = document.getElementById("search-contents");
                    const dialog = document.getElementById("modal-dialog");
                    const count = Object.values(result.address).length; // 생성할 버튼 갯수
                    const button_check = document.querySelectorAll(".check-button");
                    if (button_check.length > 0) {
                        // 이미 버튼이 존재하면 기존 버튼 삭제
                        for (let i = 0; i < button_check.length; i++) {
                            button_check[i].parentNode.removeChild(button_check[i]);
                        }
                    }
                    for (let i = 0; i < count; i++) {
                        const button = document.createElement("button");
                        button.classList.add("btn", "btn-success", "btn-block", "mt-3", "check-button");
                        button.dataset.dismiss = "modal";
                        button.dataset.toggle = "modal";

                        if (i === 0) {
                            button.innerHTML = result.address[i];
                        } else if (i === count - 1) {
                            button.innerHTML = result.address[i];
                        } else if (i % 2 === 0) {
                            button.innerHTML = result.address[i];
                        } else if (i % 2 !== 0) {
                            button.innerHTML = result.address[i];
                        }
                        searchContents.appendChild(button);
                    }
                    if (count > 5) {
                        dialog.style.marginTop = "2%"; // modal 위치 조정
                    } else {
                        dialog.style.marginTop = "-11%"; // modal 위치 조정
                    }
                    inputHTML();
                } else if (result.search === "fail") {
                    alert("검색 결과가 없습니다.");
                }
            })
            .catch((error) => {
                console.error(error);
                alert('"강남구 선릉로 10길"과 같은 도로명 주소로 검색해주세요.');
            });
    });
}
search_form();

SearchAddressController

전달받은 주소를 dao의 searchaddress 메소드에 전달한다. 주소가 존재하면 success를 응답하고 그렇지 않다면 fail을 응답한다.

@WebServlet("/searchprocess")
public class SearchAddressController extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        JSONObject jsonObj;
        JSONArray jsonArr;
        String address = req.getParameter("address");

        UserDAO dao = new UserDAO();
        ArrayList<AddressDTO> vo_list = dao.SearchAddress(address);

        if (vo_list.size() != 0) {
            jsonObj = new JSONObject();
            jsonArr = new JSONArray();
            HashSet<String> set = new HashSet<>();

            for (int i = 0; i < vo_list.size(); i++) {
                AddressDTO vo = vo_list.get(i);
                String result = vo.getSido() + " " + vo.getSigungu() + " " + vo.getDoro_name() + " "
                        + vo.getSigungu_building_name();
                if (!set.add(result)) {
                    continue;
                }
            }

            Iterator<String> it = set.iterator();
            while (it.hasNext()) {
                String element = it.next();
                jsonArr.put(element);
            }
            jsonObj.put("search", "success");
            jsonObj.put("address", jsonArr);
            resp.setContentType("application/json");
            resp.setCharacterEncoding("UTF-8");
            PrintWriter out = resp.getWriter();
            out.print(jsonObj.toString());
            out.flush();
        } else {
            jsonObj = new JSONObject();
            jsonObj.put("search", "fail");
            resp.setContentType("application/json");
            resp.setCharacterEncoding("UTF-8");
            PrintWriter out = resp.getWriter();
            out.print(jsonObj.toString());
            out.flush();
        }
    }
}

UserDAO

SearchAddress

시군구, 도로명, 빌딩 이름 기준으로 분할한 주소를 SQL 쿼리로 질의한다. 질의 결과를 리스트에 담아 컨트롤러에 반환한다.

    public ArrayList<AddressDTO> SearchAddress(String address) {
        ArrayList<AddressDTO> vo_list = new ArrayList<>();
        String sido = null;
        String sigungu = null;
        String doro_name = null;
        String sigungu_building_name = null;
        String query = null;

        ArrayList<String> splitAddress = SplitAddress(address); // " " 기준으로 문자열 자르기

        sigungu = (String) splitAddress.get(0);
        doro_name = (String) splitAddress.get(1);

        if (splitAddress.size() == 3) {
            sigungu_building_name = (String) splitAddress.get(2);
            query = "SELECT SIDO, SIGUNGU, DORO_NAME, SIGUNGU_BUILDING_NAME FROM postcode WHERE SIGUNGU='"
                    + sigungu + "' AND DORO_NAME='" + doro_name + "' AND SIGUNGU_BUILDING_NAME='"
                    + sigungu_building_name + "'";
        } else {
            query = "SELECT SIDO, SIGUNGU, DORO_NAME, SIGUNGU_BUILDING_NAME FROM postcode WHERE SIGUNGU='"
                    + sigungu + "' AND DORO_NAME='" + doro_name + "'";
        }
        conn = driver.getConnect();
        try {
            stmt = conn.createStatement();
            rs = stmt.executeQuery(query);

            while (rs.next()) {
                AddressDTO vo = new AddressDTO();
                sido = rs.getString("sido");
                sigungu = rs.getString("sigungu");
                doro_name = rs.getString("doro_name");
                sigungu_building_name = rs.getString("sigungu_building_name");

                vo.setSido(sido);
                vo.setSigungu(sigungu);
                vo.setDoro_name(doro_name);
                if (sigungu_building_name == null) {
                    vo.setSigungu_building_name(" ");
                } else {
                    vo.setSigungu_building_name(sigungu_building_name);
                }
                vo_list.add(vo);
            }
        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            driver.dbClose(rs, stmt, conn);
        }
        return vo_list;
    }

SplitAddress

입력받은 주소를 시군구, 도로명, 빌딩 이름 기준으로 분리한다.

private ArrayList<String> SplitAddress(String address) {
        String tmp = null;
        String[] result;
        String sigungu = null;
        String doro_name = null;
        String sigungu_building_name = null;
        ArrayList<String> list;

        if (address.contains("로 ")) {
            tmp = address.replace("로 ", "로");
            result = tmp.split(" ");
        } else {
            result = address.split(" ");
        }

        sigungu = result[0];
        doro_name = result[1];
        list = new ArrayList<String>();
        list.add(sigungu);
        list.add(doro_name);

        if (result.length == 3) {
            sigungu_building_name = result[2];
            list.add(sigungu_building_name);
        }
        return list;
    }

출처

https://github.com/simyat/Vulnerable-Board-Web-Application

profile
하루하루 성실하게, 인생 전체는 되는대로.
post-custom-banner

0개의 댓글