
โ
์์ธ์์ดํฐ๋?
์ด์ ํ๊ฒฝ์์ ๋ฐ์ํ ์ ์๋ ์ฅ์ ์ ๋๋นํด ์คํ๋ง ๋ถํธ๊ฐ ์ ๊ณตํ๋ ํ๋ก๋์
์ค๋น ๊ธฐ๋ฅ๋ค์ด๋ค. ํ์ฌ ์ ํ๋ฆฌ์ผ์ด์
์ด ์ด์์๋์ง, ๋ก๊ทธ ์ ๋ณด๊ฐ ์ ์ ์ค์ ๋์๋์ง, ์ปค๋ฅ์
ํ์ด ์ผ๋ง๋ ์ฌ์ฉ๋๊ณ ์๋์ง ๋ฑ์ ํ์ธํ ์ ์๊ฒ ๋์์ค๋ค. ๋ ๋์๊ฐ ๋ง์ดํฌ๋ก๋ฏธ์ด, ํ๋ก๋ฉํ
์ฐ์ค, ๊ทธ๋ผํ๋ ๊ฐ์ ์ต๊ทผ ์ ํ ๋ชจ๋ํฐ๋ง ์์คํ
๊ณผ ์ฌ์ด ์ฐ๋์ ์ ๊ณตํ๋ค.
โ
์ค๋น
์์ธ์์ดํฐ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ build.gradle์ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ถ๊ฐํด์ผํ๋ค.
implementation 'org.springframework.boot:spring-boot-starter-actuator'
ํน์ spring initializr์์ ์์ฑํ ๋ actuator๋ฅผ ์ถ๊ฐํด ์ค๋ค.
โ ํ์ธ
http://localhost:8080/actuator
์์ธ์์ดํฐ๊ฐ ์ ๋๋ก ๋์ํ๋์ง ํ์ธํ๊ธฐ ์ํด์๋ Main ํด๋์ค๋ฅผ ์คํํ๋ค http://localhost:8080/actuator ๋ก ์ ์ํ์ฌ ํ์ธํ ์ ์๋ค.
โ ์ก์ธ์์ดํฐ์ ๊ธฐ๋ฅ๋ค์ ์น์ ๋ ธ์ถ
management:
endpoints:
web:
exposure:
include: "*"

