์์๋ฅผ ํตํด ์์๋ณด๋ MVC ํจํด ์ด์ ๋ฆฌ (RequestMapping, addAttribute)
๐คจMVCํจํด์ด๋?
MVC(Mode-View-Controller)๋ ์ํํธ์จ์ด ๋์์ธ ํจํด์ผ๋ก, ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌ์ฑํ๋ ๋ฐ ๋๋ฆฌ ์ฌ์ฉ๋ฉ๋๋ค.
์ด ํจํด์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ธ ๊ฐ์ง ์ฃผ์ ๋ถ๋ถ์ผ๋ก ๋๋์ด ๊ฐ๋ฐํ๋ ๋ฐฉ๋ฒ์ ์ ์ํฉ๋๋ค!
Controller (์ปจํธ๋กค๋ฌ):
- ์ปจํธ๋กค๋ฌ๋ ๋ชจ๋ธ๊ณผ ๋ทฐ๋ฅผ ์ฐ๊ฒฐํ๋ ์ค๊ฐ ์ญํ ์ ํฉ๋๋ค.
- ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ์์ฒญ์ด ์ค๋ฉด ์น ์ ํ๋ฆฌ์ผ์ด์ ์ Controller๊ฐ ์ด๋ฅผ ๋ฐ์๋ค์ ๋๋ค. Controller๋ ์์ฒญ์ ๋ถ์ํ๊ณ , ํ์ํ ์ฒ๋ฆฌ๋ฅผ ์ํด Service๋ Repository ๋ฑ์ ๋ค๋ฅธ ์ปดํฌ๋ํธ์ ์ํธ ์์ฉํ ์ ์์ต๋๋ค.
- ์์๊ฐ์ด ์ฌ์ฉ์์ ์์ฒญ์ ๋ฐ์ ํด๋น ์์ฒญ์ ๋ํ ์ฒ๋ฆฌ๋ฅผ ์ํํ๊ณ , ๊ฒฐ๊ณผ๋ฅผ ๋ชจ๋ธ์ ์ ๋ฌํฉ๋๋ค.
- ๋ชจ๋ธ๋ก๋ถํฐ ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ ์ ํ ๋ทฐ๋ก ๋ณด๋ด ์ฌ์ฉ์์๊ฒ ์๋ต์ ์ ๊ณตํฉ๋๋ค.
@RequestMapping
- Spring MVC์์ ํน์ URL์ ๋ํ ์์ฒญ์ ์ฒ๋ฆฌํ ๋ฉ์๋์ ๋ถ์ฌํ๋ ์ด๋ ธํ ์ด์ ์ ๋๋ค.
- ์ด ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ์ฌ ์ด๋ค ์์ฒญ์ด ๋ค์ด์์ ๋ ์ด๋ค ๋ฉ์๋๊ฐ ์ฒ๋ฆฌํ ์ง๋ฅผ ์ง์ ํ ์ ์์ต๋๋ค.
์ฃผ๋ก ํด๋์ค๋ ๋ฉ์๋ ๋ ๋ฒจ์์ ์ฌ์ฉ๋๋ฉฐ, URL ํจํด์ด๋ HTTP ์์ฒญ ๋ฉ์๋(get,post,delete ...) ๋ฑ์ ์ง์ ํ ์ ์์ต๋๋ค.
model.addAttribute()
- Spring MVC์์ ์ปจํธ๋กค๋ฌ(Controller)์์ ๋ทฐ(View)๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ ๋ ์ฌ์ฉํ๋ ๋ฉ์๋์ ๋๋ค.
- ์ด ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ชจ๋ธ์ ์์ฑ์ ์ถ๊ฐํ๊ณ , ์ด ์์ฑ์ ๋ทฐ์์ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
์ฃผ๋ก ์ปจํธ๋กค๋ฌ์์ ์ฒ๋ฆฌํ ๊ฒฐ๊ณผ๋ ์ฌ์ฉ์์๊ฒ ํ์ํ ์ ๋ณด๋ฅผ ๋ชจ๋ธ์ ์ถ๊ฐํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
Service
- Controller์์ Service๋ก ์์ฒญ์ ์ ๋ฌํ๊ณ Controller๋ ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌ๋ฅผ ์ํด Service๋ฅผ ํธ์ถํฉ๋๋ค.
- Service๋ ํด๋น ์์ฒญ์ ํ์ํ ๋น์ฆ๋์ค ๋ก์ง์ ์ํํ๊ณ , ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ฅผ ์ํด Repository์ ํ๋ ฅํฉ๋๋ค.
Repository
- Service๋ Repository๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ์ ์ ๊ทผํฉ๋๋ค.
- Repository๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ํธ ์์ฉ์ ์ถ์ํํ ์ธํฐํ์ด์ค๋ก, ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ์กฐํํ๋ ๋ฑ์ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.
- JPA๋ฅผ ์์๋ฐ๊ธฐ ๋๋ฌธ์ JPA๋ฅผ ์ฌ์ฉํฉ๋๋ค.
โฉRepository๋ฅผ ํตํด ๋ฐ์ดํฐ์ ์ ๊ทผํ ํ, Service๋ ํด๋น ๋ฐ์ดํฐ๋ฅผ ๊ฐ๊ณตํ๊ฑฐ๋ ํ์ํ ํํ๋ก ๋ณํํ ํ, Controller์ ๋ฐํํฉ๋๋ค. Controller๋ ์ด๋ฅผ ๋ค์ ํด๋ผ์ด์ธํธ๋ก ์๋ตํ์ฌ ์์ฒญ์ ๋ํ ์ฒ๋ฆฌ๋ฅผ ๋ง๋ฌด๋ฆฌํฉ๋๋ค.
Model (๋ชจ๋ธ):
- ๋ชจ๋ธ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐ์ดํฐ์ ๋น์ฆ๋์ค ๋ก์ง์ ๋ํ๋ ๋๋ค.
- ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํ ์ด๋ธ๊ณผ ๋งคํ๋๋ ํด๋์ค๋ก ๊ตฌํ๋ ์ ์์ต๋๋ค.
- ์ฃผ๋ก ๋ฐ์ดํฐ์ ๊ตฌ์กฐ๋ฅผ ์ ์ํ๊ณ , ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๋น์ฆ๋์ค ๋ก์ง์ ํฌํจํฉ๋๋ค.
View (๋ทฐ):
- ๋ทฐ๋ ์ฌ์ฉ์์๊ฒ ๋ฐ์ดํฐ๋ฅผ ์๊ฐ์ ์ผ๋ก ํํํ์ฌ ๋ณด์ฌ์ค๋๋ค.
- HTML, CSS, JavaScript ๋ฑ์ ์ฌ์ฉํ์ฌ ์น ํ์ด์ง๋ฅผ ๊ตฌ์ฑํ๊ณ , ๋ชจ๋ธ์์ ๋ฐ์์จ ๋ฐ์ดํฐ๋ฅผ ํ์ํฉ๋๋ค.
- ์ฃผ๋ก ์ฌ์ฉ์ ์ธํฐํ์ด์ค(UI)๋ฅผ ์์ฑํ๊ณ ์ฌ์ฉ์์๊ฒ ์ ๋ณด๋ฅผ ํ์ํ๋ ์ญํ ์ ํฉ๋๋ค.
๐MVCํจํด์ ์ ์ฌ์ฉํด์ผํ๋์?
1. ๊ฐ์ฅ ํฐ ์ด์ ๋ MVCํจํด์ ์ฌ์ฉํ๋ฉด ์ฝ๋์ ๊ตฌ์กฐ๊ฐ ๋ช ํํด์ ธ ์ ์ง๋ณด์๊ฐ ์ฌ์์ง๊ธฐ ๋๋ฌธ์ ๋๋ค.
2. ๋ํ, ๊ฐ ๋ถ๋ถ์ด ๋ช ํํ๊ฒ ๊ตฌ์ฑ๋์ด ์์ด ์ฝ๋์ ๊ฐ๋ ์ฑ์ด ์ข์ต๋๋ค.
3. ๊ฐ ๋ถ๋ถ์ด ๋ ๋ฆฝ์ ์ผ๋ก ๊ตฌ์ฑ๋์ด ์์ด ํ ์คํธ ํ ๋์๋ ๋ถ๋ฆฌํ์ฌ ํ ์คํธํ ์ ์์ผ๋ฏ๋ก ํ ์คํธ์ ์ฉ์ดํฉ๋๋ค.
4. ๊ฐ๋ฐ์๋ค์ด ๊ฐ๋ณ์ ์ผ๋ก ๋์์ ํ์ ํด ๊ฐ๋ฐํ๊ธฐ์ ์ข์ต๋๋ค.
์์๋ฅผ ํตํด ์์๋ณผ๊น์?
1. Model
public class User {
private Long id;
private String username;
private String email;
// ๊ธฐํ ํ์ํ ์์ฑ๋ค...
// ์์ฑ์, getter, setter ๋ฑ์ ๋ฉ์๋๋ ์๋ตํ์์ต๋๋ค.
}
2. Controller
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.RequestMapping;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/profile")
public String showUserProfile(Model model) {
// ์ฌ์ฉ์ ์ ๋ณด ์กฐํ
User user = userService.getUserProfile();
// View๋ก ์ ๋ฌํ ๋ฐ์ดํฐ ์ค์
model.addAttribute("user", user);
// View ์ด๋ฆ ๋ฐํ
return "userProfilePage";
}
}
(Model model)์ ์ฐ๋ ์ด์
โฉController ๋ฉ์๋์ ๋งค๊ฐ๋ณ์๋ก Model model์ ์ ์ธํ๋ฉด, ์คํ๋ง ํ๋ ์์ํฌ๊ฐ ์๋์ผ๋ก Model ๊ฐ์ฒด๋ฅผ ์์ฑํ์ฌ ํด๋น ๋ฉ์๋์ ์ ๋ฌํฉ๋๋ค. ์ด Model ๊ฐ์ฒด์ ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๋ฉด, ์ด ๋ฐ์ดํฐ๋ ๋ทฐ์์ ์ ๊ทผํ ์ ์๊ฒ ๋ฉ๋๋ค.
๊ฐ๋จํ๊ฒ ๋งํ์๋ฉด, Model model์ ์ปจํธ๋กค๋ฌ์์ ๋ทฐ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๊ธฐ ์ํ ์๋จ์ด๋ผ๊ณ ํ ์ ์์ต๋๋ค. ๋ฐ์ดํฐ๋ฅผ Model์ ์ถ๊ฐํ๋ฉด ์ด๋ฅผ ๋ทฐ์์ ์ฌ์ฉํ ์ ์๊ฒ ๋๋ฉฐ, ์ด๋ฅผ ํตํด ์ฌ์ฉ์์๊ฒ ๋์ ์ธ ์ฝํ ์ธ ๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค.
2-1. Service
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public User getUserProfile() {
// ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์กฐํ
return userRepository.findById(1L).orElse(null);
}
}
2-2. Repository
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
// ์ถ๊ฐ์ ์ธ ๋ฉ์๋๊ฐ ํ์ํ๋ค๋ฉด ์ฌ๊ธฐ์ ์ถ๊ฐํ ์ ์์ต๋๋ค.
}
3. View(userProfilePage.jsp) - Thymeleaf
<!DOCTYPE html>
<html>
<head>
<title>User Profile</title>
</head>
<body>
<h1>User Profile</h1>
<p>User ID: ${user.id}</p>
<p>Username: ${user.username}</p>
<p>Email: ${user.email}</p>
</body>
</html>
model.attribute๋ก user๋ฅผ view์ ์ ๋ฌํ ๋๋ถ์ user.id, username, email๋ฅผ ์ฌ์ฉํ ์ ์๋ ๊ฒ!