1주차 시작!
[개발자 입문]웹개발의 봄, Spring - 1주차 | Notion
PDF 파일
teamsparta.notion.site
1. java, intllij 설치
Oracle JDK 를 기본으로 설치했지만, 이제 유료화 되었으므로 Open JDK 를 설치합니다.
Window에 JDK 설치하기 | Notion
과거에는 Oracle JDK 를 기본으로 설치했지만, 이제 유료화 되었으므로 Open JDK 를 설치합니다.
teamsparta.notion.site
이거 하다가 구글 계정을 까먹어서 해맸기에 혹시 나와같은 사람이 있다면
로그인 - Google 계정
accounts.google.com
google계정 비밀번호를 복구하는 위 링크를 들어가시길 바랍니다.
1-2 프로젝트 생성과 Git 연동
- 프로젝트 생성하기
근데 문제 발생..
그래서 2023.1 버전으로 다시 깔아서 실행했더니 해결됐다.
https://blog.naver.com/eyunp07/223325890445
자바 JDK(Java Development Kit)이해하기 [jdk 설치, jdk버전, jdk란?, jdk 고르는법]
자바로 어플리케이션을 개발하고 실행하려면 Java 컴파일러, Java 런타임 라이브러리 및 가상머신이 필...
blog.naver.com
jdk 17버전중에서 어떤걸 고를까 고민하다가 이 블로그를 보고 Amazon Corretto를 골랐다.
- 초기 셋팅
preferences버튼은 윈도우에선 Settings
File → Settings OR ctrl + alt + s 를 누르면 된다.
V 외부 패키지 자동 import
V 사용하지 않는 패키지 삭제
V 폰트 크기 바꾸기 가능 → Ctrl+휠
1-3 gradle
자바 코드를 실행가능한 파일로 만들어주는 것
- 컴파일하는 법
ctrl + D : 복사
1-4 서버 사용하기
- 기본 클래스 생성
main → java → alt + Ins 로 페키지랑 자바 클래스 생성
package com.sparta.springprepare.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/api/hello")
public String hello(){
return "Hello World!";
}
}
- Postman : 개발을 빠르게 구현시켜주는 플렛폼
1-5 HTTP란 무엇일까?
F12 → Name → Headers에서 Status Code는 응답상황에 맞춰 3자리로 표현한다.
- 1번째 : 상태 → 1: 수신되었고 계속 실행중, 2: 정상적으로 처리됨, 3: 추가적인 조치가 필요함
4: 클라이언트 오류(404) = 요청이 잘못됨, 5 : 서버 오류
- 2,3번째 : 세부적인 차이
F12 → Name → Responese에 응답받은 html을 표시되어 있다.
payload(실제 데이터)는 GET방식으로 보낼 수 없다.
1-6 Test코드
테스트할 클래스에 ctrl + shift + T OR 마우스 오른쪽 버튼 > Generate > Test
테스트하다가 한글깨짐이 있어서 참고한 블로그!
PART2에서 해결됐다.
인텔리제이 한글 깨짐 문제 해결방법(인코딩 설정)
인텔리제이에서 WAS 구동시나 app 실행시 한글이 깨진다면 보통 인코딩 설정이 잘못 되어서입니다.대부분의 경우 UTF-8 encoding 을 사용할테니 다음 방법으로 encoding 을 정확히 설정해 주면 됩니다.
velog.io
1-7 Lombok과 appliation.properties
Lombok : 필요한 매소드를 자동으로 불러온다.
셋팅 단축키 : ctrl + alt + s
Shift + Shift → plugins 검색으로 확인 가능
이와중에 컴파일 할때마다 나오는 오류메세지.. 찾아보니까
실행에는 영향을 미치지 않는다곤 하지만 너무너무 신경쓰인다.
- @Getter와 @Setter는 lombok 메소드이다.
두개만 붙여주면 알아서 build에 만들어진다.
package com.sparta.springprepare;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Memo {
private String username;
private String contents;
//
// public void setUsername(String username) {
// this.username = username;
// }
//
// public String getUsername() {
// return this.username;
// }
//
}
class Main{
public static void main(String[] args){
Memo memo = new Memo();
memo.setUsername("Rabbitbaka");
System.out.println(memo.getUsername());
}
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.sparta.springprepare;
public class Memo {
private String username;
private String contents;
public Memo() {
}
public void setUsername(String username) {
this.username = username;
}
public String getUsername() {
return this.username;
}
public String getContents() {
return this.contents;
}
public void setContents(final String contents) {
this.contents = contents;
}
}
요런 식으로 완성
- 이렇게 하기 싫다면?
본 코드에 alt + Ins (우측클릭 후 Generate) → Getter와 Setter로 만들기
@AllArgsConstructor : 모든 필드를 가진 생성자
@NoArgsConstructor : 필드를 가지지 않은 기본 생성자
@RequiredArgsConstructor : final을 가진 필드를 가진 생성자
package com.sparta.springprepare;
import lombok.Getter;
import lombok.Setter;
import lombok.RequiredArgsConstructor;
@Getter
@Setter
@RequiredArgsConstructor
public class Memo {
private final String username;
private String contents;
}
class Main{
public static void main(String[] args){
Memo memo = new Memo("happy");
memo.setUsername("Rabbitbaka");
System.out.println(memo.getUsername());
}
}
1-8 Controller
MVC 패턴 방식을 사용한다.
package com.sparta.springmvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller // 이 클래스는 컨트롤러 역할을 할것이다.
public class HelloController {
@GetMapping("/api/hello") //api가져오기
@ResponseBody //문자열만 반환할땐 이거 사용
public String hello(){
return "Hello World!!"; //return에 뷰 넣기
}
@GetMapping("/api/get")
@ResponseBody
public String get(){
return "GET Method 요청";
}
@PostMapping("/api/post")
@ResponseBody
public String post(){
return "POST Method 요청";
}
@PutMapping("/api/put")
@ResponseBody
public String put(){
return "PUT Method 요청";
}
@DeleteMapping("/api/delete")
@ResponseBody
public String delete(){
return "DELETE Method 요청";
}
}
("/api/hello"와 같은)경로는 중복 가능하지만
(GetMapping과 같은)Method는 중복가능이 불가능하다.
또한 중복되는 경로는 @RequestMapping를 클레스 앞에 붙여 요약이 가능하다.
@RequestMapping("/api")
art+1 : 프로젝트 창 끄기/켜기
1-9 동적 페이지와 정적 페이지
1. 정적 페이지 만들기
[static]
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello Spring</title>
</head>
<body>
Hello, Spring 정적 웹 페이지!! (static)
</body>
</html>
static폴더에 있는 html을 바로 불러낸다.
localhost:8080/hello.html
package com.sparta.springmvc.html;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class HtmlController {
@GetMapping("/static-hello")
public String hello(){
return "hello.html"; //return 값으로 뷰넣기
}
@GetMapping("/html/redirect") //우회해서 넣고 싶을 때 redirect사용
public String htmlStatic(){
return "redirect:/hello.html";
}
}
[templetes]
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello Spring</title>
</head>
<body>
Hello, Spring 정적 웹 페이지!! (templates)
</body>
</html>
templetes에 있는 html을 반환할때는
파일이름.html에 html을 안붙여도된다.
다시 말해 return 파일이름 으로 불러낼 수 있다.
@GetMapping("/html/templates")
public String htmlTemplates(){
return "hello"; //이부분
}
2. 동적 페이지 만들기
- hello-vsit.html
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>Hello Spring</title></head>
<body>
<div>
Hello, Spring 동적 웹 페이지!!
</div>
<div>
(방문자 수: <span th:text="${visits}"></span>)
</div>
</body>
</html>
@GetMapping("/html/dynamic")
public String htmlDynamic(Model model){
visitCount++;
model.addAttribute("visits",visitCount);
return "hello-visit";
}
1-10 데이터 반환
ctrl + E : 최근 열었던 파일 열기
package com.sparta.springmvc.response;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/response")
public class ResponseController {
//Content-Type : text/html
// Response Body
// {"name":"Rabat","age":01}
@GetMapping("/json/string")
@ResponseBody
public String helloStringJson(){
return "{\"name\":\"rabat\",\"age\':01}";
}
//Content-Type : application/json
// Response Body
// {"name":"Rabat","age":01}
@GetMapping("/json/class")
@ResponseBody
public Star helloClassJson(){
return new Star("Rabat",01); //자바 객체를 json으로
}
}
Star.java
package com.sparta.springmvc.response;
import lombok.Getter;
@Getter
public class Star {
String name;
int age;
public Star(String name, int age) {
this.name = name;
this.age = age;
}
public Star() {}
}
@RestController = @ResponseBody + @Controller 여서
@ResponseBody를 적을 필요가 없음
package com.sparta.springmvc.response;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/response")
public class ResponseController {
//Content-Type : text/html
// Response Body
// {"name":"Rabat","age":01}
@GetMapping("/json/string")
@ResponseBody
public String helloStringJson(){
return "{\"name\":\"rabat\",\"age\':01}";
}
//Content-Type : application/json
// Response Body
// {"name":"Rabat","age":01}
@GetMapping("/json/class")
@ResponseBody
public Star helloClassJson(){
return new Star("Rabat",01); //자바 객체를 json으로
}
}
1-11 jackson
Jackson : json데이터 구조를 처리해 주는 라이브러리
package com.sparta.springmvc;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sparta.springmvc.response.Star;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
public class JacksonTest {
@Test
@DisplayName("Object To JSON : get Method 필요")
void test1() throws JsonProcessingException { //star클레스에 @Getter필요
Star star = new Star("Rabbit", 01);
ObjectMapper objectMapper = new ObjectMapper(); // Jackson 라이브러리의 ObjectMapper
String json = objectMapper.writeValueAsString(star); //json을 string형태 json으로 변환
System.out.println("json = " + json);
}
@Test
@DisplayName("JSON To Object : 기본 생성자 & (get OR set) Method 필요")
void test2() throws JsonProcessingException { //star클레스에 @Getter, Setter 또는 생성자 필요
String json = "{\"name\":\"Rabbit\",\"age\":1}"; // JSON 타입의 String
ObjectMapper objectMapper = new ObjectMapper(); // Jackson 라이브러리의 ObjectMapper
Star star = objectMapper.readValue(json, Star.class);
System.out.println("star.getName() = " + star.getName());
System.out.println("star.getAge() = " + star.getAge());
}
}
코드에 soutv 작성시 → 바로 앞 변수를 출력하는 코드 작성됨
근데 json엔 숫자앞에 0이 붙이지 못한다.
JSON은 8진수 및 16진수 형식은 허용이 안되며 앞에 0이 허용되지 않는다.
그래서 application.properties 파일에
spring.jackson.parser.allow-numeric-leading-zeros=true
를 넣거나 age를 String으로 제작하면 될 것이다.
1-12 서버로 데이터 보내는 방식
Jackson : json데이터 구조를 처리해 주는 라이브러리
<!DOCTYPE html>
<html>
<head>
<title>Hello Request</title>
</head>
<body>
<h2>GET /star/{name}/age/{age}</h2>
<form id="helloPathForm">
<div>
이름: <input name="name" type="text">
</div>
<div>
나이: <input name="age" type="text">
</div>
</form>
<div>
<button id="helloPathFormSend">전송</button>
</div>
<br>
<h2>GET /hello/request/form/param</h2>
<form method="GET" action="/hello/request/form/param">
<div>
이름: <input name="name" type="text">
</div>
<div>
나이: <input name="age" type="text">
</div>
<button>전송</button>
</form>
<br>
<h2>POST /hello/request/form/param</h2>
<form method="POST" action="/hello/request/form/param">
<div>
이름: <input name="name" type="text">
</div>
<div>
나이: <input name="age" type="text">
</div>
<button>전송</button>
</form>
<br>
<h2>POST /hello/request/form/model</h2>
<form method="POST" action="/hello/request/form/model">
<div>
이름: <input name="name" type="text">
</div>
<div>
나이: <input name="age" type="text">
</div>
<button>전송</button>
</form>
<br>
<h2>GET /hello/request/form/param/model </h2>
<form method="GET" action="/hello/request/form/param/model">
<div>
이름: <input name="name" type="text">
</div>
<div>
나이: <input name="age" type="text">
</div>
<button>전송</button>
</form>
<br>
<h2>POST /hello/request/form/json</h2>
<form id="helloJsonForm">
<div>
이름: <input name="name" type="text">
</div>
<div>
나이: <input name="age" type="text">
</div>
</form>
<div>
<button id="helloJsonSend">전송</button>
</div>
<div>
<div id="helloJsonResult"></div>
</div>
</body>
<script>
// GET /star/{name}/age/{age}
const helloPathForm = document.querySelector("#helloPathFormSend")
helloPathForm.onclick = (e) => {
const form = document.querySelector("#helloPathForm");
const name = form.querySelector('input[name="name"]').value;
const age = form.querySelector('input[name="age"]').value;
const relativeUrl = `/hello/request/star/${name}/age/${age}`;
window.location.href = relativeUrl;
}
// POST /hello/request/form/json
const helloJson = document.querySelector("#helloJsonSend")
helloJson.onclick = async (e) => {
const form = document.querySelector("#helloJsonForm");
const data = {
name: form.querySelector('input[name="name"]').value,
age: form.querySelector('input[name="age"]').value
}
const response = await fetch('/hello/request/form/json', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
const text = await response.text(); // read response body as text
document.querySelector("#helloJsonResult").innerHTML = text;
};
</script>
</html>
http://localhost:8080/hello/request/form/html
@Pathvariable은 @GetMapping에서 {}안에 있는 걸 가져옴
package com.sparta.springmvc.request;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/hello/request")
public class RequestController {
@GetMapping("/form/html")
public String helloForm() {
return "hello-request-form";
}
// [Request sample]
// GET http://localhost:8080/hello/request/star/Robbie/age/95
@GetMapping("/star/{name}/age/{age}") //{}에 데이터를 @PathVariable이 가져감
@ResponseBody
public String helloRequestPath(@PathVariable String name, @PathVariable int age)
{
return String.format("Hello, @PathVariable.<br> name = %s, age = %d", name, age);
}
// [Request sample]
// GET http://localhost:8080/hello/request/form/param?name=Robbie&age=95
@GetMapping("/form/param")
@ResponseBody
public String helloGetRequestParam(@RequestParam String name, int age) {
return String.format("Hello, @RequestParam.<br> name = %s, age = %d", name, age);
}
}
@RequestParm이 중복시, 생략 가능하며
@RequestParm (requied=false)를 넣으면 null값도 가능해집니다.
'웹공부 > SPRING' 카테고리의 다른 글
SPRING 기본 (1) | 2024.12.13 |
---|---|
Intellj Community Edition에서 SPRING 작동하는 법 (0) | 2024.12.13 |
스파르타 코딩 클럽 - Spring 4주차 (0) | 2024.07.26 |
스파르타 코딩 클럽 - Spring 3주차 (0) | 2024.07.25 |
스파르타 코딩 클럽 - Spring 2주차 (2) | 2024.07.24 |