나를 소개합니다

2025. 9. 8. 19:28·JAVA/Java 실습

📚 필수 과제

  • th:field, th:text 등의 문법을 통해 HTML 폼을 구성하고 서버에 데이터를 전송할 수 있음
  • Model을 통해 사용자 입력값을 View에 출력할 수 있음
  • 프로젝트의 구성도
Practical2_starter/
├── src/
│   └── main/
│       └── java/
│           └── kr.practical2_starter
│				├── IntroController.java
│				├── MbtiEmojiService.java
│				├── Person.java
│				└── Practical2StarterApplication.java
│
├── resources
│   └── templates
│ 		├── form.html
│		└── result.html

 

1. HTML 입력 폼 구성

더보기
더보기
  • Thymeleaf의 th:field를 사용해 이름, 나이, MBTI, 좋아하는 음식, 좋아하는 색상 항목을 입력받는 <form>을 만들어보세요.
  • 데이터는 POST 방식으로 전송되어야 합니다.

 

파일 구조는 기본적으로 제공된 예시 폴더 구조를 유지하여 진행 (추가 파일 생성 / 삭제는 없이 진행해야 함)

 

작업 방식은 Java 파일을 우선적으로 작업을 진행하고, HTML 작업을 진행하는 방향으로 작업해야 함 

 

그 이유로는 Thymeleaf 템플릿은 자바코드에서 내려준 Model 데이터가 있어야 렌더링 가능하기 때문

 

1. Java (모델/컨트롤러) → HTML

- Person 클래스 (폼 데이터 DTO) → IntroController (GET에서 new person()을 model에 넣어주기)

- 이렇게 하면 form.html에서 th:object="${person}"로 안전하게 시작 가능

+. DTO란? (Data Transfer Object)

ㄴ 데이터를 옮기기 위한 객체를 의미

ㄴ 데이터를 주고받을 때 쓰는 단순한 바구니 역할 클래스

 

2. 그 다음에 form.html에서 th:field 붙이고 action="@{/intro}" 지정

3. 마지막으로 result.html에서 th:text, th:style로 모델 값 출력

 

//Person.java

package kr.sparta.practical2_starter;

/*
 model
 */
public class Person { //클래스 선언
    private String name;
    private Integer age;
    private String mbti;
    private String favoriteFood;
    private String favoriteColor;

    public Person() {} //클래스 선언 이후 생성자 선언(초기화 방법에 대한 선언)

    public String getName() {return name;}
    public void setName(String name) {this.name = name;}

    public Integer getAge() {return age;}
    public void setAge(Integer age) {this.age = age;}

    public String getMbti() {return mbti;}
    public void setMbti(String mbti) {this.mbti = mbti;}

    public String getFavoriteFood() {return favoriteFood;}
    public void setFavoriteFood(String favoriteFood) {this.favoriteFood = favoriteFood;}

    public String getFavoriteColor() {return favoriteColor;}
    public void setFavoriteColor(String favoriteColor) {this.favoriteColor = favoriteColor;}
}

 

 

//form.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8">
    <title>자기소개 입력</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css">
    <style>
        body {
            font-family: 'Noto Sans KR', sans-serif;
        }
    </style>
</head>
<body>
    <h1> 📝나를 소개합니다. </h1>

//form 형태로 도메인/intro 요청이 서버로 진행됨, 전송방식을 POST로 지정하고 입력된 값들을 person이라는 모델 객체와 바인딩 시킴
    <form th:action="@{/intro}" method="post" th:object="${person}">
        <label>이름: <input type="text" th:field="*{name}" /></label><br>
        <label>나이: <input type="number" th:field="*{age}"></label><br>
        <label>MBTI: <input type="text" th:field="*{mbti}"></label><br>
        <label>좋아하는 음식: <input type="text" th:field="*{favoriteFood}"></label><br>
        <label>좋아하는 색상: <input type="text" th:field="*{favoriteColor}"></label><br>
        <button type="submit">제출</button>
    </form>
</body>
</html>

 

2. 서버에서 입력값 처리 및 모델 전달

더보기
더보기
  • @ModelAttribute로 폼 데이터를 받아서 Model에 담아 결과 페이지로 전달하세요.
  • 전달받은 데이터를 결과 페이지에서 th:text 로 출력해보세요. 
//IntroController.java

package kr.sparta.practical2_starter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;

/*
 Controller ?
 사용자의 요청을 처음으로 받아서
 어떤 작업을 해야 할지 판단하고** 그 작업을 Service에게 시키는 역할을 해요.
 */
@Controller
public class IntroController {

    @Autowired
    private MbtiEmojiService mbtiEmojiService;

    // 폼 보여주기
    @GetMapping("/")
    public String form(Model model) {
        model.addAttribute("person", new Person());
        return "form";
    }

