📌 회원 웹 기능 - 홈 화면 추가
📌 회원 웹 기능 - 등록
📌 회원 웹 기능 - 조회
➕ 웹 MVC란?
애플리케이션을 Model-View-Controller로 나누는 것이다.
🔥 홈 컨트롤러 추가
📄 HomeController
@Controller
public class HomeController {
@GetMapping("/")
public String home() {
return "home";
}
}
🔥 회원 관리용 홈
📂 templates
📄 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>
📂
회원 등록 폼 개발
📄 MemberController
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
@GetMapping(value = "/members/new")
public String createForm() {
return "members/createMemberForm";
}
}
회원 등록 폼 HTML
📄 createMemberForm
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div class="container">
<!-- 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>
</div> <!-- /container -->
</body>
</html>
📄 MemberForm
public class MemberForm {
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
⚒️create
//같은 URL이지만 방식에 따라서 다르게 매핑된다.
//HTML에서 MemberForm에 있는 name에 매핑해줌.
@PostMapping("/members/new")
public String create(MemberForm form) {
Member member = new Member();
member.setName(form.getName());
memberService.join(member);
return "redirect:/";
}
⚒️ list
@GetMapping("/members")
public String list(Model model) {
List<Member> members = memberService.findMembers();
model.addAttribute("members", members);
return "members/memberList";
}
📄 memberList
<!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}">
<td th:text="${member.id}"></td>
<td th:text="${member.name}"></td>
</tr>
</tbody>
</table>
</div>
</div> <!-- /container -->
</body>
</html>
<조회 기능 화면>
HelloController - 이거는 다른 예제에서 한 것!!
HomeController - 첫 화면을 띄워줌. 위 컨트롤러가 정적 예제이기 떄문에 홈 컨트롤러가 우선됨.
📌컨트롤러가 정적 파일보다 우선순위가 높다.
MemberController - 회원을 등록하고 조회하는 기능을 제공하는 컨트롤러
MemberForm - 실제 컨트롤러는 아니고, 사용자로부터 입력받는 이름을 전달받는 객체이다.
@Controller
public class HomeController {
@GetMapping("/")
public String home() {
return "home";
}
}
@RequestMapping
Spring 프레임워크에서 URL을 핸들링하고 요청을 처리하는 데 사용되는 어노테이션이다. 이 어노테이션은 특정 메서드가 특정 URL 경로에 매핑되도록 지정한다.
👉 사용 방법
@@RequestMapping(url)
자바메서드...
@GetMapping
- Get method 로 RequestMapping을 합니다.
@PostMapping
- Post method 로 RequestMapping을 합니다.
➕ 흐음... 괄호안에 url이 해당 경로를 뜻하는 것은 알겠어. 하지만 @GetMapping("/")
과 @GetMapping()
의 차이가 궁금한걸?
👉 실제로 @GetMapping()
로 해도 기능의 차이가 없다고..!!
GPT 답변.. 이건 따로 포스팅을 하도록 하자.
@GetMapping("/")과 @GetMapping() 모두 루트 경로(/)에 대한 요청을 처리하는데
사용될 수 있지만, 두 가지 사례가 동일한 결과를 가져온다면,
이는 Spring Framework의 동작 방식에 기인합니다.
@GetMapping("/")은 명시적으로 / 경로로 들어오는 GET 요청을 처리하는 방법을 정의합니다.
한편, @GetMapping()은 아무런 경로를 지정하지 않았기 때문에,
모든 요청에 대해 일반적인 디폴트 동작을 수행합니다.
스프링에서는 URL을 매핑할 때, 가장 구체적인 매핑이 가장 우선시되는데,
/는 루트 경로로서 가장 구체적인 URL 경로 중 하나입니다.
그래서, @GetMapping("/")과 @GetMapping() 두 경우 모두 루트 경로를 처리하는데,
하지만 @GetMapping()의 경우는 어떠한 경로에도 매핑이 가능하기 때문에,
디폴트로 가장 구체적인 경로인 /와 동일한 동작을 보일 수 있습니다.
Spring은 요청이 들어왔을 때, 가능한 모든 매핑을 검사하여 해당 요청과
일치하는 핸들러 메소드를 찾습니다.
만약 /에 대한 매핑을 명시적으로 정의하지 않고, 다른 경로들에 대한 매핑만 정의되어 있다면,
/에 대한 요청은 가장 일반적인 디폴트 매핑인 @GetMapping()으로 처리될 수 있습니다.
이러한 동작은 Spring의 URL 매핑 및 요청 처리 우선순위에 따른 것이며,
특정 상황에 따라 명시적으로 경로를 지정하는 것과
그렇지 않은 것의 동일한 결과를 가져올 수 있을 수 있습니다.
@Controller
public class MemberController {
// 공용으로 쓸 수 있게
//private final MemberService memberService = new MemberService();
private final MemberService memberService;
@Autowired
//생성자의 Autowired?? ->
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
@GetMapping(value = "/members/new")
public String createForm() {
//단순한 이동 기능
return "members/createMemberForm";
//탬플릿에서 members/createMemberForm를 찾는다.
}
//같은 URL이지만 방식에 따라서 다르게 매핑된다.
//HTML에서 MemberForm에 있는 name에 매핑해줌.
@PostMapping("/members/new")
public String create(MemberForm form) {
Member member = new Member();
member.setName(form.getName());
memberService.join(member);
return "redirect:/";
}
@GetMapping("/members")
public String list(Model model) {
List<Member> members = memberService.findMembers();
model.addAttribute("members", members);
return "members/memberList";
}
}
이 코드는 생성자 부분과 메서드 3개로 나눠볼 수 있다. 또한 등록과 조회의 기능을 하고 있다.
천천히 살펴보자 😊
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
📍@Autowired
createForm()
과 create(MemberForm form)
😮 헉 같은 url의 RequestMapping이 두 개나?
👉 하지만 방식이 다르기 때문에 각자 다르게 동작한다!!
@GetMapping(value = "/members/new")
public String createForm() {
return "members/createMemberForm";
}
➡️ 탬플릿에서 members/createMemberForm를 찾아 제공한다.
//같은 URL이지만 방식에 따라서 다르게 매핑된다.
//HTML에서 MemberForm에 있는 name에 매핑해줌.
@PostMapping("/members/new")
public String create(MemberForm form) {
Member member = new Member();
member.setName(form.getName());
memberService.join(member);
return "redirect:/";
}
list
@GetMapping("/members")
public String list(Model model) {
List<Member> members = memberService.findMembers();
model.addAttribute("members", members);
return "members/memberList";
}
😰 나는 파라미터를 따로 준 적이없는데 왜 파라미터가 있을까??ㅜㅜ
(정말 자바스프링 어렵고 짜증나!!🫤)
model.addAttribute("members", members);
➡️ 위에서 추가된 멤버리스트를 Model객체에 추가하는 것이다.
(흠.. 추가될 때 쓰이는 군..)
이것도 따로 포스팅을 해야겠당..
Spring MVC에서 Model 객체는 컨트롤러가 뷰로 데이터를 전달하는 데 사용되는 매개변수 중 하나입니다.
이 매개변수는 메소드 시그니처에서 파라미터로 명시되지만, 직접적으로 클라이언트에서 전달되는 HTTP 요청 파라미터가 아닙니다.
Spring의 MVC 프레임워크는 요청을 처리할 때
해당 메소드 시그니처의 매개변수를 자동으로 인식하고 채웁니다.
Model 객체는 뷰로 전달할 데이터를 보유하는데 사용됩니다.
이것은 Spring MVC의 동작 방식 중 하나이며,
Model은 개발자가 직접 요청에서 파라미터를 추출하거나 사용자 입력을 처리하는 용도가 아니라,
뷰로 데이터를 전달하기 위해 사용됩니다.
하 공부는 쉽지 않아