├── .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(""); 40 | out.println(""); 41 | out.println(""); 42 | out.println(year + "년 " + month + "월 " + day + "일은 "); 43 | out.println(yoil + "요일입니다."); 44 | out.println(""); 45 | out.println(""); 46 | out.close(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ch2/footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 7 |
8 | 9 | -------------------------------------------------------------------------------- /ch2/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 13 |
14 | 15 | -------------------------------------------------------------------------------- /ch2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | Title 7 | 8 |
9 |

환영합니다.

10 |
11 | 12 | -------------------------------------------------------------------------------- /ch2/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |

9 |
10 | id:
11 |
12 | pwd:
13 |
14 | 15 |
16 | 17 | 18 | -------------------------------------------------------------------------------- /ch2/main.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin : 0; 3 | padding : 0; 4 | } 5 | 6 | #header > ul { 7 | background-color : black; 8 | color: gray; 9 | } 10 | 11 | #header > ul > li { 12 | list-style : none; 13 | display : inline-block; 14 | /* background-color : blue; */ 15 | } 16 | 17 | #header > ul > li > a { 18 | text-decoration : none; 19 | padding : 10px; 20 | display : block; 21 | /* background-color: yellow; */ 22 | } 23 | 24 | #header > ul > li > a:visited { 25 | color: gray; 26 | } 27 | 28 | #header > ul > li > a:hover { 29 | color: white; 30 | } 31 | 32 | #footer { 33 | text-align : center; 34 | width: 100%; 35 | } 36 | -------------------------------------------------------------------------------- /ch2/mainLayout.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 9 |
10 |
11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /ch2/readme.md: -------------------------------------------------------------------------------- 1 | . 2 | -------------------------------------------------------------------------------- /ch2/userInfo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |

asdf

9 |

1234

10 | 11 | 12 | -------------------------------------------------------------------------------- /ch2/yoil.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |

9 | 요일을 알고 싶으면 클릭!!! 10 |

11 |

12 |

13 |
14 |
15 |
16 | 17 |
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 | fastcampus 6 | 7 | 8 | 160 | 161 | 162 |
163 |
164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 |
번호제목이름등록일조회수
1Today I'm gonna finishaaa2020-01-30999
181 |
182 | 183 |
184 |
185 | 186 | 187 | -------------------------------------------------------------------------------- /ch4/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.7.11 9 | 10 | 11 | com.fastcampus 12 | ch4 13 | 0.0.1-SNAPSHOT 14 | ch4 15 | ch4 16 | 17 | 11 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-data-jpa 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-thymeleaf 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | com.querydsl 34 | querydsl-jpa 35 | 5.1.0 36 | jakarta 37 | 38 | 39 | com.querydsl 40 | querydsl-apt 41 | 5.1.0 42 | jakarta 43 | 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-devtools 48 | runtime 49 | true 50 | 51 | 52 | com.mysql 53 | mysql-connector-j 54 | runtime 55 | 56 | 57 | org.springframework.boot 58 | spring-boot-starter-test 59 | test 60 | 61 | 62 | 63 | 64 | 65 | 66 | org.springframework.boot 67 | spring-boot-maven-plugin 68 | 69 | 70 | com.mysema.maven 71 | apt-maven-plugin 72 | 1.1.3 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /ch4/read.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | fastcampus 6 | 7 | 8 | 65 | 66 | 67 |
68 |

게시판 읽기

69 |
70 | 71 | 72 | 73 |
74 |
75 | 76 | 77 | 78 | 79 |
80 | 98 |
99 | 100 | 101 | -------------------------------------------------------------------------------- /ch4/readme.md: -------------------------------------------------------------------------------- 1 | . 2 | -------------------------------------------------------------------------------- /ch4/uploadFile.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | File Upload 5 | 8 | 9 | 10 | 11 |

파일 업로드

12 |
13 | 14 |

15 | 16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /ch4/write.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | fastcampus 6 | 7 | 64 | 65 | 66 |
67 |

게시판 쓰기

68 |
69 | 70 | 71 | 72 |
73 |
74 | 75 | 76 | 77 |
78 | 109 |
110 | 111 | 112 | -------------------------------------------------------------------------------- /download/boot_ch02_13_filter_interceptor_print.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/castello/springboot_basic/fb05f1b3aa8edef147156ebe29c2051d32b02a15/download/boot_ch02_13_filter_interceptor_print.pdf -------------------------------------------------------------------------------- /download/boot_ch02_16_thymeleaf 알아보기_print.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/castello/springboot_basic/fb05f1b3aa8edef147156ebe29c2051d32b02a15/download/boot_ch02_16_thymeleaf 알아보기_print.pdf -------------------------------------------------------------------------------- /download/boot_ch3_10_DB모델링4_print.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/castello/springboot_basic/fb05f1b3aa8edef147156ebe29c2051d32b02a15/download/boot_ch3_10_DB모델링4_print.pdf -------------------------------------------------------------------------------- /download/boot_ch3_2_의존성관리_자동설정4_print.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/castello/springboot_basic/fb05f1b3aa8edef147156ebe29c2051d32b02a15/download/boot_ch3_2_의존성관리_자동설정4_print.pdf -------------------------------------------------------------------------------- /download/boot_ch3_final.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/castello/springboot_basic/fb05f1b3aa8edef147156ebe29c2051d32b02a15/download/boot_ch3_final.zip -------------------------------------------------------------------------------- /download/boot_ch4.final.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/castello/springboot_basic/fb05f1b3aa8edef147156ebe29c2051d32b02a15/download/boot_ch4.final.zip -------------------------------------------------------------------------------- /download/boot_ch4_01_JPA개요4_print.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/castello/springboot_basic/fb05f1b3aa8edef147156ebe29c2051d32b02a15/download/boot_ch4_01_JPA개요4_print.pdf -------------------------------------------------------------------------------- /download/boot_ch4_04_SpringDataJpa_final_print.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/castello/springboot_basic/fb05f1b3aa8edef147156ebe29c2051d32b02a15/download/boot_ch4_04_SpringDataJpa_final_print.pdf -------------------------------------------------------------------------------- /download/ch2.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/castello/springboot_basic/fb05f1b3aa8edef147156ebe29c2051d32b02a15/download/ch2.zip -------------------------------------------------------------------------------- /download/readme.md: -------------------------------------------------------------------------------- 1 | . 2 | --------------------------------------------------------------------------------