์ฐธ๊ณ ์๋ฃ : [Spring] ์คํ๋ง๋ถํธ ์์ธ์์ดํฐ(Actuator)๋?
โ
MVC๋?
MVC๋ Model-View-Controller์ ์ฝ์ด๋ก, ์ ํ๋ฆฌ์ผ์ด์
์ ์ธ ๋ถ๋ถ์ผ๋ก ๋๋์ด ์ญํ ์ ๋ถ๋ฆฌํ๋ ๋์์ธ ํจํด์ด๋ค.
| ํจํด | ์ญํ |
|---|---|
| Model | ๋น์ฆ๋์ค ๋ก์ง๊ณผ ๋ฐ์ดํฐ, ์ ํ๋ฆฌ์ผ์ด์ ์ ์ํ๋ฅผ ์๋ฐ ๊ฐ์ฒด๋ก ํํํ๊ณ ์กฐ์ํ๋ ๊ธฐ๋ฅ์ ๋ด๋นํ๋ค. |
| View | HTML, CSS, JavaScript ๋ฑ์ ์ฌ์ฉํด ์ฌ์ฉ์๊ฐ ๋ณผ ์ ์๋ ํ๋ฉด์ ๊ตฌ์ฑํ๋ฉฐ, Thymeleaf์ ๊ฐ์ ํ ํ๋ฆฟ ์์ง์ ํตํด ๋์ ํ๋ฉด์ ์์ฑํ๋ค. |
| Controllerใ ค | ์ฌ์ฉ์์ ์์ฒญ์ ๋ฐ์ Model๊ณผ ์ํธ์์ฉํ๊ณ , ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ View์ ์ ๋ฌํ๋ ์ค๊ฐ ์ญํ ์ ํฉ๋๋ค. |
โ
Thymeleaf ๋
ํ์๋ฆฌํ(Thymeleaf)๋ Java ์น ์ ํ๋ฆฌ์ผ์ด์
๊ฐ๋ฐ์ ์ฌ์ฉ๋๋ ์๋ฒ์ฌ์ด๋ ํ
ํ๋ฆฟ ์์ง์
๋๋ค. HTML, XML, JavaScript, CSS ๋ฑ ๋ค์ํ ํ์์ ํ์ผ์ ๋์ ์ผ๋ก ์ฒ๋ฆฌํ์ฌ ๋ทฐ๋ฅผ ์์ฑํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. ํนํ, ์๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ HTML์ ๋์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฃผ์
ํ์ฌ ์น ํ์ด์ง๋ฅผ ๊ตฌ์ฑํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค.
โ
service
๋น์ฆ๋์ค ๋ก์ง์ ๋ด๋นํ๋ค. ์ปจํธ๋กค๋ฌ์์ ๋ถ๋ฆฌ๋์ด ์ฌ์ฌ์ฉ ๋ฐ ์ ์ง๋ณด์์ ์ฉ์ดํ๋ค.
๋ณต์กํ ์ฐ์ฐ, ์กฐ๊ฑด ๋ถ๊ธฐ, ์ธ๋ถ api ํธ์ถ ๋ฑ์ ๋ก์ง์ service ์ ์์ฑํ๋ฉด, ์ปจํธ๋กค๋ฌ๋ ์์ฒญ-์๋ต์ฒ๋ฆฌ์๋ง ์ง์คํ ์ ์์ด ์ฝ๋๊ฐ ๋ ๊น๋ํ๊ณ ๋ช
ํํด์ง๋ค.
โน๏ธ ์ ๋ฆฌํ๋ฉด Service ๊ณ์ธต์ ๋ค์๊ณผ ๊ฐ์ ์ญํ ์ ํฉ๋๋ค:
โ
controller
์ฌ์ฉ์์ ์์ฒญ์ ๋ฐ์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๊ณ , ๊ฒฐ๊ณผ๋ฅผ ๋ทฐ์ ์ ๋ฌํ๋ ์ญํ ์ ํ๋ค. ์ฆ, ์ฌ์ฉ์ ์
๋ ฅ์ ํด์ํ๊ณ ์ ์ ํ ์๋น์ค ๋ก์ง์ ํธ์ถํ๋ฉฐ, ๊ทธ ๊ฒฐ๊ณผ๋ฅผ Thymeleaf ๋ทฐ์ ๋๊ฒจ์ฃผ๋ ์ค๊ฐ ๋ค๋ฆฌ ์ญํ ์ ์ํํ๋ค.
โน๏ธ ์ปจํธ๋กค๋ฌ๋ ๋ค์๊ณผ ๊ฐ์ ์ฑ ์์ ๊ฐ์ง๋ค:
โ
Thymeleaf
์ฌ์ฉ์์ ์
๋ ฅ๊ฐ์ ํผ์ ํตํด ์๋ฒ๋ก ์ ์กํ๊ณ , ๊ฒฐ๊ณผ ๋๋ ์๋ฌ ๋ฉ์์ง๋ฅผ ๋์ ์ผ๋ก ํ๋ฉด์ ์ถ๋ ฅํ๋ค. th:action์ ํตํด ์๋ฒ ๊ฒฝ๋ก๋ฅผ ์ง์ ํ๊ณ , th:text, th:if ๋ฑ์ ์ฌ์ฉํด ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ๊ตฌํํ๋ค.
โ ํ์ผ๊ตฌ์กฐ
๐ฆsrc
โฃ ๐main
โ โฃ ๐java
โ โ โ ๐com
โ โ โ โ ๐j797
โ โ โ โ โ ๐ซcalculator
โ โ โ โ โ โฃ โ
controller
โ โ โ โ โ โ โ ๐CalculatorController.java
โ โ โ โ โ โฃ โ
service
โ โ โ โ โ โ โ ๐CalculatorService.java
โ โ โ โ โ โ ๐CalculatorApplication.java
โ โ ๐resources
โ โ โฃ ๐static
โ โ โฃ ๐templates
โ โ โ โ โ
calculator.html
โ โ โ ๐application.properties
โ ๐test
โ โ ๐java
โ โ โ ๐com
โ โ โ โ ๐j797
โ โ โ โ โ ๐calculator
โ โ โ โ โ โ ๐CalculatorApplicationTests.java
โ
service
๊ณ์ฐ๊ธฐ ์ฑ๊ณผ ๊ฐ์ ๊ตฌ์กฐ์์๋ ์ฐ์ฐ ๋ก์ง์ ์ปจํธ๋กค๋ฌ๊ฐ ์๋ Service์ ์์ํจ์ผ๋ก์จ, ํ
์คํธ ์ฝ๋ ์์ฑ์ด ์ฌ์์ง๊ณ ๋ก์ง ๋ณ๊ฒฝ ์ ์ํฅ ๋ฒ์๋ฅผ ์ค์ผ ์ ์๋ค.
CalculatorService ํด๋์ค์ calculate ๋ฉ์๋๋ฅผ ๊ตฌํํ๋ค. ์ด ๋ฉ์๋๋ ๋ ๊ฐ์ double ๊ฐ์ ๋ฐ์ ์ฌ์น์ฐ์ฐ์ ์ํํ๊ณ , ์ฐ์ฐ์๊ฐ ์ ํจํ์ง ์๊ฑฐ๋ 0์ผ๋ก ๋๋๋ ๊ฒฝ์ฐ์๋ IllegalArgumentException ์์ธ๋ฅผ ๋ฐ์์ํจ๋ค.@Service
public class CalculatorService {
public double calculate(double num1, double num2, String operation) {
switch (operation) {
case "add":
return num1 + num2;
case "subtract":
return num1 - num2;
case "multiply":
return num1 * num2;
case "divide":
if (num2 == 0) {
throw new IllegalArgumentException("0์ผ๋ก ๋๋ ์ ์์ต๋๋ค.");
} else {
return num1 / num2;
}
default:
throw new IllegalArgumentException("ํ์ฉ๋์ง ์์ ์ฐ์ฐ์์
๋๋ค." + operation);
}
}
}
โ
controller
์ฌ์ฉ์๊ฐ ์
๋ ฅํ ์ซ์์ ์ฐ์ฐ์๋ @RequestParam์ ํตํด ์ปจํธ๋กค๋ฌ๋ก ์ ๋ฌ๋๋ฉฐ, ์ปจํธ๋กค๋ฌ๋ ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก CalculatorService์ calculate ๋ฉ์๋๋ฅผ ํธ์ถํ๋ค. ๊ฒฐ๊ณผ๊ฐ์ด๋ ์์ธ ๋ฉ์์ง๋ Model ๊ฐ์ฒด์ ๋ด์ ํ
ํ๋ฆฟ์ ์ ๋ฌํ์ฌ ์ฌ์ฉ์์๊ฒ ํผ๋๋ฐฑ์ ์ ๊ณตํ๋ค.
@PostMapping("/calculate") ๋ฉ์๋๋ ์ฌ์ฉ์๋ก๋ถํฐ ์
๋ ฅ๋ฐ์ ์ซ์์ ์ฐ์ฐ์ ๊ฐ์ @RequestParam์ผ๋ก ๋ฐ์ CalculatorService์ calculate ๋ฉ์๋๋ฅผ ํธ์ถํ๋ค. ๊ฒฐ๊ณผ๊ฐ์ Model ๊ฐ์ฒด์ ๋๊ฒจ ๋ทฐ๋ก ์ ๋ฌ๋๋ค.@Controller
public class CalculatorController{
private final CalculatorService calculatorService;
<@Autowired
public CalculatorController(CalculatorService calculatorService) {
this.calculatorService = calculatorService;
}
@GetMapping("/")
public String showCalculator() {
return "calculator"; // ํ์๋ฆฌํ html ๋ฐํ
}
@PostMapping("/calculate")
public String calculate(
@RequestParam("num1") double num1,
@RequestParam("num2") double num2,
@RequestParam("operation") String operation,
Model model
) {
try {
double result = calculatorService.calculate(num1, num2, operation);
System.out.println("clicked!" + result);
model.addAttribute("result", result);
} catch(IllegalArgumentException e) {
model.addAttribute("errorMessage", e.getMessage());
}
return "calculator";
}
}
โ Thymeleaf
๊ณ์ฐ๊ธฐ ์ฑ์ ๋ทฐ๋ Thymeleaf ํ
ํ๋ฆฟ์ผ๋ก ๊ตฌ์ฑ๋๋ฉฐ, ์ฌ์ฉ์์ ์
๋ ฅ๊ฐ์ ํผ์ ํตํด ์๋ฒ๋ก ์ ์กํ๊ณ , ๊ฒฐ๊ณผ ๋๋ ์๋ฌ ๋ฉ์์ง๋ฅผ ๋์ ์ผ๋ก ํ๋ฉด์ ์ถ๋ ฅํ๋ค. th:action์ ํตํด ์๋ฒ ๊ฒฝ๋ก๋ฅผ ์ง์ ํ๊ณ , th:text, th:if ๋ฑ์ ์ฌ์ฉํด ์กฐ๊ฑด๋ถ ๋ ๋๋ง์ ๊ตฌํํ๋ค.
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Simple Calculator</title>
</head>
<body>
<h1>Simple Calculator</h1>
<form th:action="@{/calculate}" method="post">
<!--id๋ label๊ณผ ๋งค์นญ, name์ controller/@RequestParam๊ณผ ๋งค์นญ-->
<label for="num1">Number 1:</label>
<input type="number" step="any" name="num1" id="num1" required />
<label for="num2">Number 2:</label>
<input type="number" step="any" name="num2" id="num2" required />
<label for="operation">Operation:</label>
<select name="operation" id="operation">
<!--value๋ฅผ ๋ฐํ-->
<option value="add">Add (+)</option>
<option value="subtract">Subtract (-)</option>
<option value="multiply">Multiply (ร)</option>
<option value="divide">Divide (รท)</option>
</select>
<button type="submit">Calculate</button>
</form>
<!--Model์ ๊ฐ์ด ์์ผ๋ฉด ๊บผ๋ด์จ๋ค-->
<div th:if="${errorMessage}" class="error">
<p th:text="${errorMessage}"></p>
</div>
<div th:if="${result}" class="result">
<h2>Result: <span th:text="${result}"></span></h2>
</div>
</body>
</html>