ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

๐Ÿ’กํšŒ์› ์›น ๊ธฐ๋Šฅ - ํ™ˆ ํ™”๋ฉด ์ถ”๊ฐ€

๐Ÿ’ป HomeController

package hello.hellospring.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HomeController {
    @GetMapping("/")
    public String home() {
        return "home";
    }
}

http://localhost:8080/ ์„ ์น˜๊ณ  ๋“ค์–ด๊ฐ€๋ฉด home ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ ,
return "home";์„ ํ†ตํ•ด home.htmlํŒŒ์ผ์„ ๋ถˆ๋Ÿฌ์˜จ๋‹ค.
 

๐Ÿ’ปhome.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div class="container">
    <div>
        <h1>Hello Spring</h1>
        <p>ํšŒ์› ๊ธฐ๋Šฅ</p>
        <p>
            <a href="/members/new">ํšŒ์› ๊ฐ€์ž…</a>
            <a href="/members">ํšŒ์› ๋ชฉ๋ก</a>
        </p>
    </div>
</div> <!-- /container -->
</body>
</html>

 

์œ„์™€ ๊ฐ™์€ ํ™”๋ฉด์ด ๋œฌ๋‹ค.
ํšŒ์› ๊ฐ€์ž…๊ณผ ํšŒ์› ๋ชฉ๋ก ํŽ˜์ด์ง€๋ฅผ ๋ˆ„๋ฅด๋ฉด, ์•„์ง ํ•ด๋‹น htmlํŒŒ์ผ๊ณผ controller๊ฐ€ ๋งŒ๋“ค์–ด์ง€์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ error page๊ฐ€ ๋œฌ๋‹ค.
 

๐Ÿ’ป ์ปจํŠธ๋กค๋Ÿฌ (์šฐ์„ ์ˆœ์œ„)

์ „์— index.html ์ด๋ผ๋Š” staticํ•œ htmlํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์ฃผ์—ˆ์—ˆ๊ณ , http://localhost:8080/ ์— ๋“ค์–ด๊ฐ€๋ฉด index.html์ด ๋–ด์ง€๋งŒ,
 
์ง€๊ธˆ์€ home.html์ด ๋œฌ๋‹ค.
๊ทธ ์ด์œ ๋Š” 

์™œ๋ƒํ•˜๋ฉด ๋‚ด์žฅ ํ†ฐ์ผ“ ์„œ๋ฒ„์—์„œ ํ•ด๋‹น ํŽ˜์ด์ง€์— ๋Œ€ํ•œ ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ฐพ๊ณ , ๋งŒ์•ฝ ๊ทธ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์—†์œผ๋ฉด ์ •์  ์ปจํ…์ธ ๋ฅผ ์ฐพ๊ฒŒ ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ฆ‰, ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์ •์  ํŒŒ์ผ๋ณด๋‹ค ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋” ๋†’๋‹ค.
๋”ฐ๋ผ์„œ ๋‚ด์žฅ ํ†ฐ์ผ“ ์„œ๋ฒ„๋Š” HomeController๋ฅผ ์ฐพ๊ณ , ์ด ์ปจํŠธ๋กค๋Ÿฌ์—์„œ returnํ•ด์ค€ home.html์„ ํ™”๋ฉด์— ๋„์šด๋‹ค.
 

๐Ÿ’กํšŒ์› ์›น ๊ธฐ๋Šฅ - ๋“ฑ๋ก

๐Ÿ’ป MemberController

@Controller
public class MemberController { //์–˜๋„ spring ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๊ด€๋ฆฌ๋ฅผ ํ•˜๊ฒŒ ๋จ

