- 오늘의 코딩순서
1.Spring 설치법
2. New Spring Project 생성법
3. (폴더: oBootHello) ( 줌 강의 0730일자 05:16~) 5:25 봐야함
메인 페이지 http://localhost:8381/
- application.properties
- Emp.class + Member1.class
- hello.html + HelloController.class ==> templates Package에 만들기, View에 해당
메인 페이지 http://localhost:8381/members/memberForm
- MemberRepository.interface + MemoryMemberRepository.class + MemberService.class + MemberController.class + MemberForm.html + index.html + memberList.html
폴더 및 패키지 생성 Tip)
- src/main/java 폴더에는 Controller, command, dao, dto,domain, repository, service는 Package 생성하여 class등 만들기
- src/main/resources폴더는 view자리이므로 Folder 생성하여 html등 만들기
오늘의 코딩 포인트
1. Spring 설치법
1. c드라이브에 spring 폴더 만들고 그 안에 springSrc폴더 만들기
2. soring 폴더 안에 spring-tool-suite-4-4.jar 파일 같이 두기
3. cmd 창 키고 C:\spring입력하여 위치 바꿔준뒤, cd java -jar springSrc17 입력하기
4. java -jar spring-tool-suite-4-4.jar 입력해서 압축해제 명령하고 기다리기
5. sts-4.21.0.RELEASE 폴더 들어가서 체크하고 아래 exe 파일 눌러서 설치 시작
6. 파일 생성할 폴더 지정해서 springSrc17 선택하고 설치하기
7. springSrc17 폴더에 .metadata 폴더 생긴거 확인하기
8. 서버 연결하기
- 상단 메뉴에서 Window > Show View > Servers창 띄우기
- Server 연결하기: C:\Program Files\Apache Software Foundation\Tomcat 10.1 선택 > jdk-17선택 > 설치 후 설치 기다리기
2. New Spring Project 생성법
1. 새 파일 만들기 > New > Spring Starter Project
2. File 설정하기
↳ Package의 이름의미: 앞(com.oracle)은 회사정보, 뒤(oBootHello)는 주요 프로젝트 context 정보
3. Boot Version 확인하고 Available 추가하기 > Finish 누르고 설치 기다리기
- 내가 사용하는 Spring Boot Version 알아두기(가끔 면접에서 물어봄) ==> 나는 3.3.2
- Available에서 Web와 Thymeleaf를 추가하지 않으면 실행되지 않고 오류가 발생함
3. JSP Spring Boot 연계하기 >> 이걸 해야 HTML을 사용할 수 있음
1. 상단 표시줄 > Help > Eclipse Marketplace 선택
2. eclipse web 검색 > Eclipse Web Developer Tools 두 개 다 최신버전 설치하기
(폴더: oBootHello)
메인 페이지 http://localhost:8381/
- application.properties
spring.application.name=oBootHello
server.port=8381
com.oracle.oBootHello.dto >>Java의 DTO 파일들, Getter and Setter 잊지말기
- Emp.class
package com.oracle.oBootHello.dto;
public class Emp {
private String empno;
private String ename;
public String getEmpno() {
return empno;
}
public void setEmpno(String empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
}
- Member1.class
package com.oracle.oBootHello.dto;
public class Member1 {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
templates >> 이클립스 JSP의 webapp폴더에 해당함, 여기에 View을 만듬
- hello.html
Tip)- perfix: 컨트롤러가 지정한 View 이름 앞에 붙음
- suffix: 컨트롤러가 지정한 View 이름 뒤에 붙음
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>hello.html</h1>
<p th:text="안녕 + ${parameter}">
<!-- JSP의 core library와 같은 기능 -->
</body>
</html>
com.oracle.oBootHello.controller >> Controller는 여기에 만들기
- HelloController.class
Tip)- @ Controller
- 역할
- @Controller 어노테이션은 해당 클래스가 웹 애플리케이션의 컨트롤러임
- 스프링 컨테이너는 @Controller 어노테이션이 지정된 클래스를 빈으로 등록하고, 요청을 해당 컨트롤러에 매핑하여 처리함
- 스프링 MVC의 핵심 요소 중 하나로, 클라이언트의 요청을 처리하는 비즈니스 로직과 뷰를 결합하여 전체적인 웹 애플리케이션의 동작을 제어함
- 사용방법
- @Controller 어노테이션이 지정된 클래스는 일반적으로 HTTP 요청을 처리하기 위한 메소드들을 포함함
- 각 메소드는 @RequestMapping 어노테이션과 함께 사용하여 특정 URL 패턴에 대한 처리를 정의함
- @RequestMapping 어노테이션을 사용하여 요청 URL과 해당 메소드를 매핑시키고, 메소드는 요청을 처리하고 필요한 로직을 수행한 후에 응답을 생성함
- 컨트롤러 메소드에서는 ModelAndView, Model, ResponseEntity 등을 반환하여 응답 데이터와 뷰 정보를 제공함
- 역할
- @Controller 라고 선언하여 Controller 기능 부여하기
- Java의 Controller에 해당
- Logger 자동완성할때 org.slf4j 형식으로 import하기
- @ Controller
@Controller
public class HelloController {
private static final Logger logger = LoggerFactory.getLogger(HelloController.class);
+
Tip) 전체 수행 Floor=> viewResolver와 출력법
- viewResolver
- Controller가 return 값이 호출되면, viewResolver가 prefix와 suffix를 적용하여 값을 반환하고, jsp를 호출
- Console 메시지 출력법
- System.out.println(); :원하는 메시지 앞에 이름까지 입력해야 메시지의 출력 순서를 파악할 수 있지만, Console에 깔끔하게 메시지만 출력됨
- logger: 원하는 메시지만 괄호안에 넣으면 되므로 편리하지만, Console창에 스크롤이 넘어갈만큼 길게 출력됨
다만, 많은 기업에서 이 출력법을 사용함
- Annotation
- 사전적 의미로는 주석이라는 뜻이지만, 자바에서 Annotaion(@)은 코드 사이에 특별한 의미, 기능을 수행하도록 하는 기술
- 프로그램 코드의 일부가 아닌 프로그램에 관한 데이터를 제공하고, 코드에 정보를 추가하는 정형화된 방법
- 어노테이션을 사용하면 코드가 깔끔해지고 재사용이 가능함
- 컴파일러에게 코드 작성 문법 에러를 체크하도록 정보를 제공함
- 소프트웨어 개발 툴이 빌드나 배치시 코드를 자동으로 생성할 수 있도록 정보를 제공힘
- 실행시(런타임시) 특정 기능을 실행하도록 정보를 제공함
- @RequestMapping
- HandlerMapping의 기능을 함
- 해당 URL에 대한 요청(여기서는 hello)이 들어왔을 때, table에 저장된 정보에 따라 해당 클래스 또는 메서드에 Mapping 함
- templates/가 prefix, hello는 컨트롤러가 지정한 논리적 뷰 이름, .html는 suffix
@RequestMapping("hello")
/* 루트 다음에 붙을 url */
public String hello (Model model) {
System.out.println("HelloController hello start...");
logger.info("start....");
model.addAttribute("parameter", "boot start...");
return "hello";
// View의 이름
// ViewResolver == > templates/ + hello + .html
}
- Controller을 실행시키고 Console창에서 돌아가는지 확인 후, 주소창에 http://localhost:8381/hello 타이핑 해서 들어가기
+
Tip) ajax로 보내는 법 1.ReponseBody Flow => StringConverter
- @ResponseBody
- return 값을 반환할 때 viewResolver가 작동하지 않고, 내부 객체에서 HttpMessageConverter을 호출함
- 이때 반환되는 값이 String이면, 내부에서 StringConverter를 호출함
- @GetMapping
- RequestMapping의 자손
- URL에 대한 요청을 해당 클래스 또는 메서드에 GET방식으로 Mapping 함
- Get방식
- 클라이언트의 데이터를 URL뒤에 붙여서 Map 방식으로 데이터를 response함
- URL형태로 표현되므로, 특정 페이지를 다른사람 에게 접속하게 할 수 있음
- 간단한 데이터를 넣도록 설계되어, 데이터를 보내는 양의 한계가 있음
- Get방식
- @RequestParam
- RequestParam을 기재하면 parameter의 값을 꼭 입력하여 값을 받아야 함
==> 값을 입력하지 않으면 badRequest 오류(status=400)이 뜸
- RequestParam을 기재하면 parameter의 값을 꼭 입력하여 값을 받아야 함
@ResponseBody
@GetMapping("ajaxString")
/* RequestMapping의 자손 */
/* GetMapping인지, PostMapping인지 기술하는 것 */
public String ajaxString(@RequestParam("ajaxName") String aName) {
//괄호 안은 parameter 이름
System.out.println("HelloController ajaxString aName->"+aName);
return aName;
}
- Controller을 실행시키고 Console창에서 돌아가는지 확인 후, 주소창에 http://localhost:8381/ajaxString?ajaxName=kkk 타이핑 해서 들어가기
- 여기서 ?뒤의 값은 parameter 이름
- = 뒤에 값은 선언한 String(여기서는 aName)에 들어감 => 나중에는 jQuery를 이용해서 DOM에 넣음
+
Tip) ajax로 보내는 법 2.ReponseBody Flow => JsonConverter
- @ResponseBody
- return 값을 반환할 때 viewResolver가 작동하지 않고, 내부 객체에서 HttpMessageConverter을 호출함
- 이때 반환되는 값이 객체이면, 내부에서 JsonConverter를 호출함
- 이때 반환되는 형식은 {"":""}, 이 값은.jsp의 jQuery를 이용해서 success의 DOM에 들어감
(들어가는 ajax의 형식은 0725일지 och16의 list.jsp 참고)- DOM?: Document Object Model, 문서 객체 모델,
<html>이나 <body> 같은 html문서의 태그들을 JavaScript가 이용할 수 있는 객체(object)로 만들면 그것을 문서 객체라고 함, 문서 객체 모델은 문서 객체를 인식하는 방식
즉, DOM은 웹 브라우저가 HTML 페이지를 인식하는 방식, document 객체와 관련된 객체의 집합을 의미함
- DOM?: Document Object Model, 문서 객체 모델,
@ResponseBody
// JSP의 ajax의 list.jsp 참고하기
@GetMapping("ajaxEmp")
// 보통 Annotation의 url과 변수명은 같도록 해줌
public Emp ajaxEmp(@RequestParam("empno") String empno,
@RequestParam("ename") String ename
) {
System.out.println("HelloController ajaxEmp empno->"+empno);
logger.info("ename -> {}", ename);
// 아래 세 줄이 만들었던 DTO 값
Emp emp = new Emp();
emp.setEmpno(empno);
emp.setEname(ename);
return emp;
}
- Controller을 실행시키고 Console창에서 돌아가는지 확인 후, 주소창에 http://localhost:8381/ajaxEmp?empno=1234&ename=kkk 타이핑 해서 들어가기
메인페이지 http://localhost:8381/members/memberForm
1. 클래식한 방식
DB를 이용하지 않고, Memory에 TBL을 보관하여 저장과 조회를 하는 방법
1. Web에서 Request 발생 => memberform.html에서 이름을 등록하면, /members/save를 타고 name을 controller로 이동함
- MemberForm.html ==> ID와 이름을 등록하는 메인 Form
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="/members/save" method="post">
// 실행 후 Controller의 /members/save로 이동
<label for="name">이름</label>
<input type="text" id="name" name="name" placeholder="이름을 입력하세요">
<button type="submit">등록</button>
</form>
</body>
</html>
2. Controller에서 Service 호출 => method가 post방식이기 때문에 controller에서 Postmapping을 타고 Console에 메시지 출력
- MemberController.class ==> Controller는 여러 개 만들어도 된다! 실제 프로젝트 때는 사람별로 Controller를 만듬
Tip)- PostMapping: URL에 대한 요청을 해당 클래스 또는 메서드에 Post방식으로 Mapping 함
- Post방식
- GET 방식과 달리, 데이터 전송을 기반으로 한 요청 메서드
- URL에 붙여서 보내지 않고BODY에다가 데이터를 넣어서 보냄
- POST 방식으로 데이터를 보낼때는 위와 같이 컨텐츠 타입을 꼭 명시해줘야 함
- GET방식과 마찬가지로 BODY에 key 와 value 쌍으로 데이터를 넣음
ex) application/x-www-form-urlencoded - BODY에 단순 txt를 넣음
ex) text/plain - BODY의 데이터를 바이너리 데이터로 넣는다는걸 알려줌, 파일전송을 할때 많이 쓰임
ex) multipart/form-data
- GET방식과 마찬가지로 BODY에 key 와 value 쌍으로 데이터를 넣음
- Post방식
- PostMapping: URL에 대한 요청을 해당 클래스 또는 메서드에 Post방식으로 Mapping 함
9. return된 getId 값이 id에 저장되고, redirect를 통해 /에 저장되어야 하지만 없음
=> 이런 경우에는 static 폴더에 index로 이동됨 ∵ boot의 기본값은 static의 index이기 때문
=> 때문에 이 index 파일을 메인 페이지로 만들어도 됨
- return "redirect:ㅁㅁ": return값을 redirect로 하면 View로 이동하지 않고, 같은 컨트롤러 안에서 따옴표 안의 객체를 호출함
package com.oracle.oBootHello.controller;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import com.oracle.oBootHello.dto.Member1;
import com.oracle.oBootHello.service.MemberService;
@Controller
public class MemberController {
private static final Logger Logger = LoggerFactory.getLogger(MemberController.class);
// 이렇게 선언하고 나면 logger를 쓸 수 있음
// 클래식한 방법
MemberService memberService = new MemberService();
@GetMapping(value = "members/memberForm")
//괄호안의 값을 따라 template명과 html을 만들기
public String memberForm() {
System.out.println("MemberController /members/memberForm Start...");
return "members/memberForm";
// viewResolver에 의해 DispatcherServlet으로 이동하는 값
// 즉, memberForm.html로 이동하게 함
}
@PostMapping(value= "members/save")
public String save(Member1 member1) {
//Java와 달리, getparameter를 쓰지 않고 DTO에서 곧장 객체가 넘어온다
//memberService 로 이동
System.out.println("MemberController /members/save Start...");
System.out.println("MemberController /members/save member1.getName()->"+member1.getName());
Long id = memberService.memberSave(member1);
System.out.println("MemberController /members/save id->"+id);
return "redirect:/";
}
@GetMapping(value= "members/memberList")
public String memberListString(Model model) {
Logger.info("memberList Start...");
List<Member1> memberLists = memberService.allMembers();
Logger.info("memberLists.size()-> {}", memberLists.size());
model.addAttribute("memberLists",memberLists);
return "members/memberList";
}
}
3. Model 객체의 Service => save값을 갖고 MemberService.class로 이동
8. 가져온 save 값을 getId에 넘김, getId 값 갖고 Controller로 return
- MemberService.class
package com.oracle.oBootHello.service;
import java.util.List;
import com.oracle.oBootHello.dto.Member1;
import com.oracle.oBootHello.repository.MemberRepository;
import com.oracle.oBootHello.repository.MemoryMemberRepository;
public class MemberService {
// 클래식한 방법
MemberRepository memberRepository = new MemoryMemberRepository();
// MemberRepository는 interface
// emoryMemberRepository()는 실제 구현할 객체
// 회원가입
public long memberSave(Member1 member1) {
System.out.println("MemberService memberSave start...");
memberRepository.save(member1);
//memberRepository로 이동
return member1.getId();
}
public List<Member1> allMembers() {
System.out.println("MemberService allMembers start...");
List<Member1> memList = null;
memList = memberRepository.findAll();
System.out.println("memList->"+memList.size());
return memList;
}
}
4. save값을 갖고 memberRepository.save로 이동
- MemberRepository.interface
Tip)- Repository: DB를 DML방식을 통해 처리하는 곳
package com.oracle.oBootHello.repository;
import java.util.List;
import com.oracle.oBootHello.dto.Member1;
public interface MemberRepository {
Member1 save(Member1 member1);
// 저장할 프로그램
List<Member1> findAll();
// 조회할 프로그램
}
5. save값을 갖고 MemoryMemberRepository.interface로 이동
이동된 값이 아래 sequence를 지나 Map 방식으로 store(memory)에 저장됨(처음에는 1로 저장됨)
6. 이 값이 조회 프로그램에 return 되기 시작
7. save 값 가지고 Service로 return
- MemoryMemberRepository.class ==> 위의 MemberRepository를 상속하여 추상메소드 사용하기
Tip)- Map 방식 사용⭐⭐⭐: 메모리에 저장하기 위해, insert에 활용하기 위해 사용
package com.oracle.oBootHello.repository;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.oracle.oBootHello.dto.Member1;
public class MemoryMemberRepository implements MemberRepository {
private static Map<Long, Member1> store = new HashMap<Long, Member1>();
// 메모리에 저장하기 위해 사용한 객체: Map방식***
// Map<k,v>에서 k:멤버번호 v:객체번호, Map방식을 통해 통째로 저장
private static Long sequence = 0L;
// 멤버번호 0부터 시작
@Override
// 저장할 프로그램
public Member1 save(Member1 member1) {
member1.setId(++sequence);
// 멤버번호가 늘어나서 계속 들어와도 처리할 수 있도록 하는 로직
store.put(member1.getId(), member1);
System.out.println("MemoryMemberRepository sequence->"+sequence);
System.out.println("MemoryMemberRepository member1.getName()->"+member1.getName());
return member1;
}
@Override
// 조회할 프로그램
public List<Member1> findAll() {
System.out.println("MemoryMemberRepository findAll start...");
List<Member1> listMember = new ArrayList<>(store.values());
// store의 value(Member1)값만 List<Member1>로 돌려주는 로직
System.out.println("MemoryMemberRepository findAll slistMember.size()->"+listMember.size());
return listMember;
}
}
10. return된 id값이 이동되어 index.html이 실행됨
- index.html ==> Service 기능, 회원가입과 목록 등이 나오는 창
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>나 Index야</h1>
<a href="/hello">Hello</a><p>
<a href="/members/memberForm">회원 가입</a><p>
<a href="/members/memberList">회원 목록</a><p>
</body>
</html>
- memberList.html ==> Service 기능, 회원목록 눌렀을때 나오는 창
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<table border="1">
<thread>
<tr>
<th>NO</th>
<th>이름</th>
</tr>
</thread>
<tbody>
<tr th:each="member : ${memberLists}">
<!-- foreach문과 같은 기능 -->
<td th:text="${member.id}"></td>
<td th:text="${member.name}"></td>
</tr>
</tbody>
</table>
</body>
</html>
질문목록
수업교재
1. FrameWork ⭐⭐
1. 정의 ==> 면접에 질문이 나오면 아래에 정의와 함께 종류 다섯 가지를 설명하기
- 대표적 오픈소스 기반의 어플리케이션 프레임워크
- EJB 의 복잡성 및 빈약한 데이터 모델을 해결하기 위한 POJO(Plain Old Java Object)기반의 OSS(Open Source Software) 프레임워크
- EJB (Enterprise JavaBeans)
- 기업환경의 시스템을 구현하기 위한 서버측 컴포넌트 모델
- 애플리케이션의 업무 로직을 가지고 있는 서버 애플리케이션
- EJB 사양은 Java EE의 자바 API 중 하나로, 주로 웹 시스템에서 JSP는 화면 로직을 처리하고, EJB는 업무 로직을 처리하는 역할을 함
- 단점
- EJB의 다양한 기술들을 사용하기 위해서는 EJB 스펙을 사용해야 했고, 그로 인하여 서비스가 구현해야 하는 비즈니스 로직보다 EJB 컨테이너 설정을 위해 더 많은 시간을 투자해야 함
- 이런 복잡한 EJB의 컨테이너를 대체하기 위해서 등장한 것이 바로 Spring 컨테이너
==> Spring 컨테이너는 특정 클래스를 상속하거나 인터페이스를 구현하지 않는 POJO를 사용하여 많은 복잡성이 제거됨
- POJO (Plain Old Java Object)
- Java로 생성하는 순수한 객체
- 객체 지향적인 원리에 충실하면서 환경과 기술에 종속되지 않고, 필요에 따라 재활용될 수 있는 방식으로 설계된 오브젝트를 의미함
- POJO에 애플리케이션의 핵심 로직과 기능을 담아 설계하고 개발하는 방법을 POJO 프로그래밍이라고 함
- Java나 Java의 스펙에 정의된 것 이외에는 다른 기술이나 규약에 얽매이지 않아야 함
- 특정 환경에 종속적이지 않아야 함. 즉, 특정한 프레임워크에서만 동작이 가능하면 않아야 함
- POJO가 필요한 이유
- 객체지향적인 설계를 제한 없이 적용할 수 있다. (가장 중요한 이유)
- 특정 환경이나 기술에 종속적이지 않으면 재사용이 가능하고, 확장 가능한 유연한 코드를 작성할 수 있다.
- 저수준 레벨의 기술과 환경에 종속적인 코드를 제거하여 코드를 간결해지며 디버깅하기에도 상대적으로 쉬워진다.
- 특정 기술이나 환경에 종속적이지 않기 때문에 테스트가 단순해진다.
- OSS (Open Source Software)
- EJB (Enterprise JavaBeans)
- ⭐⭐⭐(면접 필수 질문) DI, SpringMVC, AOP, ORM을 기반으로 하는 팀 프로젝트의 도구
2. 종류
2. Spring MVC : 웹 어플리케이션 제작을 위한 기반 제공 ⭐⭐⭐⭐
JSP의 MVC 모델과의 차이점
0.차이점
1. DispatcherServlet
- @Controller이 기재된 클래스를 찾아 Controller에게 요청을 전달함
- Spring Framework가 제공하는 Servlet 클래스
- 사용자의 request를 받음
- preController 라고도 함
- JAVA의 Controller가 Servlet으로 상속된 것처럼 (Controller extends HttpServlet) Servlet의 역할을 함
2.HandlerMapping
- 사용자에게서 받은 request를 처리할 Controller을 찾음(Controller URL Mapping)
- 요청 url에 해당하는 Controller 정보를 저장하는 table를 가짐
- requestMapping, default Mapping 이라고도 함
- 클래스에 @RequestMapping("/url") annotation을 명시하면 해당 URL에 대한 요청이 들어왔을 때, table에 저장된 정보에 따라 해당 클래스 또는 메서드에 Mapping 함
3. Validator
- Server에 올려보내기 위해 필드를 검증함
4. Model 객체
- setAttribute 기능을 하며, Spring에서는 Model 객체를 더 많이 씀
- 특정 속성에 값을 변경하거나 새로 지정함
5. ViewResolover
- Controller에서 return(반환)된 Model과 View 객체에서 선언된 View Page를 지정해주는 Class
즉, 실질적인 jsp를 호출하는데 필요한 클래스임 - Controller에서 return(반환)된 View Name에 prefix와 suffix를 적용하여 View Object를 반환함
ex) /WEB-INF/viewjsp/hello.jsp
==> /WEB-INF/viewjsp/가 prefix, hello는 컨트롤러가 지정한 논리적 뷰 이름, .jsp는 suffix
오늘의 숙제
'Spring' 카테고리의 다른 글
2024_08_06_화~08_07_수 (0) | 2024.08.06 |
---|---|
2024_08_05_월~08_06_화 (0) | 2024.08.05 |
2024_08_02_금 (0) | 2024.08.02 |
2024_08_01_목 (0) | 2024.08.01 |
2024_07_31_수 (0) | 2024.07.31 |