CAFE

함께풀어보기

Re: 연습문제 : 구구단 구현해보기_윤희상,유해준,김준서,조병찬,오진석

작성자오진석|작성시간26.06.18|조회수21 목록 댓글 0

//GugudanServlet.java

package exam;

 

import jakarta.servlet.ServletException;

import jakarta.servlet.annotation.WebServlet;

import jakarta.servlet.http.HttpServlet;

import jakarta.servlet.http.HttpServletRequest;

import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

 

/**

* [구구단 처리 서블릿]

* 사용자가 입력한 기준 단(dan)과 출력 개수(limit)를 바탕으로

* 화면에 표시할 시작 단(start)과 끝 단(end)을 계산하여 JSP로 전달하는 컨트롤러입니다.

*/

@WebServlet("/gugudanServlet")

public class GugudanServlet extends HttpServlet {

// 객체 직렬화(Serialization)를 위한 고유 버전 ID (클래스 구조 변경 시 검증용)

private static final long serialVersionUID = 1L;

 

/**

* HTTP POST 요청을 처리하는 메서드입니다.

* 폼(Form) 전송 데이터나 비동기 POST 요청이 들어오면 호출됩니다.

*/

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

setCorsHeaders(response); // 교차 출처 자원 공유(CORS) 문제를 방지하기 위해 응답 헤더 설정

doProcess(request, response); // 실제 구구단 로직을 처리하는 공통 메서드로 실행 위임

}

 

/**

* HTTP OPTIONS 요청을 처리하는 메서드입니다.

* 브라우저가 실제 요청(POST 등)을 보내기 전, 서버의 권한을 확인하는 '예비 요청(Preflight)'을 처리합니다.

*/

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

setCorsHeaders(response); // 예비 요청에도 CORS 승인 헤더가 반드시 필요함

doProcess(request, response); // 공통 로직 실행 위임

}

 

/**

* 모든 HTTP 메서드(POST, OPTIONS 등)의 비즈니스 로직을 통합 처리하는 공통 메서드입니다.

*/

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

 

// 1. 요청 파라미터 추출 및 데이터 타입 변환 (String -> int)

// 클라이언트가 보낸 문자열 데이터를 정수형(int)으로 형변환하여 변수에 저장합니다.

int limit = Integer.parseInt(request.getParameter("limit")); // 화면에 보여줄 총 단의 개수 (범위 제한 값)

int dan = Integer.parseInt(request.getParameter("dan")); // 사용자가 선택한 핵심 기준 단

 

// 2. 구구단 출력 범위 계산 알고리즘

// 기준 단(dan)을 중심으로 좌우 대칭이 되도록 시작 단과 끝 단을 산출합니다.

// 예: dan=5, limit=5 일 때 -> limit/2 = 2 이므로

// start = 5 - 2 = 3단 / end = 5 + 2 = 7단 -> 총 5개 단(3,4,5,6,7) 출력

int start = dan - (limit / 2); // 시작할 구구단 번호 계산

int end = dan + (limit / 2); // 끝날 구구단 번호 계산

 

// 3. JSP(뷰) 화면으로 전달할 데이터를 Request 영역에 저장 (수명: 1개의 HTTP 요청 안에서만 유효)

request.setAttribute("dan", dan); // 사용자가 선택한 기준 단 저장

request.setAttribute("start", start); // 계산된 시작 단 저장

request.setAttribute("end", end); // 계산된 끝 단 저장

request.setAttribute("color", request.getParameter("color")); // 사용자가 선택한 강조 배경색 스킨 저장

 

// 4. 서버 내부 포워딩 (Forward)

// 제어권을 보이지 않게 '/WEB-INF/views/gugudan.jsp'로 넘깁니다.

// 사용자의 브라우저 URL은 변경되지 않으며, 위에서 request에 담은 데이터들을 JSP에서 그대로 꺼내 쓸 수 있습니다.

// WEB-INF 폴더 내부에 jsp를 두어 사용자가 URL을 통해 JSP 파일에 직접 접근하는 것을 차단(보안)합니다.

request.getRequestDispatcher("/WEB-INF/views/gugudan.jsp").forward(request, response);

}

/**

* [CORS(Cross-Origin Resource Sharing) 헤더 설정 메서드]

* 서로 다른 도메인이나 포트(예: React, Vue 등 다른 서버)에서 이 서블릿으로

* API 요청을 보낼 때, 브라우저의 보안 정책으로 인해 차단되는 현상을 방지합니다.

*/

private void setCorsHeaders(HttpServletResponse response) {

// 모든 도메인(*)에서의 접근을 허용합니다. (실무에서는 특정 도메인만 지정하는 것이 안전합니다)

response.setHeader("Access-Control-Allow-Origin", "*");

 

// 허용할 HTTP 메서드 방식을 정의합니다. (조회용 GET, 데이터 전송용 POST, 예비 요청 OPTIONS)

response.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS");

 

// 요청 본문(Body)에 포함될 수 있는 허용 헤더 타입을 지정합니다. (예: application/json 등)

response.setHeader("Access-Control-Allow-Headers", "Content-Type");

}

}

//guguform.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>guguForm</title>

</head>

<body>

<div style="width: 450px; margin: auto">

<h2 style="text-align: center;">구구단 설정</h2>

<form action="gugudanServlet" method="post" style="width: 300px; margin: auto;">

<p>

<label>단 :</label>

<input type="number" name="dan" required>

</p>

<p>

<label>범위:</label>

<select name="limit">

<option value="3">3</option>

<option value="5">5</option>

<option value="7">7</option>

<option value="9">9</option>

</select>

</p>

<p>

<label>색상:</label>

<input type="color" name="color" value="#ff0000">

</p>

<p style="text-align: center;">

<input type="submit" value="구구단 출력">

</p>

</form>

</div>

</body>

</html>

//gugudan.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"

pageEncoding="UTF-8"%>

<%@taglib prefix="c" uri="jakarta.tags.core"%>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>gugudan.jsp</title>

<style>

table {

margin: 20px auto;

border-collapse: collapse;

}

 

td {

border: 1px solid #999;

padding: 8px;

text-align: center;

}

 

th {

background-color: #f0f0f0;

padding: 8px;

}

</style>

</head>

<body>

<div style="width: 900px; margin: auto">

<table>

<h2>start : ${start}, end : ${end}</h2>

<c:forEach var="j" begin="0" end="9">

<tr>

<c:forEach var="i" begin="${start}" end="${end}">

<c:choose>

<%-- 특정 단(dan)과 일치할 때: 지정된 배경색 적용 --%>

<c:when test="${dan == i}">

<td style="border: 1px solid; background-color: ${color};">

<c:choose>

<c:when test="${j == 0}">

${i}

</c:when>

<c:otherwise>

${i} x ${j} = ${j * i}

</c:otherwise>

</c:choose>

</td>

</c:when>

 

<%-- 일치하지 않을 때: 흰색 배경 적용 --%>

<c:otherwise>

<td style="border: 1px solid; background-color: white;">

<c:choose>

<c:when test="${j == 0}">

${i}

</c:when>

<c:otherwise>

${i} x ${j} = ${j * i}

</c:otherwise>

</c:choose>

</td>

</c:otherwise>

</c:choose>

</c:forEach>

</tr>

</c:forEach>

</table>

 

</div>

</body>

</html>

다음검색
현재 게시글 추가 기능 열기

댓글

댓글 리스트
맨위로

카페 검색

카페 검색어 입력폼