    //private final MemberService memberService = new MemberService();
    //new ํ•ด์„œ ํ•˜๋ฉด memberCotroller๋ง๊ณ  ๋‹ค๋ฅธ controller๋“ค๋”” memberService๊ฐ€์ ธ๋‹ค ์“ธ ์ˆ˜ ์žˆ์Œ
    //์—ฌ๋Ÿฌ๊ฐœ์˜ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑํ•  ํ•„์š” ์—†์ด ํ•˜๋‚˜ ์ƒ์„ฑํ•ด๋†“๊ณ  ๊ณต์šฉ์œผ๋กœ ์“ฐ๋ฉด ๋จ -> spring ์ปจํ…Œ์ด๋„ˆ์— ํ•˜๋‚˜ ๋“ฑ๋กํ•˜๊ณ  ์“ฐ๊ธฐ (ํ•˜๋‚˜๋งŒ ๋“ฑ๋ก์ด๋จ)
    private MemberService memberService;

//    @Autowired //setter injection ๋ฐฉ์‹
//    public void setMemberService(MemberService memberService){
//        this.memberService = memberService;
//    } // ํ•œ๋ฒˆ settingํ•˜๋ฉด ๋ฐ”๊ฟ€ ์ผ ์—†๋Š”๋ฐ public์œผ๋กœ ์„ค์ •ํ•ด์•ผํ•จ ์ตœ๋Œ€ํ•œ ๋ณ€๊ฒฝ ๋ชปํ•˜๋„๋ก ํ•ด์•ผํ•˜๋Š”๋ฐ..


    @Autowired //๊ทธ๋Ÿฐ๋ฐ ์ƒ์„ฑ์ž์— AutoWired๋ผ๊ณ  ๋˜์–ด ์žˆ์œผ๋ฉด
    // ์Šคํ”„๋ง์ด ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ์žˆ๋Š” ๋ฉค๋ฒ„ ์„œ๋น„์Šค๋ฅผ ๊ฐ€์ ธ๋‹ค๊ฐ€ ์—ฐ๊ฒฐ์„ ๋”ฑ ์‹œ์ผœ์ค๋‹ˆ๋‹ค
    // ์ƒ์„ฑ์ž์—์„œ ์ด๋ ‡๊ฒŒ ์“ฐ๋ฉด ๋ฉค๋ฒ„ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์ƒ์„ฑ์ด ๋  ๋•Œ ์Šคํ”„๋ง ๋นˆ์— ๋“ฑ๋ก๋˜์–ด ์žˆ๋Š” ๋ฉค๋ฒ„ ์„œ๋น„์Šค๋ฅผ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ๋‹ค๊ฐ€ ๋„ฃ์–ด์คŒ = dependency Injection
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }

    @GetMapping("/members/new")
    public String createForm() {
        return "members/createMemberForm";
    } //๊ธฐ๋ณธ์ ์œผ๋กœ ์ด๋Ÿฐ URL ์ฐฝ์— ์—”ํ„ฐ ๋”ฑ ์น˜๋Š” ๊ฒƒ์€ ๊ทธ๋ƒฅ GetMapping

http://localhost:8080/members/new ํŽ˜์ด์ง€์— ๋“ค์–ด๊ฐ€๋ฉด createForm ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๊ณ , members/createMemberForm์„ returnํ•˜๊ธฐ ๋•Œ๋ฌธ์— members ํด๋”์— createMemberForm.htmlํŒŒ์ผ๋„ ๋งŒ๋“ค์–ด์ค€๋‹ค.
 

๐Ÿ’ป createMemberForm.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div class="container">
    <form action="/members/new" method="post">
        <div class="form-group">
            <label for="name">์ด๋ฆ„</label>
            <input type="text" id="name" name="name" placeholder="์ด๋ฆ„์„
์ž…๋ ฅํ•˜์„ธ์š”">
        </div>
        <button type="submit">๋“ฑ๋ก</button>
    </form>
</div> <!-- /container -->
</body>
</html>

 
http://localhost:8080/members/new ์ด์ œ ์ด ๋งํฌ๋ฅผ ๋“ค์–ด๊ฐ€๋ฉด 

์œ„์™€ ๊ฐ™์€ ํ™”๋ฉด์ด ๋œฌ๋‹ค.
 
