├── .gitignore
├── LICENSE
├── README.md
├── ch1
└── readme.md
├── ch2
├── Ch2Application.java
├── HomeController.java
├── LoginController.java
├── Main.java
├── MyDate.java
├── PerformanceFilter.java
├── PerformanceInterceptor.java
├── RequestInfo.java
├── RequestParamTest.java
├── WebMvcConfig.java
├── YoilTeller.java
├── footer.html
├── header.html
├── index.html
├── login.html
├── main.css
├── mainLayout.html
├── readme.md
├── userInfo.html
└── yoil.html
├── ch3
└── readme.md
├── ch4
├── ManyToOneTest.java
├── application.properties
├── list.html
├── pom.xml
├── read.html
├── readme.md
├── uploadFile.html
└── write.html
└── download
├── boot_ch02_13_filter_interceptor_print.pdf
├── boot_ch02_16_thymeleaf 알아보기_print.pdf
├── boot_ch3_10_DB모델링4_print.pdf
├── boot_ch3_2_의존성관리_자동설정4_print.pdf
├── boot_ch3_final.zip
├── boot_ch4.final.zip
├── boot_ch4_01_JPA개요4_print.pdf
├── boot_ch4_04_SpringDataJpa_final_print.pdf
├── ch2.zip
└── readme.md
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # BlueJ files
8 | *.ctxt
9 |
10 | # Mobile Tools for Java (J2ME)
11 | .mtj.tmp/
12 |
13 | # Package Files #
14 | *.jar
15 | *.war
16 | *.nar
17 | *.ear
18 | *.zip
19 | *.tar.gz
20 | *.rar
21 |
22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
23 | hs_err_pid*
24 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 SEONG NAMKUNG
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | > # 남궁성의 Spring Boot 강좌 - 기본편
2 | > Spring Boot 입문자를 위한 최고의 강좌 - https://fastcampus.co.kr/dev_academy_nks2
3 | > Spring framework 강좌 - 심화편(준비중)
4 | > Spring boot 강좌 - 심화편(준비중)
5 | > email : seong.namkung@gmail.com
6 | > 수강생 전용 Q&A : https://cafe.naver.com/javachobostudy?iframe_url=/ArticleList.nhn%3Fsearch.clubid=10286641%26search.menuid=221%26search.boardtype=L
7 |
8 |
9 | # Part1. Spring Boot 시작하기
10 | ## 1. 개요
11 | - ### Spring Boot란?
12 | Spring makes programming Java quicker, easier, and safer for everybody.
13 | Spring’s focus on speed, simplicity, and productivity has made it the world's most popular Java framework.
14 | https://spring.io/why-spring
15 |
16 | - ### Spring MVC란?
17 | A Spring MVC is a framework to build web applications. It follows the MVC(Model-View-Controller) design pattern.
18 | https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/mvc.html
19 |
20 | **[참고]** MVC패턴이란? https://developer.mozilla.org/ko/docs/Glossary/MVC
21 |
22 |
23 | ## 2. 개발 도구 설치 & 설정
24 |
25 | 1. JDK11 설치
26 | [자바의 정석 - 무료강의] https://youtube.com/playlist?list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp
27 |
28 | [Windows] https://download.java.net/java/ga/jdk11/openjdk-11_windows-x64_bin.zip
29 |
30 | [Mac] SDKMAN을 이용해서 openJDK설치
31 |
32 | - SDKMAN 설치 - https://sdkman.io/install
33 |
34 | ```
35 | $ curl -s "https://get.sdkman.io" | bash
36 | $ source "$HOME/.sdkman/bin/sdkman-init.sh"
37 | ```
38 |
39 | - SDKMAN 명령어
40 | ```
41 | $ sdk version <--- sdkman 버전출력
42 | $ sdk list java <-- 설치 가능 & 설치된 JDK목록
43 | $ sdk install java 11.0.12.7.2-amzn <--- 지정된 JDK설치(원하는 종류와 버전 지정)
44 | $ sdk default java 11.0.12.7.2-amzn <--- 사용할 java버전을 변경(모든 쉘에 적용)
45 | $ sdk use java 11.0.12.7.2-amzn <--- 사용할 java버전을 변경(현재 쉘에만 적용)
46 | $ sdk current java <--- 현재 사용중인 java버전 출력
47 | $ echo $JAVA_HOME <--- JAVA_HOME으로 지정된 경로 출력
48 | ```
49 | **[참고]** openJDK버전별 다운로드 - https://jdk.java.net/archive/
50 |
51 |
52 |
53 | 2. IntelliJ 설치
54 | **Windows** - https://www.jetbrains.com/idea/download/#section=windows
55 | **MacOS** - https://www.jetbrains.com/idea/download/#section=mac
56 | **MacOS M1** - https://www.jetbrains.com/idea/download/download-thanks.html?platform=macM1
57 |
58 | **[참고]** IntelliJ 학생 라이센스 - https://www.jetbrains.com/shop/eform/students
59 |
60 |
61 |
62 |
63 | 3. MySQL 설치
64 | **Windows, MacOS** - https://downloads.mysql.com/archives/community/
65 | **[참고]** MacOS(M1, M2)에 MySQL설치하는 방법 - https://codechobo.tistory.com/31
66 |
--------------------------------------------------------------------------------
/ch1/readme.md:
--------------------------------------------------------------------------------
1 | .
2 |
--------------------------------------------------------------------------------
/ch2/Ch2Application.java:
--------------------------------------------------------------------------------
1 | package com.fastcampus.ch2;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | import org.springframework.boot.web.servlet.ServletComponentScan;
6 |
7 | @SpringBootApplication
8 | @ServletComponentScan
9 | public class Ch2Application {
10 | public static void main(String[] args) {
11 | SpringApplication.run(Ch2Application.class, args);
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/ch2/HomeController.java:
--------------------------------------------------------------------------------
1 | package com.fastcampus.ch2;
2 |
3 | import org.springframework.stereotype.Controller;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 | import org.springframework.web.bind.annotation.RestController;
6 |
7 | // 1. 원격 프로그램으로 등록
8 | @RestController
9 | public class HelloController {
10 | // 2. URL과 메서드를 연결
11 | @RequestMapping("/hello")
12 | public String main() {
13 | System.out.println("Hello");
14 | return "Hello";
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/ch2/LoginController.java:
--------------------------------------------------------------------------------
1 | package com.fastcampus.ch2;
2 |
3 | import org.springframework.stereotype.Controller;
4 | import org.springframework.ui.Model;
5 | import org.springframework.web.bind.annotation.GetMapping;
6 | import org.springframework.web.bind.annotation.PostMapping;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 | import org.springframework.web.bind.annotation.RequestMethod;
9 |
10 | import java.net.URLEncoder;
11 |
12 | @Controller
13 | @RequestMapping("/login")
14 | public class LoginController {
15 | // @RequestMapping("/login/login")
16 | // @RequestMapping(value="/login/login", method=RequestMethod.GET)
17 | @GetMapping("/login")
18 | public String showLogin() {
19 | return "login"; // login.html을 화면에 보여줌
20 | }
21 |
22 | // 하나의 메서드로 GET, POST를 둘다 처리하는 경우
23 | // @RequestMapping(value="/login/login", method= {RequestMethod.GET,RequestMethod.POST})
24 | // @RequestMapping(value="/login/login", method= RequestMethod.POST) // 아래의 라인과 동일
25 | @PostMapping("/login")
26 | public String login(String id, String pwd, Model model) throws Exception{
27 | // 1. id, pwd를 확인
28 | if(loginCheck(id,pwd)) {
29 | // 2. 일치하면, userInfo.html
30 | model.addAttribute("id", id);
31 | model.addAttribute("pwd", pwd);
32 | return "userInfo" ; // userInfo.html
33 | } else {
34 | // 일치하지 않으면, login.html로 이동
35 | String msg = URLEncoder.encode("id 또는 pwd가 일치하지 않습니다.", "utf-8");
36 | return "redirect:/login/login?msg="+msg; // GET - URL재작성
37 | }
38 | }
39 |
40 | private boolean loginCheck(String id, String pwd) {
41 | return id.equals("asdf") && pwd.equals("1234");
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/ch2/Main.java:
--------------------------------------------------------------------------------
1 | package com.fastcampus.ch2;
2 |
3 | public class Main {
4 | public static void main(String[] args) {
5 | System.out.println("Hello");
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/ch2/MyDate.java:
--------------------------------------------------------------------------------
1 | package com.fastcampus.ch2;
2 |
3 | public class MyDate {
4 | private int year;
5 | private int month;
6 | private int day;
7 |
8 | public int getYear() {
9 | return year;
10 | }
11 |
12 | public void setYear(int year) {
13 | this.year = year;
14 | }
15 |
16 | public int getMonth() {
17 | return month;
18 | }
19 |
20 | public void setMonth(int month) {
21 | this.month = month;
22 | }
23 |
24 | public int getDay() {
25 | return day;
26 | }
27 |
28 | public void setDay(int day) {
29 | this.day = day;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/ch2/PerformanceFilter.java:
--------------------------------------------------------------------------------
1 | package com.fastcampus.ch2;
2 |
3 | import javax.servlet.*;
4 | import javax.servlet.annotation.WebFilter;
5 | import javax.servlet.http.HttpServletRequest;
6 | import java.io.IOException;
7 |
8 | @WebFilter(urlPatterns = "/*") // 모든 요청에 PerformanceFilter를 적용.
9 | public class PerformanceFilter implements Filter {
10 | @Override
11 | public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
12 | // 1. 전처리 작업
13 | long startTime = System.currentTimeMillis();
14 |
15 | // 2. 서블릿(컨트롤러)또는 다음 필터
16 | filterChain.doFilter(request, response);
17 |
18 | // 3. 후처리 작업
19 | long endTime = System.currentTimeMillis();
20 | System.out.print("["+ ((HttpServletRequest)request).getRequestURI()+"]");
21 | System.out.println(" time="+(endTime-startTime));
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ch2/PerformanceInterceptor.java:
--------------------------------------------------------------------------------
1 | package com.fastcampus.ch2;
2 |
3 | import org.springframework.stereotype.Component;
4 | import org.springframework.web.method.HandlerMethod;
5 | import org.springframework.web.servlet.HandlerInterceptor;
6 | import org.springframework.web.servlet.ModelAndView;
7 |
8 | import javax.servlet.http.HttpServletRequest;
9 | import javax.servlet.http.HttpServletResponse;
10 |
11 | @Component
12 | public class PerformanceInterceptor implements HandlerInterceptor { // 단일 책임의 원칙(SRP) - 하나의 메서드는 하나의 책임만 갖는다.
13 | // long startTime; // iv - 인스턴스 변수. 싱글톤(하나의 객체)이라서 여러 쓰레드가 하나의 객체를 공유.
14 |
15 | @Override
16 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
17 | // 1. 전처리 작업
18 | long startTime = System.currentTimeMillis();
19 | request.setAttribute("startTime", startTime); // request객체에 startTime을 저장
20 |
21 | // handler - 요청하고 연결된 컨트롤러의 메서드
22 | HandlerMethod method = (HandlerMethod) handler;
23 | System.out.println("method.getMethod() = " + method.getMethod()); // URL하고 연결된 메서드
24 | System.out.println("method.getBean() = " + method.getBean()); // 메서드가 포함된 컨트롤러
25 |
26 | // return true; // 다음 인터셉터나 컨트롤러를 호출 false면 호출안함.
27 | return HandlerInterceptor.super.preHandle(request, response, handler);
28 | }
29 |
30 | @Override
31 | public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
32 | // 2. 후처리 작업
33 | long startTime = (long)request.getAttribute("startTime");
34 | long endTime = System.currentTimeMillis();
35 | System.out.print("["+ ((HttpServletRequest)request).getRequestURI()+"]");
36 | System.out.println(" time="+(endTime-startTime));
37 |
38 | HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/ch2/RequestInfo.java:
--------------------------------------------------------------------------------
1 | package com.fastcampus.ch2;
2 |
3 | import org.springframework.stereotype.Controller;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 |
6 | import javax.servlet.http.HttpServletRequest;
7 |
8 | @Controller
9 | public class RequestInfo {
10 | @RequestMapping("/requestInfo")
11 | // public static void main(String[] args) {
12 | public void main(HttpServletRequest request) {
13 | System.out.println("request.getCharacterEncoding()="+request.getCharacterEncoding()); // 요청 내용의 인코딩
14 | System.out.println("request.getContentLength()="+request.getContentLength()); // 요청 내용의 길이. 알수 없을 때는 -1
15 | System.out.println("request.getContentType()="+request.getContentType()); // 요청 내용의 타입. 알 수 없을 때는 null
16 |
17 | System.out.println("request.getMethod()="+request.getMethod()); // 요청 방법
18 | System.out.println("request.getProtocol()="+request.getProtocol()); // 프로토콜의 종류와 버젼 HTTP/1.1
19 | System.out.println("request.getScheme()="+request.getScheme()); // 프로토콜
20 |
21 | System.out.println("request.getServerName()="+request.getServerName()); // 서버 이름 또는 ip주소
22 | System.out.println("request.getServerPort()="+request.getServerPort()); // 서버 포트
23 | System.out.println("request.getRequestURL()="+request.getRequestURL()); // 요청 URL
24 | System.out.println("request.getRequestURI()="+request.getRequestURI()); // 요청 URI
25 |
26 | System.out.println("request.getContextPath()="+request.getContextPath()); // context path
27 | System.out.println("request.getServletPath()="+request.getServletPath()); // servlet path
28 | System.out.println("request.getQueryString()="+request.getQueryString()); // 쿼리 스트링
29 |
30 | System.out.println("request.getLocalName()="+request.getLocalName()); // 로컬 이름
31 | System.out.println("request.getLocalPort()="+request.getLocalPort()); // 로컬 포트
32 |
33 | System.out.println("request.getRemoteAddr()="+request.getRemoteAddr()); // 원격 ip주소
34 | System.out.println("request.getRemoteHost()="+request.getRemoteHost()); // 원격 호스트 또는 ip주소
35 | System.out.println("request.getRemotePort()="+request.getRemotePort()); // 원격 포트
36 | }
37 | }
38 |
39 | [실행결과] http://localhost:8080/ch2/requestInfo?year=2023&month=1&day=1
40 | request.getCharacterEncoding()=UTF-8
41 | request.getContentLength()=-1
42 | request.getContentType()=null
43 | request.getMethod()=GET
44 | request.getProtocol()=HTTP/1.1
45 | request.getScheme()=http
46 | request.getServerName()=localhost
47 | request.getServerPort()=8080
48 | request.getRequestURI()=http://localhost:8080/ch2/requestInfo
49 | request.getRequestURI()=/ch2/requestInfo
50 | request.getContextPath()=/ch2
51 | request.getServletPath()=/requestInfo
52 | request.getQueryString()=year=2023&month=1&day=1
53 | request.getLocalName()=localhost
54 | request.getLocalPort()=8080
55 | request.getRemoteAddr()=0:0:0:0:0:0:0:1 <--- AWS에 배포(deploy)한 다음에 실행하면, 실제 ip주소를 확인할 수 있음.
56 | request.getRemoteHost()=0:0:0:0:0:0:0:1 <--- AWS에 배포(deploy)한 다음에 실행하면, 실제 ip주소를 확인할 수 있음.
57 | request.getRemotePort()=54855
58 |
--------------------------------------------------------------------------------
/ch2/RequestParamTest.java:
--------------------------------------------------------------------------------
1 | package com.fastcampus.ch2;
2 |
3 | import java.util.Date;
4 |
5 | import javax.servlet.http.HttpServletRequest;
6 |
7 | import org.springframework.stereotype.Controller;
8 | import org.springframework.web.bind.annotation.RequestMapping;
9 | import org.springframework.web.bind.annotation.RequestParam;
10 |
11 | @Controller
12 | public class RequestParamTest {
13 | @RequestMapping("/requestParam")
14 | public String main(HttpServletRequest request) {
15 | String year = request.getParameter("year");
16 | // http://localhost/requestParam ---->> year=null
17 | // http://localhost/requestParam?year= ---->> year=""
18 | // http://localhost/requestParam?year ---->> year=""
19 | System.out.printf("[%s]year=[%s]%n", new Date(), year);
20 | return "yoil";
21 | }
22 |
23 | @RequestMapping("/requestParam2")
24 | // public String main2(@RequestParam(name="year", required=false) String year) { // 아래와 동일
25 | public String main2(String year) {
26 | // http://localhost/requestParam2 ---->> year=null
27 | // http://localhost/requestParam2?year ---->> year=""
28 | System.out.printf("[%s]year=[%s]%n", new Date(), year);
29 | return "yoil";
30 | }
31 |
32 | @RequestMapping("/requestParam3")
33 | // public String main3(@RequestParam(name="year", required=true) String year) { // 아래와 동일
34 | public String main3(@RequestParam String year) {
35 | // http://localhost/requestParam3 ---->> year=null 400 Bad Request. required=true라서
36 | // http://localhost/requestParam3?year ---->> year=""
37 | System.out.printf("[%s]year=[%s]%n", new Date(), year);
38 | return "yoil";
39 | }
40 |
41 | @RequestMapping("/requestParam4")
42 | public String main4(@RequestParam(required=false) String year) {
43 | // http://localhost/requestParam4 ---->> year=null
44 | // http://localhost/requestParam4?year ---->> year=""
45 | System.out.printf("[%s]year=[%s]%n", new Date(), year);
46 | return "yoil";
47 | }
48 |
49 | @RequestMapping("/requestParam5")
50 | public String main5(@RequestParam(required=false, defaultValue="1") String year) {
51 | // http://localhost/requestParam5 ---->> year=1
52 | // http://localhost/requestParam5?year ---->> year=1
53 | System.out.printf("[%s]year=[%s]%n", new Date(), year);
54 | return "yoil";
55 | }
56 |
57 | // =======================================================================
58 |
59 | @RequestMapping("/requestParam6")
60 | // public String main6(@RequestParam(required=false) int year) {
61 | public String main6(int year) {
62 | // http://localhost/requestParam6 ---->> 500 java.lang.IllegalStateException: Optional int parameter 'year' is present but cannot be translated into a null value due to being declared as a primitive type. Consider declaring it as object wrapper for the corresponding primitive type.
63 | // http://localhost/requestParam6?year ---->> 400 Bad Request, nested exception is java.lang.NumberFormatException: For input string: ""
64 | System.out.printf("[%s]year=[%s]%n", new Date(), year);
65 | return "yoil";
66 | }
67 |
68 | @RequestMapping("/requestParam7")
69 | public String main7(@RequestParam int year) {
70 | // http://localhost/requestParam7 ---->> 400 Bad Request, Required int parameter 'year' is not present
71 | // http://localhost/requestParam7?year ---->> 400 Bad Request, nested exception is java.lang.NumberFormatException: For input string: ""
72 | System.out.printf("[%s]year=[%s]%n", new Date(), year);
73 | return "yoil";
74 | }
75 |
76 | @RequestMapping("/requestParam8")
77 | public String main8(@RequestParam(required=false) int year) {
78 | // http://localhost/requestParam8 ---->> 500 java.lang.IllegalStateException: Optional int parameter 'year' is present but cannot be translated into a null value due to being declared as a primitive type. Consider declaring it as object wrapper for the corresponding primitive type.
79 | // http://localhost/requestParam8?year ---->> 400 Bad Request, nested exception is java.lang.NumberFormatException: For input string: ""
80 | System.out.printf("[%s]year=[%s]%n", new Date(), year);
81 | return "yoil";
82 | }
83 |
84 | @RequestMapping("/requestParam9")
85 | public String main9(@RequestParam(required=true) int year) {
86 | // http://localhost/requestParam9 ---->> 400 Bad Request, Required int parameter 'year' is not present
87 | // http://localhost/requestParam9?year ---->> 400 Bad Request, nested exception is java.lang.NumberFormatException: For input string: ""
88 | System.out.printf("[%s]year=[%s]%n", new Date(), year);
89 | return "yoil";
90 | }
91 |
92 | @RequestMapping("/requestParam10")
93 | public String main10(@RequestParam(required=true, defaultValue="1") int year) {
94 | // http://localhost/requestParam10 ---->> year=1
95 | // http://localhost/requestParam10?year ---->> year=1
96 | System.out.printf("[%s]year=[%s]%n", new Date(), year);
97 | return "yoil";
98 | }
99 |
100 | @RequestMapping("/requestParam11")
101 | public String main11(@RequestParam(required=false, defaultValue="1") int year) {
102 | // http://localhost/requestParam11 ---->> year=1
103 | // http://localhost/requestParam11?year ---->> year=1
104 | System.out.printf("[%s]year=[%s]%n", new Date(), year);
105 | return "yoil";
106 | }
107 | } // class
108 |
--------------------------------------------------------------------------------
/ch2/WebMvcConfig.java:
--------------------------------------------------------------------------------
1 | package com.fastcampus.ch2;
2 |
3 | import org.springframework.context.annotation.Configuration;
4 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
5 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
6 |
7 | @Configuration
8 | public class WebMvcConfig implements WebMvcConfigurer {
9 | @Override
10 | public void addInterceptors(InterceptorRegistry registry) {
11 | registry.addInterceptor(new PerformanceInterceptor())
12 | .addPathPatterns("/**") // 인터셉터를 적용할 대상
13 | .excludePathPatterns("/css/**", "/js/**"); // 인터셉터 적용 제외대상
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/ch2/YoilTeller.java:
--------------------------------------------------------------------------------
1 | package com.fastcampus.ch2;
2 |
3 | import org.springframework.stereotype.Controller;
4 | import org.springframework.web.bind.annotation.RequestMapping;
5 |
6 | import javax.servlet.http.HttpServletRequest;
7 | import javax.servlet.http.HttpServletResponse;
8 | import java.io.IOException;
9 | import java.io.PrintWriter;
10 | import java.util.Calendar;
11 |
12 | @Controller
13 | public class YoilTeller {
14 | @RequestMapping("/getYoil") // http://localhost:8080/getYoil?year=2021&month=10&day=1
15 | // public static void main(String[] args) {
16 | public void main(HttpServletRequest request, HttpServletResponse response) throws IOException {
17 | // 1. 입력
18 | String year = request.getParameter("year");
19 | String month = request.getParameter("month");
20 | String day = request.getParameter("day");
21 |
22 | int yyyy = Integer.parseInt(year);
23 | int mm = Integer.parseInt(month);
24 | int dd = Integer.parseInt(day);
25 |
26 | // 2. 처리
27 | Calendar cal = Calendar.getInstance();
28 | cal.clear(); // 모든 필드(날짜, 시간 등)을 초기화
29 | cal.set(yyyy, mm - 1, dd);
30 |
31 | int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
32 | char yoil = "일월화수목금토".charAt(dayOfWeek-1); // dayofWeek는 일요일:1, 월요일:2, ...
33 |
34 | // 3. 출력
35 | response.setContentType("text/html"); // 응답의 형식을 html로 지정
36 | response.setCharacterEncoding("utf-8"); // 응답의 인코딩을 utf-8로 지정
37 | PrintWriter out = response.getWriter(); // 브라우저로의 출력 스트림(out)을 얻는다.
38 | out.println("");
39 | out.println("
9 | 요일을 알고 싶으면 클릭!!! 10 |
11 |12 |
18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /ch3/readme.md: -------------------------------------------------------------------------------- 1 | . 2 | -------------------------------------------------------------------------------- /ch4/ManyToOneTest.java: -------------------------------------------------------------------------------- 1 | package com.fastcampus.ch4; 2 | 3 | import org.junit.jupiter.api.*; 4 | import org.springframework.beans.factory.annotation.*; 5 | import org.springframework.boot.test.context.*; 6 | 7 | import javax.persistence.*; 8 | import java.util.*; 9 | 10 | import static org.junit.jupiter.api.Assertions.assertTrue; 11 | 12 | @SpringBootTest 13 | class ManyToOneTest { 14 | @Autowired 15 | EntityManager em; 16 | 17 | @Autowired 18 | UserRepository userRepository; 19 | 20 | @Autowired 21 | BoardRepository boardRepository; 22 | 23 | 24 | @Test 25 | public void test() { 26 | // 1. 테스트 데이터 작성 27 | User user = new User(); 28 | user.setId("aaa"); 29 | user.setPassword("1234"); 30 | user.setName("LEE"); 31 | user.setEmail("aaa@aaa.com"); 32 | user.setInDate(new Date()); 33 | user.setUpDate(new Date()); 34 | userRepository.save(user); 35 | 36 | Board b1 = new Board(); 37 | b1.setBno(1L); 38 | b1.setTitle("title1"); 39 | b1.setContent("content1"); 40 | b1.setUser(user); 41 | b1.setViewCnt(0L); 42 | b1.setInDate(new Date()); 43 | b1.setUpDate(new Date()); 44 | boardRepository.save(b1); 45 | 46 | Board b2 = new Board(); 47 | b2.setBno(2L); 48 | b2.setTitle("title2"); 49 | b2.setContent("content2"); 50 | b2.setUser(user); 51 | b2.setViewCnt(0L); 52 | b2.setInDate(new Date()); 53 | b2.setUpDate(new Date()); 54 | boardRepository.save(b2); 55 | 56 | b1 = boardRepository.findById(1L).orElse(null); 57 | b2 = boardRepository.findById(2L).orElse(null); 58 | 59 | System.out.println("b1 = " + b1); 60 | System.out.println("b2 = " + b2); 61 | 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /ch4/application.properties: -------------------------------------------------------------------------------- 1 | # datasource설정 - 스키마 이름(sprinboot_basic), id, pwd를 본인에게 맞게 변경하세요. 2 | spring.datasource.url=jdbc:mysql://localhost:3306/springboot_basic?useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=UTF-8&serverTimezone=UTC 3 | spring.datasource.username=castello 4 | spring.datasource.password=asdf1234 5 | spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver 6 | 7 | # 쿼리를 콘솔에 출력하게 8 | spring.jpa.show-sql=true 9 | 10 | # 콘솔에 출력되는 쿼리를 보기 좋게 포맷팅 11 | spring.jpa.properties.hibernate.format_sql=true 12 | 13 | # 실제 사용할 DB의 종류 - hibernate가 DB별로 제공 14 | spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect 15 | 16 | # DB 자동 초기화 17 | # create : 기존 테이블 삭제 후 새로 테이블 생성(개발) 18 | # create-drop : create와 동일. 단, 종료시 테이블 삭제(개발) 19 | # update : 기존 테이블을 삭제하지 않고, 변경 사항(컬럼 추가)만 적용(개발) 20 | # validate : 엔티티와 테이블의 매핑 확인(운영) 21 | # none : 사용하지 않음(운영) 22 | spring.jpa.hibernate.ddl-auto=create 23 | -------------------------------------------------------------------------------- /ch4/list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |번호 | 167 |제목 | 168 |이름 | 169 |등록일 | 170 |조회수 | 171 |
---|---|---|---|---|
1 | 174 |Today I'm gonna finish | 175 |aaa | 176 |2020-01-30 | 177 |999 | 178 |