풀스택 백엔드 2026.06.10

syyu21b·2026년 6월 10일

풀스택 - 백엔드

목록 보기
27/49
post-thumbnail

[SECTION 03. JSP에서 Java 코드를 사용하자 — 스크립틀릿]

스크립틀릿 패턴 완전 정복

패턴 1: 변수 선언과 출력

<%
    String title = "스프링 입문";
    int price = 50000;
    boolean isSale = true;
%>

<h2><%= title %></h2>
<p>가격: <%= price %>원</p>
<p>할인 중: <%= isSale %></p>

패턴 2: 조건문 (if / else)

<% %> 블록은 여러 개로 쪼개도 됩니다. HTML을 사이에 끼워 넣을 수 있어요.

<%
    int score = 78;
%>

<% if (score >= 90) { %>
    <p style="color: blue;">A등급 — 우수합니다!</p>
<% } else if (score >= 70) { %>
    <p style="color: green;">B등급 — 양호합니다.</p>
<% } else { %>
    <p style="color: red;">C등급 — 분발하세요.</p>
<% } %>

핵심 원리: <% if (score >= 90) { %><% } %> 사이의 HTML은 조건이 참일 때만 출력됩니다. {} 는 짝을 맞춰야 합니다!


패턴 3: 반복문 (for)

<%
    String[] fruits = {"사과", "바나나", "포도", "오렌지"};
%>

<ul>
    <% for (String fruit : fruits) { %>
        <li><%= fruit %></li>
    <% } %>
</ul>

출력 결과:

<ul>
    <li>사과</li>
    <li>바나나</li>
    <li>포도</li>
    <li>오렌지</li>
</ul>

패턴 4: 반복문 + 조건문 조합

인덱스를 활용하거나 조건에 따라 다른 스타일 적용하기:

<%
    String[] names = {"홍길동", "김철수", "이영희", "박민준", "최수진"};
%>

<table border="1">
    <tr><th>번호</th><th>이름</th><th>비고</th></tr>

    <% for (int i = 0; i < names.length; i++) { %>
    <tr style="background-color: <%= (i % 2 == 0) ? "#ffffff" : "#f2f2f2" %>">
        <td><%= i + 1 %></td>
        <td><%= names[i] %></td>
        <td>
            <% if (i == 0) { %>
                1등
            <% } else { %>
                -
            <% } %>
        </td>
    </tr>
    <% } %>
</table>

패턴 5: request에서 데이터 꺼내기

서블릿이 request.setAttribute()로 저장한 데이터를 JSP에서 꺼낼 때:

<%
    // Object로 반환되므로 반드시 형변환(캐스팅) 필요
    String username = (String) request.getAttribute("username");
    Integer age     = (Integer) request.getAttribute("age");       // int가 아닌 Integer!
    List<String> hobbies = (List<String>) request.getAttribute("hobbies");
%>

<p>이름: <%= username %></p>
<p>나이: <%= age %>세</p>

<ul>
    <% for (String hobby : hobbies) { %>
        <li><%= hobby %></li>
    <% } %>
</ul>

자주 하는 실수

<%
    int age = (int) request.getAttribute("age");     // ❌ Cannot cast Object to int
    Integer age = (Integer) request.getAttribute("age"); // ✅ 올바른 방법
%>

패턴 6: null 체크

getAttribute()는 값이 없으면 null을 반환합니다. null 처리를 잊으면 화면이 깨집니다.

<%
    String errorMsg = (String) request.getAttribute("error");
%>

<%-- null 체크 후 출력 --%>
<% if (errorMsg != null) { %>
    <p style="color: red;">❌ <%= errorMsg %></p>
<% } %>

<%-- 삼항 연산자로 간결하게 --%>
<p><%= (username != null) ? username : "비회원" %></p>

[SECTION 04. 모든 요청을 한 곳으로 — 프론트 컨트롤러 패턴]

프론트 컨트롤러 직접 만들기

프로젝트 구조

src/main/
├── java/com/example/
│   ├── front/
│   │   └── FrontController.java   ← 핵심! 모든 요청의 입구
│   └── model/
│       └── Member.java
└── webapp/
    └── WEB-INF/
        └── views/
            └── member/
                ├── list.jsp
                └── form.jsp

FrontController.java

package com.example.front;

import com.example.model.Member;

import javax.servlet.RequestDispatcher;
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 java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@WebServlet("/member/*")
public class FrontController extends HttpServlet {

    private List<Member> memberStore = new ArrayList<>();

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        process(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        process(req, resp);
    }

