Java 객체 : new 연산자에 의해 Heap 영역에 클래스에 작성된 내용대로 생성된 것
instance : 개발자가 직접 만들고, 관리하는 객체
Bean : Spring Container가 만들고, 관리하는 객체
Spring 의 Controller 메서드 작성 시 매개변수에 원하는 객체를 작성하면
존재하는 객체를 바인딩(연결) 또는 없으면 생성해서 바인딩
--> ArgumentResolver (전달 인자 해결사)
public String paramTest1(HttpServletRequest req)
// 이렇게 매개변수 자리에 req전달 시
String inputName = req.getParameter("inputName");
String inputAddress = res.getParameter("inputAddress");
// inputName과 inputAddress라는 키 전달 시 해당 키에 있는 값을 리턴해줌
▶ 요청주소를 처리할 메서드를 매핑하는 어노테이션
// 1) @RequestMapping("주소")
// 2) @GetMapping("주소") : Get (조회) 방식 요청 매칭
ex) @GetMapping("ex3/{number}")
public String pathVariableTest( @PathVariable("number") int number ) {
// 주소 중 {number} 부분의 값을 가져와서 매개변수로 저장
// controller 에서 사용할 수 있도록 해줌
// + request Scope에 자동 세팅도 해줌
@PostMapping("주소") : Post (삽입) 방식 요청 매핑
@PutMapping("주소") : Put (수정) 방식 요청 매핑 (form, a태그 요청 불가)
@DeleteMapping("주소") : Delete (삭제) 방식 요청 매핑 (form, a태그 요청 불가)
1) 메서드에 작성 :
@RequestMapping(value="/hello", method=RequestMethod.POST)
public String hello() {
// 메서드 로직
return "경로..";
}
2) 클래스에 작성
@RequestMapping("/todo")
public class 클래스명 {
@RequestMapping("/insert") // /todo/insert 매핑
public String 메서드명() {}
@RequestMapping("/select") // /todo/select 매핑
public String 메서드명() {}
@RequestMapping("/update") // /todo/update 매핑
public String 메서드명() {}
}
‣ 메서드에서 반환되는 문자열이 forward 할 html 파일의 경로가 되기 때문!
Thymeleaf : JSP 대신 사용하는 템플릿 엔진(html 형태)
classpath : src/main/resources
접두사 : classpath:/templates/
접미사 : .html
ex) return "test"; // --> 접두사 + 반환값 + 접미사 경로의 html로 forward
== src/main/resources/templates/test.html
타임리프의 접두사, 접미사, forward 설정은 View Resolver 객체가 담당!
‣ Controller 메서드 반환 값에 "redirect:요청주소"; 작성
- 템플릿 양식과 특정 데이터 모델에 따른 입력자료를 합성하여 결과 문서(응답 화면)를 출력하는 것
→ 만들어 둔 화면(html)에 데이터를 추가하여 하나의 html로 만들어서 응답 (JSP도 템플릿 엔진)
[ 타임리프 특수 속성 ]
th문법(표현식) : xmlns:th="http://www.thymeleaf.org"
th속성을 사용하기 위해 선언된 네임스페이스로
th속성 사용하기 전 head태그 상단에 선언해주기 !
${key} : 변수, Model 등을 이용해서 세팅한 값 출력${Student.getName()} == ${Student.name} th 속성은 출력된 화면에서 보여지지 않는다 ! → 해석된 후 사라짐 !!
- 웹 및 독립 실행형 환경을 모두 지원하는 최신 서버 측 Java 템플릿 엔진
→ 웹 실행 == 요청 시 포워드 되는 화면
→ 독립 실행 == html 파일만 실행
- HTML 파일에서 th(Thymeleaf) 속성을 이용해
컨트롤러로부터 전달 받은 데이터를 이용해 동적 페이지를 만들 수 있음
Spring Boot에서는 JSP가 아닌 Thymeleaf 사용을 권장하고 있음
org.springframeword.ui 패키지에 존재@SessionAttribute 와 함께 사용 시 session scope 변환 (session으로 확장 가능)▶ 기본 사용법
Model.addAttribute("key", value);
// 단일 값(숫자, 문자열) Model 을 이용해서 html로 전달
model.addAttribute("productName", "종이컵");
model.addAttribute("price", 2000);
[html]
<span class="price">
<th:block th:text="${price}">가격</th"block> 원
// 복수 값(배열, List) Model 을 이용해서 html로 전달
List<String> fruitList = new ArrayList<>();
fruitList.add("사과");
fruitList.add("딸기");
fruitList.add("바나나");
model.addAttribute("fruitList", fruitList);
[html]
<ul>
<th:block th:each="fruit : ${fruitList}"
<li th:text="${fruit}">과일명</li> <!-- 사과, 딸기, 바나나 각각 출력 -->
</ul>
// DTO 객체를 Model 을 이용해서 html로 전달
Student std = new Student();
std.setStudentNo("12345");
std.setName("홍길동");
std.setAge(22);
model.addAttribute("std", std);
[html]
<ul th:object="${std}">
<li th:text="*{stdentNo}">학번</li>
<li th:text="*{name}">이름</li>
<li th:text="*{age}">나이</li>
</ul>
// List<Student> 객체를 Model 을 이용해서 html로 전달
List<Student> stdList = new ArrayList<>();
stdList.add(new Student("11111", "김일번", 20));
stdList.add(new Student("22222", "최이번", 23));
stdList.add(new Student("33333", "홍삼번", 22));
model.addAttribute("stdList", stdList);
[html]
<table border="1">
<thead>
<tr>
<th>학번</th>
<th>학번</th>
<th>학번</th>
</tr>
</thead>
<tbody>
<!-- th:each가 설정된 태그부터 반복(tr부터 반복) -->
<tr th:each="std : ${stdList}" th:object="${std}">
<td th:text="*{studentNo}">학번</td>
<td th:text="*{name}">이름</td>
<td th:text="*{age}">나이</td>
<!-- List 3요소
0번 인덱스 -> Student -> 김일번
1번 인덱스 -> Student -> 최이번
2번 인덱스 -> Student -> 홍삼번
-->
</tr>
</tbody>
ModelAttribute와 전혀 관련 없음 !!!!!!!!!!
[ 낱개 파라미터 컨트롤러에서 얻어오기 ]
▶ 기본 작성법
@RequestParam("key") 자료형 매개변수명
→ ex) @RequestParam("title") String title
▶ 속성 추가 작성법
@RequestParam(value="name", required="false", defaultValue="1")
value : 전달받은 input 태그의 name 속성값 (파라미터 key)
required : 입력된 name 속성값 파라미터 필수 여부 지정 (기본값 true)
-> required = true 인 파라미터가 존재하지 않는다면
(파라미터 값 전달하지 않는다면)
400 Bad Request 에러 발생
defaultValue : 파라미터 중 일치하는 name 속성값이 없을 경우에 대입할 값 지정
-> required = false 인 경우 사용
defaultValue = "10000" 지정 시 값 전달하지 않아도
에러 발생하지 않고 기본값으로 10000이 넘어감
[ 여러 개 파라미터 컨트롤러에서 얻어오기 ]
▶ String[ ]
▶ List<String>
▶ Map<String, Object> ➡ - 제출된 모든 파라미터가 Map에 저장된다
- key(name속성값)가 중복되면 덮어쓰기가 된다!
- 같은 name속성 파라미터가 String[ ], List로 저장이 안 되고
String[ ], List 형태라면 처음에 체크한 값으로 넘어온다
@RequestParam 이용 시 참고사항 !
ex) form 태그 안에서 input 태그를 이용해서 테스트 중..
String형은 값 전달하지 않아도 에러발생하지 않음.
파라미터로는 title=""&writer=""&...
-> 빈 문자열로 넘어감. 파라미터가 없는 게 아님!
-> required=true에 위배되지 않는 것.
@ModelAttribute 를 이용해 값이 필드에 세팅된 객체를 "커멘드 객체" 라고 부른다@ModelAttribute 어노테이션 생략 가능!→ (@ModelAttribute DTO타입 작성 객체명(변수명 같은 거라 내 맘대로 써도 됨))
@ModelAttribute 이용 시 참고사항 !
반환값을 HTTP 응답 본문으로 직접 전송(값 그대로 돌려보낼 거야!!!)
컨트롤러 메서드 반환 값을 Http 응답 본문에 직접 바인딩하는 역할임을 명시
컨트롤러 메서드의 반환 값을
비동기 요청했던 HTML/JS 파일 부분에 값을 돌려보낼 것이다!! 명시
→ 해당 어노테이션이 붙어있는 컨트롤러의 메서드는
반환값이 forward/redirect가 아니다 라고 인식함
만약 return에 0; 이라고 작성한다면 0이라는 값이 첫번째 then의 response 로 들어옴
getSize() : 파일 크기isEmpty() : 업로드 한 파일이 없을 경우 true / 있다면 false 반환getOriginalFileName() : 원본 파일명transferTo(경로) : 메모리 또는 임시 저장 경로에 업로드 된 파일을스프링 설정용 클래스임을 명시(스프링이 해당 클래스를 설정 정보로 인식하고 사용)
+ 객체로 생성해서 내부 코드를 서버 실행 시 모두 바로 실행
config 파일에 이 어노테이션이 전부 있어야 한다!!
→ classpath:/ 는 src/main/resources 경로를 의미!
발자가 수동으로 생성한 객체의 관리를 스프링에게 넘기는 어노테이션(Bean) 등록
→ 개발자가 직접 객체 만들었지만 (new)
→ Bean으로 등록해서 Spring이 관리하도록 해줌!
@Bean 어노테이션이 작성된 메서드에서 반환된 객체는 Spring Container가 관리함(IOC)
@ConfigurationProperties(prefix = "spring.datasource.hikari")
properties 파일의 내용을 이용해서 생성되는 bean을 설정하는 어노테이션
prefix를 지정하여 spring.datasource.hikari으로 시작하는 설정을 모두 적용
@PropertySource 로 읽어온 config.properties 파일의 내용 중@Mapper 어노테이션
MyBatis 에서 제공하는 어노테이션
MyBatis가 해당 인터페이스를 DAO로 인식하여 SQL 매핑을 처리
해당 어노테이션이 작성된 인터페이스는 namespace에 해당 인터페이스가 작성된
mapper.xml 파일과 연결되어 SQL 호출/수행/결과 반환 가능
MyBatis에서 제공하는 Mapper 상속 객체가 Bean으로 등록됨
@Mapper를 사용할 때 @Repository 는 필요하지 않음
-> MyBatis가 DAO 객체로 Mapper 인터페이스를 관리하기 때문
@SessionAttributes({"loginMember"})
.
.
.
model.addAttribute("loginMember", loginMember);
loginMember가 session scope로 변경됨 !
public String logout(SessionStatus status) {
status.setComplete();
// 세션을 완료시킴 (== 세션에서 @SessionAttributes로 등록된 세션 제거)
session scope로 변경됐던 loginMember가 제거됨 !
구글에 error code 검색 후 MDN Web Docs의 HTTP 상태 코드 누르면 에러 종류별 설명이 적혀있음. 이거 보고 에러 추적하면 된당
ModelAttribute
파라미터 키랑 필드명이 같을 때 Key == 필드명 --> Value를 setter를 이용해서 넣어줌