실습
Controller
@Controller
public class TController {
// @ResponseBody
// @GetMapping("/params1")
// String showPram1(HttpServletResponse req) {
// String name =
// System.out.println("name =" + name);
// }
@ResponseBody
@GetMapping("/params1")
public String showParam1(HttpServletRequest req) {
System.out.println("/param1");
String name = req.getParameter("name");
return "";
}
// localhost:8080/params2?name=...
@ResponseBody
@GetMapping("/params2")
public String showParams2(@RequestParam(name = "name") String name ) {
System.out.println("/params2");
System.out.println("name = " + name);
return "";
}
//required = false로 두면 name을 강요하지 않음
//age에서 강요는 하지 않지만 값은 가지고 시작했으면 좋겠을 때defaultValue에 값
@ResponseBody
@GetMapping("/params3")
public String showParams3(
@RequestParam(name = "name", required = false) String name,
@RequestParam(name = "age", required = false, defaultValue = "1") int age
) {
System.out.println("/params3");
System.out.println("name = " + name);
System.out.println("age = " + age);
return "";
}
// 로그인 할 때
// id ,비밀번호 <- 객체로 관리 가능
//@ModelAttribute를 붙히면 info에 값을 받기위한 값이라고 Spring이 인지해서 bean으로 등록
// 값을 받기위해서는 SignForm클래스에서 주입받기 위한 Setter가 필요한데 @Data를 붙히면 그역할을 대신해줄 수 있음
@ResponseBody
@GetMapping("/params4")
public String showParams4(@ModelAttribute SignForm info) {
System.out.println("username = " + info.getUsername());
return "";
}
@Data
class SignForm { // VO(Value Object)
private String username;
private int password;
}
//DTO vs VO
//@ModelAttribute를 안붙혀도 info 자리에 들어가면 Spring이 알아서 인지함
@ResponseBody
@GetMapping("/params5")
public String showParams5(SignForm info) {
System.out.println("username = " + info.getUsername());
return "";
}
// 여러값을 받는 방법 객체로 받으면됨
@ResponseBody
@GetMapping("/params6")
public String showParams6(@RequestParam(name = "favorite") String[] favorites) {
System.out.println("/params6");
//
for (String favorite : favorites) {
System.out.println("favorite = " + favorite);
}
return "";
}
}
경로 변수
// 경로 변수
@Controller
public class T2Controller {
// REST API
// /boards/공지사항/posts/1의 url을 받을 때 -> 게시글이 늘어가면 1에서 계속해서 늘어남 이때 해결방법
// pathVariable -> @PathVariable
@ResponseBody
@GetMapping("/boards/공지사항/posts/{id}")
public String showPathV(@PathVariable(name = "id") int id) {
System.out.println("id = " + id);
return "";
}
//같은경로 요청이 2개가 들어오면 더 구체적인 쪽을 실행
// ex) /path1/ 과 /path1/test가 있다면 /path1/test을 요청했을 때 /path1는 무시
//path2/mango
//path2
// 이렇게하면 2가지 url을 받았을 때 쓰는 기능을 정의할 수 있음 /Dpath와 /path2/{name}
@ResponseBody
@GetMapping(value = { "/Dpath", "/path2/{name}"})
public String showPathV2(@PathVariable(name = "name", required = true) String name) {
System.out.println("name = " + name);
return "";
}
//Optional을 사용해서 값이 비어있다면 null로 받고 있다면 받도록 설정할 수 있음
@ResponseBody
@GetMapping(value = {"/Dpath2", "/path3/{name}"})
public String showPathV3(
@PathVariable(name = "name") Optional<String> name
) {
System.out.println("/path3 =" + name.orElse("null"));
System.out.println("/name = " + name.orElse("null"));
return "";
}
// GetMapping의 {name} 과 @PathVariable의 변수 name이 같다면 자동으로 연결해 준다.
@ResponseBody
@GetMapping("/path4/{name}")
public String showPathV4(@PathVariable String name) {
System.out.println("/path4/" + name);
System.out.println("name = " + name);
return "";
}
}
Controller 와 service 연
@Controller
@RequiredArgsConstructor
public class T3Controller {
private final TService service;
@ResponseBody
@GetMapping("/sum")
public String result(Numbers numbers) {
int result = service.sum(numbers);
return "";
}
@Data
public class Numbers {
private int a;
private int b;
}
}
@Service
public class TService {
// public int sum(int a, int b) {
// return a + b;
// }
public int sum(T3Controller.Numbers numbers) {
return numbers.getA() + numbers.getB();
}
}
Thymeleaf
thymeleaf 문법1
java파일
@Controller
public class Thymeleaf1 {
public String prefix = "/thymeleaf";
@GetMapping("/")
public String index() {
return "index";
}
// Model로 model을 스프링이 자동으로 넣어줌
@GetMapping("/1")
public String page1(Model model) {
// model을 key와 value로 값을 받음
model.addAttribute("key", "model의 값 입니다.");
return prefix + "/page1";
}
@GetMapping("/2")
public String page2(Post post, Model model) {
model.addAttribute("post", post);
return prefix + "/page2";
}
@Data
class Post {
private String title;
private String content;
}
// utext가 위험한 이유 (Escape처리를 안한 text)
@GetMapping("/3")
public String page3(Post post, Model model) {
String unsafe = "<script>alert('해킹');</script>";
model.addAttribute("script", unsafe);
return prefix + "/page3";
}
}
html 파일
//index
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div th:each = "index : ${#numbers.sequence(1,11)}">
<a th:href="@{~/thymeleaf/{idx}(idx=${index})}">viewpage[[${index}]]</a>
</div>
</body>
</html>
// 1번 model 객체로 받아온 key값에 해당하는 value값을 출력
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>page1</title>
</head>
<body>
<!-- model atrribute에서 받아온 해당하는 key값의 value를 가져옴-->
<h1 th:text="${key}">나는 페이지1</h1>
</body>
</html>
// 2번 model 객체로 전달받은 post의 변수를 사용
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>page2</title>
</head>
<body>
<h1 th:text="${post.getTitle()}">게시물 제목</h1>
<div>
<span th:text="${post.getContent()}"> 내용</span>
</div>
</body>
</html>
// 3번 escape 처리를 안한 utext에 자바스크립트 코드가 그대로 들어와서 변경됨
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>page3</title>
</head>
<body>
<div th:text ="${script}">1번</div>
<!-- 컨트롤러에서 만든 script코드가 반영되어 버림-->
<div th:utext ="${script}">2번</div>
</body>
</html>
thymeleaf 문법2
java파일
@Controller
//@RequestMapping을 사용하면 항상 url Mapping할 때 맨 앞에 /view의 값이 붙음
@RequestMapping("/thymeleaf")
public class ThymeLeaf2 {
public String prefix = "/thymeleaf";
@GetMapping("/5") // /view/1 과 같음
public String syntaxPage1(Model model) {
model.addAttribute("username", "Hello World");
return prefix+"/page5";
}
@GetMapping("/6")
public String syntaxPage2(Model model) {
List<String> shopList = Arrays.asList("양파", "돈");
model.addAttribute("shopList", shopList);
return prefix + "/page6";
}
//post 값을 넣어 생성하여 view로 전달
@GetMapping("/7")
public String syntaxPage3(Model model) {
Post post = new Post(1, "안녕하세요", "content");
model.addAttribute("post", post);
return prefix + "/page7";
}
// view로 생성된 post를 전달
@GetMapping("/8")
public String syntaxPage4(Model model) {
model.addAttribute("post",new Post());
return prefix + "/page8";
}
// view에서 post로 전달받은 객체를 전달받아 줄력
@PostMapping("/9")
public String syntaxPage5(Post post, String content) {
System.out.println("post = " + post);
System.out.println("content = " + content);
return "index";
}
@GetMapping("/10")
public String syntaxPage6() {
return prefix + "/thpage1";
}
@GetMapping("/11")
public String syntaxPage7(int target, Model model) {
model.addAttribute("target", target);
return prefix + "/thpage2";
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Post {
private int id;
private String title;
private String content;
}
html 파일
// 5번 th:if문 조건을 만족하면 실행 thLunless문 조건을 불만족하면 실행하지 않음
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
<span th:if="username != null"> [[${username}]] 회원님! 반갑습니다.</span>
<span th:unless="username != null"> 회원이 없습니다.</span>
</div>
</body>
</html>
//6번 컬렉션도 전달 가능
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>page6</title>
</head>
<body>
<h2>물건</h2>
<ul>
<li th:each = "item : ${shopList}" th:text="${item}"></li>
</ul>
</body>
</html>
//7번 th:object를 상속받은 자식 태그부터 getTitle,post.title을 하지 않아도 해당 객체에 전달받은 필드 값을 바로 사용가능
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>문법 페이지 3</title>
</head>
<body>
<!-- th:object : wrapper클래스 하위 태그에 post라는 객체를 적용시켜줄꺼야-->
<div class="wrapper" th:object="${post}">
<h2 th:text="*{title}">제목란</h2>
<hr />
<h4> [[ *{id} ]] 번 게시글, 작성자 : </h4>
<div class="contents">
<p th:text="*{content}"></p>
</div>
</div>
</body>
</html>
//8번
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>게시글 작성</title>
</head>
<body>
<div> 게시물 작성</div>
<form th:action="@{/page/5}" method ="post">
<div>
<label for="title">제목 : </label>
<input id="title" type="text" name="title">
</div>
<div>
<textarea name = "content" cols="30" rows="10"></textarea>
</div>
<div>
<button type="submit">작성</button>
</div>
</form>
</body>
</html>
//9번 8번에서 전달받은 post에 값을 담아 다시 Post방식으로 넘겨준다.
//10번
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul>
<li>
<a th:href="@{~/page/1}"> page1</a>
</li>
<!-- #numbers.sequence [1,2,3,4] 배열 자동으로 생성-->
<li th:each = " idxx : ${#numbers.sequence(1,4)}">
<a th:href="@{~/view/{idx}(idx=${idxx})}" >view[[${idxx}]]</a>
</li>
</ul>
</body>
</html>
//11번
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--html 내부에서 변수를 만들고 싶을 때 th:with-->
<div th:with="name = '구구단'">
<h2 th:text="${name}"></h2>
<h3>[[${target}]]</h3>
<div>
<!-- th:block 어떤 태그를 써야할지 애매할 때 넣는다-->
<th:block th:each="idx : ${#numbers.sequence(1,9)}">
<p>[[ ${target} ]] X [[ ${idx}]] = [[ ${target} * ${idx}]]</p>
</th:block>
</div>
</div>
</body>
</html>
'Spring' 카테고리의 다른 글
| [오르미 백엔드7기](Spring 프록시객체, 지연로딩 ,즉시로딩, 영속성전이, N+1문제) (1) | 2024.11.25 |
|---|---|
| [오르미 백엔드 7기] (Spring Entity 개념, 연관관계, 공통속성정의) (0) | 2024.11.25 |
| [오르미 백엔드7기] (Spring JPA 기본,ORM이란? , JDBC) (0) | 2024.11.22 |
| [오르미 백엔드 7기](POJO, SPRING @Controller, Thymeleaf + CS지식(CSR, SSR)) (1) | 2024.11.18 |
| [오르미 백엔드7기] (Spring DI, IOC, AOP, Annotation) (0) | 2024.11.14 |