    private void process(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {

        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html");
        resp.setCharacterEncoding("UTF-8");

        String requestURI = req.getRequestURI();
        System.out.println("[FrontController] 요청 URI: " + requestURI);

        if (requestURI.equals("/member/list")) {
            memberList(req, resp);

        } else if (requestURI.equals("/member/new") && req.getMethod().equals("GET")) {
            memberForm(req, resp);

        } else if (requestURI.equals("/member/new") && req.getMethod().equals("POST")) {
            memberSave(req, resp);

        } else {
            resp.sendError(HttpServletResponse.SC_NOT_FOUND);
        }
    }

    private void memberList(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        req.setAttribute("members", memberStore);
        forward(req, resp, "/WEB-INF/views/member/list.jsp");
    }

    private void memberForm(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        forward(req, resp, "/WEB-INF/views/member/form.jsp");
    }

    private void memberSave(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        String name  = req.getParameter("name");
        String email = req.getParameter("email");

        if (name == null || name.trim().isEmpty()) {
            req.setAttribute("error", "이름을 입력해주세요.");
            forward(req, resp, "/WEB-INF/views/member/form.jsp");
            return;
        }

        memberStore.add(new Member(name, email, ""));
        resp.sendRedirect("/member/list");
    }

    private void forward(HttpServletRequest req, HttpServletResponse resp, String path)
            throws ServletException, IOException {
        RequestDispatcher dispatcher = req.getRequestDispatcher(path);
        dispatcher.forward(req, resp);
    }
}

Member.java

package com.example.model;

public class Member {

    private String name;
    private String email;
    private String password;

    public Member(String name, String email, String password) {
        this.name     = name;
        this.email    = email;
        this.password = password;
    }

    public String getName()     { return name; }
    public String getEmail()    { return email; }
    public String getPassword() { return password; }
}

list.jsp

src/main/webapp/WEB-INF/views/member/list.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ page import="java.util.List" %>
<%@ page import="com.example.model.Member" %>

<%
    List<Member> members = (List<Member>) request.getAttribute("members");
%>

<%= members %>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ page import="java.util.List" %>
<%@ page import="com.example.model.Member" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>회원 목록</title>
    <style>
        body { font-family: Arial, sans-serif; max-width: 500px; margin: 40px auto; }
        .member { padding: 12px; margin: 8px 0; background: #f5f5f5; border-radius: 6px; }
        a { display: inline-block; margin-bottom: 16px; padding: 8px 16px; background: #4CAF50; color: white; text-decoration: none; border-radius: 4px; }
    </style>
</head>
<body>

    <h2>회원 목록</h2>
    <a href="/member/new">+ 회원 추가</a>

    <%
        List<Member> members = (List<Member>) request.getAttribute("members");
    %>

    <% if (members == null || members.isEmpty()) { %>
        <p>등록된 회원이 없습니다.</p>
    <% } else { %>
        <p><strong><%= members.size() %></strong></p>
        <% for (Member m : members) { %>
        <div class="member">
            <strong><%= m.getName() %></strong> — <%= m.getEmail() %>
        </div>
        <% } %>
    <% } %>

</body>
</html>

form.jsp

src/main/webapp/WEB-INF/views/member/form.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>회원 가입</title>
    <style>
        body { font-family: Arial, sans-serif; max-width: 400px; margin: 40px auto; }
        input { width: 100%; padding: 8px; margin-top: 4px; box-sizing: border-box; }
        button { margin-top: 12px; padding: 10px 20px; background: #4CAF50; color: white; border: none; cursor: pointer; width: 100%; }
        .error { color: red; margin-bottom: 12px; }
    </style>
</head>
<body>

    <h2>회원 가입</h2>

    <% if (request.getAttribute("error") != null) { %>
        <p class="error">❌ <%= request.getAttribute("error") %></p>
    <% } %>

    <form action="/member/new" method="post">
        <label>이름 *<br>
            <input type="text" name="name">
        </label><br><br>
        <label>이메일<br>
            <input type="email" name="email">
        </label><br>
        <button type="submit">가입하기</button>
    </form>

    <br><a href="/member/list">← 목록으로</a>

</body>
</html>

섹션 정리

개념핵심 내용
프론트 컨트롤러모든 요청을 서블릿 하나가 받아서 URL에 따라 처리를 분기하는 패턴
@WebServlet("/*")모든 URL 요청을 이 서블릿이 받겠다는 선언
getRequestURI()현재 요청의 URL 경로를 가져오는 메서드
공통 처리 집중인코딩 설정 등 반복 코드를 한 곳에서 처리
DispatcherServlet스프링이 제공하는 프론트 컨트롤러. 우리가 만든 것의 완성형

0개의 댓글