    // 제출 처리
    @PostMapping("/intro")
    public String submit(@ModelAttribute("person")  Person person, Model model) {
        String emoji = mbtiEmojiService.emojiFor(person.getMbti());
        model.addAttribute("emoji", emoji);
        return "result";
    }
}

 

3. 한 줄 자기소개 출력

더보기
더보기
- 결과 페이지에 다음 형식으로 출력해보세요.

안녕하세요! 저는 20살이고 ENFP이며 마라탕을 좋아하고 노랑색을 좋아해요!

 

//result.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8">
    <title>자기소개 결과 화면</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css">
  <style>
    body {
      font-family: 'Noto Sans KR', sans-serif;
    }
  </style>
</head>

// th:text로 사용, th:style은 도전과제 진행을 위함
<body th:style="'background:'+ ${person.favoriteColor}">
<p th:text="|안녕하세요 저는 ${person.age}살이고 ${person.mbti} ${emoji}인 ${person.name}이에요. ${person.favoriteFood}를 좋아하고, ${person.favoriteColor} 색을 좋아해요!|"></p>    <a th:href="@{/}"> 다시 작성하기</a>
</body>
</html>

❤️‍🔥 도전 과제

1. 좋아하는 색상에 따라 배경색 적용하기

더보기
더보기
  • 입력 폼에서 사용자가 좋아하는 색상을 고르면, 결과 페이지의 <body> 배경색으로 적용되도록 구현해보세요.
  • th:style 을 사용해 CSS 스타일을 동적으로 적용해보세요.

 

form 형태로 제출하게 될 경우 정확한 색상의 고유값을 입력하거나, 선택하게 진행했어야 했음

이에 따라 select-option 형태로 입력받는 값을 한정지어 받게 진행하였고 그에 대한 value 값들을 적용시켜 body문에 색을 변화시켰음

 

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8">
    <title>자기소개 입력</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css">
    <style>
        body {
            font-family: 'Noto Sans KR', sans-serif;
        }
    </style>
</head>
<body>
    <h1> 📝나를 소개합니다. </h1>

    <form th:action="@{/intro}" method="post" th:object="${person}">
        <label>이름: <input type="text" th:field="*{name}" /></label><br>
        <label>나이: <input type="number" th:field="*{age}"></label><br>
        <label>MBTI: <input type="text" th:field="*{mbti}"></label><br>
        <label>좋아하는 음식: <input type="text" th:field="*{favoriteFood}"></label><br>
        <label>좋아하는 색상:
            <select th:field="*{favoriteColor}">
                <option value="red">빨강</option>
                <option value="citrus">주황</option>
                <option value="lightyellow">노랑</option>
                <option value="lightgreen">초록</option>
                <option value="lightblue">파랑</option>
                <option value="purple">보라</option>
                <option value="pink">분홍</option>
            </select>
        </label><br>
        <button type="submit" >제출</button>
    </form>
</body>
</html>

 

 

2. MBTI에 따라 이모지 출력하기

더보기
더보기
  • MBTI 입력값에 따라 대표 이모지를 매핑해서 결과 페이지에 함께 출력해보세요.
  • 아래 예시 Java 코드로 Map<String, String>을 만들어서 MBTI에 따른 이모지 매핑을 해보세요.
// 아래 코드를 그대로 MbtiEmojiService.java에 붙여넣어 사용하세요

public static final Map<String, String> MBTI_EMOJI_MAP = Map.ofEntries(
    Map.entry("ISTJ", "📘"), // 신중한 관리자 – 책
    Map.entry("ISFJ", "🛡️"), // 헌신적인 수호자 – 방패
    Map.entry("INFJ", "🔮"), // 통찰력 있는 조언자 – 수정구슬
    Map.entry("INTJ", "♟️"), // 전략적인 사색가 – 체스말

    Map.entry("ISTP", "🛠️"), // 논리적인 장인 – 공구
    Map.entry("ISFP", "🎨"), // 예술적인 예민가 – 팔레트
    Map.entry("INFP", "🌸"), // 감성적인 중재자 – 벚꽃
    Map.entry("INTP", "💡"), // 논리적인 사색가 – 전구

    Map.entry("ESTP", "🏍️"), // 모험적인 활동가 – 오토바이
    Map.entry("ESFP", "🎉"), // 자유로운 연예인 – 폭죽
    Map.entry("ENFP", "🔥"), // 열정적인 외교관 – 불꽃
    Map.entry("ENTP", "⚡"), // 재기발랄한 발명가 – 번개

    Map.entry("ESTJ", "📋"), // 현실적인 관리자 – 체크리스트
    Map.entry("ESFJ", "🤝"), // 친화력 좋은 사회자 – 악수
    Map.entry("ENFJ", "🌟"), // 정의로운 주도자 – 별
    Map.entry("ENTJ", "👑")  // 당당한 리더 – 왕관
);

 