๊ทธ๋Ÿฌ๋‚˜ ์•„์ง ์„œ๋ฒ„๋กœ ์ „๋‹ฌ์ด ์•ˆ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜๊ณ  ๋“ฑ๋ก์„ ํ•˜๋ฉด Error Page๊ฐ€ ๋œฌ๋‹ค.
html์˜ form ํƒœ๊ทธ ์•ˆ์— method="post" ์ด๋ ‡๊ฒŒ POST ๋ฐฉ์‹์œผ๋กœ ์ž…๋ ฅ์„ ๋ฐ›์œผ๋ฉด ์„œ๋ฒ„๋กœ ์ „๋‹ฌ์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์—
input์œผ๋กœ ์ž…๋ ฅ ๋ฐ›์€ ๋‚ด์šฉ์„ ๋ฐ›๊ธฐ ์œ„ํ•œ ํšŒ์› ๋“ฑ๋ก ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค.
 

๐Ÿ’ป MemberForm

package hello.hellospring.controller;

public class MemberForm {
    private String name;
    //html์—์„œ name="name"์„ ๋ณด๊ณ  ์ด name์— ๋„ฃ์–ด์คŒ

    public String getName() {
        return name;
    }

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

ํšŒ์› ๋“ฑ๋ก ํ™”๋ฉด์—์„œ input์„ ํ†ตํ•ด ์ž…๋ ฅ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌ ๋ฐ›์„ ํผ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์—ˆ๋‹ค.
 

๐Ÿ’ปMemberController

    @PostMapping("/members/new")
    public String create(MemberForm form){
        Member member = new Member();
        member.setName(form.getName());

        memberService.join(member);

        return "redirect:/"; //ํšŒ์›๊ฐ€์ž…์ด ๋๋‚˜๊ณ  ํ™ˆ ํ™”๋ฉด์œผ๋กœ ๋ณด๋‚ด๋ฒ„๋ฆผ
    }

์ž…๋ ฅ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ปจํŠธ๋กค๋Ÿฌ์—์„œ ํšŒ์›์„ ์‹ค์ œ ๋“ฑ๋กํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๋งŒ๋“ค์–ด์ฃผ์—ˆ๋‹ค.
 
์ด์ œ http://localhost:8080/members/new๋กœ ๋“ค์–ด๊ฐ€ ์ด๋ฆ„์„ ์ž…๋ ฅํ•˜๊ณ  ๋“ฑ๋ก ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด return "redirect:/"; ์— ์˜ํ•ด ํšŒ์›๊ฐ€์ž…์ด ๋๋‚˜๊ณ  ํ™ˆ ํ™”๋ฉด์œผ๋กœ ๋ณด๋‚ด๋ฒ„๋ฆฐ๋‹ค.

 

๐Ÿ’ป ํšŒ์› ๋“ฑ๋ก ์ปจํŠธ๋กค๋Ÿฌ ์„ค๋ช…!!

์šฐ๋ฆฌ๊ฐ€ ์ผ๋ฐ˜์ ์œผ๋กœ ์›น ํŽ˜์ด์ง€ ์ฃผ์†Œ๋ฅผ ์ž…๋ ฅํ•ด ๋“ค์–ด๊ฐ€๋Š” ๋ฐฉ์‹์„ GET ๋ฐฉ์‹์ด๋ผ๊ณ  ํ•œ๋‹ค.
ํšŒ์› ๋“ฑ๋ก Form์—์„œ input ์†์„ฑ ์ค‘ name์€ ์ž…๋ ฅ๋ฐ›์•„์„œ ์ œ์ถœํ•œ ๊ฐ’์˜ key๊ฐ’์ด ๋˜์–ด, ๊ฐ’์„ ์ž…๋ ฅ ๋ฐ›๊ณ  ๋“ฑ๋ก ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด "/members/new" ๋กœ POST ๋ฐฉ์‹์œผ๋กœ ๋„˜์–ด๊ฐ€๊ฒŒ ๋œ๋‹ค.

<form action="/members/new" method="post">
  <div class="form-group">
    <label for="name">์ด๋ฆ„</label>
    <input type="text" id="name" name="name" placeholder="์ด๋ฆ„์„ ์ž…๋ ฅํ•˜์„ธ์š”">
  </div>
  <button type="submit">๋“ฑ๋ก</button>
</form>

๊ทธ๋Ÿผ POST ๋ฐฉ์‹์œผ๋กœ ๋„˜๊ฑฐ๊ฐ€๊ฒŒ ๋˜๋ฉด ์•„๋ž˜ @PostMapping("/members/new") ๋ฉ”์„œ๋“œ๋กœ ํ˜ธ์ถœ์ด ๋œ๋‹ค.

@PostMapping("/members/new") // Post ๋ฐฉ์‹์œผ๋กœ localhost::8080/members/new
public String create(MemberForm form) {
	Member member = new Member(); // member ๊ฐ์ฒด ์ƒ์„ฑ
	member.setName(form.getName()); // form์—์„œ ์ž…๋ ฅ๋ฐ›์€ ์ด๋ฆ„์„ member ๊ฐ์ฒด ์ด๋ฆ„์œผ๋กœ ๋„ฃ์Œ

	memberService.join(member); // member ๊ฐ์ฒด๋กœ join(ํšŒ์›๊ฐ€์ž…)

	return "redirect:/"; // ๋ฐ”๋กœ "localhost::8080/" ํ™”๋ฉด์œผ๋กœ ์ด๋™
}

(์ถœ์ฒ˜: easy00.log)

๐Ÿ’กํšŒ์› ์›น ๊ธฐ๋Šฅ - ์กฐํšŒ

๐Ÿ’ป MemberController (ํšŒ์› ์กฐํšŒ ํ™”๋ฉด ์ถ”๊ฐ€)