☠️ 트러블 슈팅

  • 발생한 Issue
    • 타임리프 속성 및 의미에 대해 다시 복습하고 세부내용 살펴볼 필요가 있었음. (왜 사용되고 어떤 방식으로 연결해야 하는지에 대한 이해도 부족)
    • Getter / Setter 개념 복습 필요

  • 해결방법 / 찾아본 내용
    • 🔑 th:field, th:text 의 개념은?
      • 타임리프(Thymeleaf)에서 제일 기본적인 속성
        • th:field
          • 폼 입력 요소(input, textarea, select 등)를 객체의 필드와 연결(bind)하는 속성
            th:object="${person}" → 컨트롤러에서 모델에 넣어준 Person 객체를 바인딩 대상으로 지정
            th:filed="*{name}" → person.name 필드와 이 input을 연결
        • th:text
          • HTML 태그 안에 텍스트를 동적으로 출력하는 속성
          • 단순한 ${변수} 출력과 달리, th:text는 XSS 방지를 위해 HTML 이스케이프 처리를 해줌
            예:<script> 같은 값이 들어와도 그냥 텍스트로 보이게 함
            <p th:text="${person.name}">기본값</p> → <p>홍길동</p>
      • 이에 따라 입력 폼에서는 필드를 연결하는 th:field를 사용하여 연결하고, 결과문에서는 값들을 조합하는 th:text를 활용한 최종 문장 출력에 이용하게 되었음 
    • 🔑 Getter / Setter의 개념에 대해 복습 필요
      • Getter (읽기)
        • 필드(변수)의 값을 가져올 때 사용하는 메서드
        • 이름 규칙 : get + 필드명 (대문자로 시작)
        • 반환 타입은 필드 타입과 동일해야 함
      • Setter (쓰기)
        • 필드(변수)의 값을 변경할 때 사용하는 메서드
        • 이름 규칙 : set + 필드명(대문자로 시작)
        • 매개변수 타입은 필드의 타입과 동일, 리턴은 보통 void
      • 목적 : 캡슐화 + 제어 가능성 확보
      • 사용 위치 : 클래스 블록 안, 생성자 밖

> ❗️ Getter,Setter / th:field, th:text 유사해보이는데 비슷한 과정을 거치는 것 아닌가?

  • 값을 주고받는 것에서는 비슷해 보이지만, 실제로는 역할과 위치가 다름

  • Getter / Setter 
    • 자바 클래스 내부에서 정의 하는 메서드
    • 목적 : 객체의 필드를 읽고 변경하기
  • th:field / th:text
    • 템플릿(HTML, 뷰) 에서 쓰이는 속성
    • 목적 : HTML 입력값 ↔︎ 자바 객체 필드를 자동 매핑 / 객체의 값을 화면에 출력
 💬 Q. Controller가 뭔가요?

A. Controller 는 사용자의 요청을 처음으로 받아서, 어떤 작업을 해야 할지 판단하고 그 작업을

Service에게 시키는 역할을 해요.

Q. Service는 뭔가요?

A. Service는 **실제로 처리해야 할 일(기능)**을 담아두는 클래스예요.

'JAVA > Java 실습' 카테고리의 다른 글

[JAVA] 계산기 과제 개념 추가 정리  (0) 2025.09.16
점메추 SPA 에디션  (0) 2025.09.10
MVC 기반 점심 메뉴 추천기  (0) 2025.09.10
JSP 자기소개 버전 만들기  (0) 2025.09.09
JSP / Servlet 실습  (0) 2025.09.05
'JAVA/Java 실습' 카테고리의 다른 글
  • 점메추 SPA 에디션
  • MVC 기반 점심 메뉴 추천기
  • JSP 자기소개 버전 만들기
  • JSP / Servlet 실습
stark77
stark77
하마의 IT 자기개발 이모저모, 백엔드 개발자로 거듭나기
  • stark77
    하마의 개발자 성장일기
    stark77
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 컴퓨터구조와 운영체제
        • 컴퓨터구조
        • 운영체제
      • SQL 기초
      • Spring
        • 백엔드 기초
        • Spring 실습
      • JAVA
        • Java 실습
      • HTML&CSS
        • HTML&CSS 실습
      • Git&GitHub
        • Git&GitHub 실습
      • 내배캠 끄적끄적
        • Today I Learned
      • 유용한 툴 및 사이트 정리
      • 취미
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    다형성
    JPA
    BEAN
    경합조건과 교착상태
    jsp
    실시간 데이터 처리
    MVC
    웹소켓
    백엔드 기초다지기
    WebSocket
    Spriingboot
    객체지향
    백엔드 기초
    HTML&CSS
    Stomp
    SpringSecurity
    git
    java
    algorithm
    Github
    Til
    네트워크 기초
    Java 문법기초
    Spring
    RestTemplate
    for문
    thymleaf
    객체지향프로그래밍
    String.format
    프로세스와 쓰레드
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
stark77
나를 소개합니다
상단으로

티스토리툴바