    @GetMapping("/members")
    public String list(Model model) { //Model์€ ์Šคํ”„๋ง์—์„œ ์ปจํŠธ๋กค๋Ÿฌ์™€ ๋ทฐ ๊ฐ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›๊ธฐ ์œ„ํ•œ ๊ฐ์ฒด
        List<Member> members = memberService.findMembers();
        model.addAttribute("members",members);
        return "members/memberList";
    }

์ž…๋ ฅ๋ฐ›์€ input๊ฐ’์„ ์ง์ ‘ ํ™”๋ฉด์—์„œ ์กฐํšŒํ•ด๋ณด๊ธฐ ์œ„ํ•ด controller๋ฅผ ๋งŒ๋“ค์–ด์ฃผ์—ˆ๋‹ค.
 
return "members/memberList"; ์„ ํ•ด์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— memberList.html๋„ ๋งŒ๋“ค์–ด์ค€๋‹ค.
 

๐Ÿ’ป memberList.html

<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div class="container">
    <div>
        <table>
            <thead>
            <tr>
                <th>#</th>
                <th>์ด๋ฆ„</th>
            </tr>
            </thead>
            <tbody>
            <tr th:each="member : ${members}"> <!--model์•ˆ์— ์žˆ๋Š” ๊ฐ’ ๊บผ๋‚ด๋Š” ๊ฒƒ, ์ฒซ๋ฒˆ์งธ ๊ฐ์ฒด๋ฅผ ํ•˜๋‚˜ ๊บผ๋‚ด์„œ ๋ฉค๋ฒ„์— ๋‹ด๊ณ , ์•„์ด๋””๋ž‘ ๋„ค์ž„ ์ถœ๋ ฅ-->
                <td th:text="${member.id}"></td>
                <td th:text="${member.name}"></td>
            </tr>
            </tbody>
        </table>
    </div>
</div> <!-- /container -->
</body>
</html>

 

<tr th:each="member : ${members}"> <!--model์•ˆ์— ์žˆ๋Š” ๊ฐ’ ๊บผ๋‚ด๋Š” ๊ฒƒ, ์ฒซ๋ฒˆ์งธ ๊ฐ์ฒด๋ฅผ ํ•˜๋‚˜ ๊บผ๋‚ด์„œ ๋ฉค๋ฒ„์— ๋‹ด๊ณ , ์•„์ด๋””๋ž‘ ๋„ค์ž„ ์ถœ๋ ฅ-->
    <td th:text="${member.id}"></td>
    <td th:text="${member.name}"></td>
</tr>

${members}๋Š” controller์—์„œ ๋„˜๊ฒจ์ค€ ๋ชจ๋“  member๋“ค์˜ List์ธ members ๋ผ๋Š” model์ด๋‹ค.
th:each๋ฅผ ํ†ตํ•ด members์˜ ๊ฐ์ฒด ์ˆ˜๋งŽํผ loop๋ฅผ ๋Œ๊ณ , ์ฒซ๋ฒˆ์งธ ๊ฐ์ฒด๋ฅผ ํ•˜๋‚˜ ๊บผ๋‚ด์„œ ๋ฉค๋ฒ„์— ๋‹ด๊ณ , ์•„์ด๋””๋ž‘ ๋„ค์ž„ ์ถœ๋ ฅํ•˜๋Š” ๊ฒƒ์„ ๋ฐ˜๋ณตํ•œ๋‹ค.
member์˜ id์™€ name์ด ๊ฐ๊ฐ ${member.id} ์™€ ${member.name} ์— ์น˜ํ™˜์ด ๋œ๋‹ค.
 
์ด์ œ http://localhost:8080/members์— ๋“ค์–ด๊ฐ€๋ฉด

์œ„์™€ ๊ฐ™์€ ํ™”๋ฉด์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
 
๊ทธ๋Ÿฌ๋‚˜ ์ง€๊ธˆ ๋“ฑ๋กํ•œ ์ •๋ณด๋“ค์€ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ฒ„๋ฅผ ๊ป๋‹ค ํ‚ค๋ฉด ์ดˆ๊ธฐํ™”๊ฐ€ ๋œ๋‹ค.
๋”ฐ๋ผ์„œ ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด DB๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

'Spring' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[SPRING]์Šคํ”„๋ง ์ž…๋ฌธ - ์ฝ”๋“œ๋กœ ๋ฐฐ์šฐ๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ, ์›น MVC, DB ์ ‘๊ทผ ๊ธฐ์ˆ  ์„น์…˜7 (AOP)  (0) 2024.01.01
[SPRING]์Šคํ”„๋ง ์ž…๋ฌธ - ์ฝ”๋“œ๋กœ ๋ฐฐ์šฐ๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ, ์›น MVC, DB ์ ‘๊ทผ ๊ธฐ์ˆ  ์„น์…˜6 (์Šคํ”„๋ง DB ์ ‘๊ทผ ๊ธฐ์ˆ )  (3) 2023.12.29
[SPRING]์Šคํ”„๋ง ์ž…๋ฌธ - ์ฝ”๋“œ๋กœ ๋ฐฐ์šฐ๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ, ์›น MVC, DB ์ ‘๊ทผ ๊ธฐ์ˆ  ์„น์…˜4 (์Šคํ”„๋ง ๋นˆ๊ณผ ์˜์กด๊ด€๊ณ„)  (0) 2023.11.27
[SPRING]์Šคํ”„๋ง ์ž…๋ฌธ - ์ฝ”๋“œ๋กœ ๋ฐฐ์šฐ๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ, ์›น MVC, DB ์ ‘๊ทผ ๊ธฐ์ˆ  ์„น์…˜3 (ํšŒ์› ๊ด€๋ฆฌ ์˜ˆ์ œ - ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ)  (0) 2023.11.08
[SPRING]์Šคํ”„๋ง ์ž…๋ฌธ - ์ฝ”๋“œ๋กœ ๋ฐฐ์šฐ๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ, ์›น MVC, DB ์ ‘๊ทผ ๊ธฐ์ˆ  ์„น์…˜ 2 (์ •์ ์ปจํ…์ธ , MVC์™€ ํ…œํ”Œ๋ฆฟ ์—”์ง„, API)  (1) 2023.11.07