HCD 랩스 11월 2주차 - Javascript, 리액트, 서블릿, 스프링 시작

우영·2025년 11월 10일

HDC 랩스 풀스택 1기

목록 보기
12/20

11/10 월 - Javascript 이벤트, DOM

assignment

review


이벤트

8. 이벤트 
	- 웹 페이지에서 발생하는 사건, 자극을 의미
	- 이벤트를 통해서 사용자와 상호작용이 가능
	- 마우스나 키보드의 움직임
	1) 이벤트종류 
		- 사용자의 동작이나 브라우저의 상태가 변경됨을 의미
		- 마우스이벤트 : click, mouseover, mouseout...
		- 키보드이벤트 : keyup, keydown
		- 폼이벤트 : change, submit...
		- 윈도우이벤트 : load, resize, scroll
	2) 이벤트핸들러
		- 이벤트가 발생되면 실행하는 함수
		[예]
		<p id = "text" style = "cursor: pointer;" 
				onclick="changeColor()">텍스트클릭하기</p>
		changeColor가 이벤트 핸들러함수
		onclick="changeColor()" 브라우저의 text라는 id로 정의된 요소에소 click이벤트가 발생
		하면 changeColor 함수를 실행하라고 등록하는 코드
	3)이벤트리스너(event Listener)
		- 이벤트를 감시하고 이벤트핸들러와 실제 소스객체를 연결 
	4)이벤트 연결하는 방법
		①이벤트핸들러속성
		② 표현식을 이용해서 이벤트속성에 함수등록
		③ addEventListener를 이용해서 등록
			- 표준방식
			- 이벤트핸들러로 정의한 함수가 호출될때 자바스크립트엔진이 자동으로 함수에 event객체를 전달한다.
			[형식]
			addEventListener(type, function(e){ -> 전달되는 이벤트객체를 사용
							--------               사용하지 않으면 매개변수에 정의하지
							이벤트종류				   않아도 된다.
							click, keyup
							mouseover....			
										      })
											---------
											이벤트가 발생되면 실행할 함수	
	5) 이벤트동작(이벤트흐름)
		
		- 이벤트가 발생하면 부모요소를 거쳐 타겟요소까지 찾아 내려가고 다시 부모에서 최상위까지 전파
		- stopPropagation을 이용해서 버블링이 발생해도 부모이벤트가 발생하지 않도록 작업
		- 원래 기존 태그가 갖고 있는 특성대로 실행되는 것을 막기 위해 preventDefault()를 이용
		① 이벤트캡처링
			- 이벤트가 최상위요소에서 이벤트가 발생된 타겟요소까지 내려가는 단계
		② 타겟인지
		  - 이벤트가 발생한 타겟에서 이벤트처리로 등록한 함수가 실행
		③ 이벤트 버블링				
			- 이벤트가 타겟요소에서 최상위로 다시 올라가는 단계

DOM

  • window.onload = function()
    = 읽히는 순간 바로 만들어짐 html이 다 만들어지고 난 후에 자바스크립트를 실행해야 오류가 나지 않음
	let form = document.querySelector("#todoForm");   // 폼
	let input = document.querySelector("#todoInput"); // 입력창
	let list = document.querySelector("#todoList");   // 할 일 목록

= 위의 3개를 가져오는 이유: 내가 조작할 부분의 태그를 가져와서 각각의 변수에 넣음. 내가 누르는 곳, 만들어지는 곳, 클릭한 곳.
= 자바스크립트는 HTML 태그를 직접 만질 수 없으니까, querySelector로 태그를 가져옴

form.addEventListener("submit", function(e) {
		e.preventDefault();  // 기본 새로고침 막기
  		let todoText = input.value;
		alert(todoText); // 테스트 	
	});
  1. 새로고침을 막고 자바스크립트로 할 일을 받아 오고 테스트 하기
    = 1) form에 이벤트 연결 -> 추가 버튼을 눌렀을 때 submit은 항상 새로고침이 됨. 그러면 밑에 항목이 추가가 되지 않기 때문에 새로고침을 막아서 자바스크립트로 밑에 할 일을 추가할 수 있도록 준비하는 단계.
    = 2) todoText = input.value 입력창에 적은 글자를 자바스크립트 코드로 가져오기.

  2. html파일에 리스트로 표현하라는 태그가 있음.
    ul이란 전체적인 틀이 있고 항목들은 내가 li들을 만들어야 함.
    1) li 태그 만들기

let new태그 = document.createElement("태그이름");

createElement : HTML 안에 아직 존재하지 않는 태그를 자바스크립트 코드로 새로 생성
Element : HTML에서 태그 1개를 의미
2) 안에 글자 넣기

  • 2가지 방법
  1. textcontent
  2. createTextNode() + appendchild()
    node : HTML 문서를 브라우저가 읽을 때, 트리 구조로 바뀜 -> 트리 구조의 가지 = node, HTML 문서를 구성하는 모든 조각 하나
    element(태그), text(내용), attribute(속성 id = "todol), comment(주석) node들이 있음.
newItem.textContent = todoText;
  • 입력창에서 가져온 글자를 li에 넣음
let textnode = document.createTextNode(todoText);
  • HTMl 안에서 다뤄지는 하나의 노드 객체 만들기
    • 나중에 다른 태그에 붙일 수 있게 해줌.
      3) li태그 + 텍스트 태그
      appendChild() : 부모노드의 자식노드로 새로운 노드를 추가
list.appendChild(newItem)
  • li 태그에 자식 태그인 텍스트 태그를 이어 붙인다.
  1. 이제 화면에 있는 ui 태그 안으로 옮겨 붙어야 함. 지금은 메모리 안에서만 만들어진 상태.
    1) 위에 list로 화면의 ui태그를 가져온 상태임으로 ui태그 + li태그
list.appendChild(newItem)

2) 이제 li태그에 입력한 값이 들어가 화면에 표시됨 하지만 글자가 계속 남아있음 그래서 초기화를 시켜줌

input.value = ""; // 다음 입력을 위해 입력창 비우기
<ul id="todoList">
  <li>공부하기</li>   ← 현재까지 한것
</ul>

  1. 밑의 코드처럼 만들어야 함. span 추가 및 붙이기
<li>
  <span>공부하기</span> // 텍스트도 따로 구분해야 삭제나 수정이 편함.
  <button>완료</button>
  <button>삭제</button>
</li>
  • span으로 바꾸기 위해 내가 쓴 코드 - 에러남!!
window.onload = function() {
	let form = document.querySelector("#todoForm");
	let input = document.querySelector("#todoInput");
	let list = document.querySelector("#todoList");
	
	form.addEventListener("submit", function(e) {
		e.preventDefault(); 
		let todoText = input.value;
		//alert(todoText); // 테스트용
		
		let newItem = document.createElement("li");
		/*newItem.textContent = todoText;*/
		let textnode = document.createTextNode(todoText);
		newItem.appendChild(textnode);
		list.appendChild(newItem);
		/*input.value = "";*/	
		let span = document.createElement("span");
		/*let textnode = document.createTextNode(todoText);*/ /*span.textContent = todoText;*/
		span.appendChild(textnode);
		input.value = "";
	});
	 
}
  • 이유 : textnode를 작은거 부터 넣어서 결국 ul까지 다시 합쳐야 함. 내꺼는 textnode를 두 번 붙이려 함. appendChild() 이동하기 때문에 span엔 들어가고 li에는 안들어가서 화면이 이상해짐
window.onload = function() {
	let form = document.querySelector("#todoForm");
	let input = document.querySelector("#todoInput");
	let list = document.querySelector("#todoList");
	
	form.addEventListener("submit", function(e) {
		e.preventDefault(); 
		let todoText = input.value;
		//alert(todoText); // 테스트용
		
		// li 만들기
		let newItem = document.createElement("li");
		// 글자(textnode) 먼저 만들기
		let textnode = document.createTextNode(todoText); 
		/*newItem.textContent = todoText;*/
		/*span.textContent = todoText;*/
		// span 만들기
		let span = document.createElement("span");
		// textnode를 span 안에 붙이기
		span.appendChild(textnode);
		// span을 li 안에 붙이기
		newItem.appendChild(span);
		// li를 ul 안에 붙이기
		list.appendChild(newItem);	
		/*let textnode = document.createTextNode(todoText);*/ 
		/*span.textContent = todoText;*/
		// 입력창 비우기
		input.value = "";
	});
	 
}
  • 깔끔하게 바꿈
  1. 버튼 2개 만들기
    createElement : HTML 안에 아직 존재하지 않는 태그를 자바스크립트 코드로 새로 생성
let doneBtn = document.createElement("button");
let delBtn = document.createElement("button");

버튼에 텍스트 넣는 3가지 방법
1. textContent : 가장 안전하고 간단함.
= 태그가 아닌 글자형태로 들어감
2. innerText : 화면에 눈에 보이는 텍스트만 다룸
= 숨겨진 글씨는 무시, 사실상 1번이랑 비슷함
3.innerHTML : HTMl 태그를 해석해서 넣음
= HTMl 태그를 직접 쓸 수 있음
4. appendChild(createTextNode) : 정석 DOM 방식
= 과정이 길지만 내부구조를 직접 만듦.

appendChild() : 부모노드의 자식노드로 새로운 노드를 추가

		
// 버튼에 텍스트 추가 
doneBtn.appendChild(document.createTextNode("추가"));
delBtn.appendChild(document.createTextNode("삭제"));
// 버튼을 li안에 붙이기
newItem.appendChild(doneBtn);
newItem.appendChild(delBtn);
  1. 이벤트 적용 완료
  • 버튼엔 줄 긋기 (토글 형식처럼 완료 누르면 줄그어지고 다시 누르면 원래상태로)
  • 삭제 버튼엔 해당 li 항목 삭제

  • 요소.addEventListener(이벤트종류, 실행할함수);
    • 요소 :이벤트를 감지할 대상
    • 이벤트종류 : 어떤 행동을 감지할지 ("click", "keyup", "submit", "mouseover" 등)
    • 실행할함수 : 이벤트가 발생했을 때 실행할 코드 (여기선 function() { ... })

doneBtn.addEventListener("click", function() {
			/*alert("완료 버튼 눌림!"); // 테스트*/
			newItem.classList.toggle("done")
		});
  1. “doneBtn(완료 버튼)”이 클릭되면 function() 안의 코드가 실행된다.
  2. li.done span {
      text-decoration: line-through;
      color: #999;
    }
    ]
  • li 태그에 done 클래스가 있을때 그안의 span에 즐 긋기

  • newItem.classList.toggle("done");
    = 뜻 : li 태그(newItem)에 done이라는 클래스를 붙였다 뗐다 해라

  • . 의미= newItem 자체가 객체라 점을 이용해서 그 안의 속성이나 기능에 접근함. 쉽게 말해 객체 안의 무언가를 꺼내겠다라는 뜻

  • classList : 이 태그가 가진 class 속성들 모음

  • toggle("done") : li태그에 done 클래스가 없을 때 추가됨 있으면 제거되고 스위치 같이 on/off 같은 기능

  • 삭제 버튼

delBtn.addEventListener("click", function(){
			
			newItem.remove();
		});
  • 요소.addEventListener(이벤트종류, 실행할함수);
    • 요소 :이벤트를 감지할 대상
    • 이벤트종류 : 어떤 행동을 감지할지 ("click", "keyup", "submit", "mouseover" 등)
    • 실행할함수 : 이벤트가 발생했을 때 실행할 코드 (여기선 function() { ... })
      remove() = js에서 제공하는 메서드로 DOM 트리에서 완전히 제거하는 함수

강사님이 하신 코드에서 공부할 것

  • querySelector()는 자바스크립트에서 HTML 요소를 “가져올 때” 쓰는 함수, 조건에 맞는 첫 번째 요소만 가져옴
  • querySelectorAll() : 조건에 맞는 모든 요소들(NodeList) 을 가져옴.
// ✅ 1. todolist의 항목값을 저장할 빈배열 
let todoArray = [];

// ✅ 2. 새로운 할 일(todoItem)을 객체로 만들어 배열에 추가
const todoItem = {
	id: Date.now(),
	text: newTodoText,
	done: false
};
todoArray = [...todoArray, todoItem];

// ✅ 3. 삭제할 때 (filter로 특정 id만 제외)
todoArray = todoArray.filter(item => item.id !== id);

// ✅ 4. 완료 토글할 때 (map으로 done 값을 반대로 변경)
todoArray = todoArray.map(item => 
	item.id === id ? {...item, done:!item.done} : item
);

배열을 쓴 이유 :
1. 상태를 저장할 수 있음
= 할 일을 추가하거나 삭제하거나 완료했을 때,
그 “현재 상태”를 배열 안에 그대로 저장할 수 있음.
2. 화면을 다시 그리기 가능
3. 추가/삭제/수정이 너무 쉬워짐

  • 추가

    • todoArray = [...todoArray, newTodo];
  • 삭제

    • todoArray = todoArray.filter(item => item.id !== id);
  • 수정

todoArray = todoArray.map(item => 
  item.id === id ? {...item, done: !item.done} : item
);
  1. 나중에 DB에 연결해서 저장할때도 JSON 형식으로 보내면 끝.

객체들 정리




11/11 화 - 노드js설치 및 리액트 프로젝트 생성, 프론트페이지 연동(JSX, 컨퍼런트)

assignment

review


https://nodejs.org/ko[노드js](https://nodejs.org/ko)

  • 깃허브에 올릴때 지우고 올림 -> npm install 폴더로 이동해서 다시 깔음


  • 툴바 고정, url에 액세스 허용

컴포넌트를 씀으로써 돔 api를 안씀. -> 리액트를 쓰는 이유

11/12 수 - 리액트 외부 CSS, 프롭, 라우팅, +템플릿, 디자인 프레임워크, 프로젝트 요구 명세서등등

assignment

review


  • css파일
    • 파일이름을 반드시 [이름].module.css로 정의해야한다.
    • class속성은 리액트에서 className 속성으로 사용

라우팅 프로젝트 생성 후 폴더 이동 후 React Router라이브러리를 설치
= npm install react-router-dom

  • 설치 확인

  • main.jsx에서 컴포넌트를 BrowserRouter로 감싸준다.

    • 부모컨포넌트가 되도록 메인에서 설정
  • 폴더 만듦. - rafce

  • 다시 공부하기

import React from "react";
import User from "./User";

const UserList = (userlist) => {
  console.log(userlist);
  return (
    <div>
      {userlist.users.map((user) => (
        <User
          key={user.id}
          id={user.id}
          name={user.name}
          addr={user.addr}
        />
      ))}
    </div>
  );
};

export default UserList;

11/13 목 - 백엔드 시작!, 서블릿, JSP

assignment

review


  • 웹 구조
    = 웹 서버 : 분석하고 응답하는 일밖에 못함 -> 컨테이너에게 정보를 넘기고 표준화된 폴더구조(컨텍스트 - 웹 파일, web-znf- web.xml, lib, classes(자바파일들)) , 서블릿에게 넘김(서블릿이 요청을 받아주는 역할 그럼 요청) -> DB ->DBMS 다시 반대로 돌아서 요청을 돌려줌

  • 컨테이너와 서블릿에 대한 이해 필요!

  • HTML, CSS, javascript - DOM이 복잡하고 화면도 복잡해서 만들어 낸게 react

  • DOM이 나오기전에 DOM을 편하게 해주는 jquery를 씀

    • jquery, react는 같이 못씀
  • 서버쪽 뒤에서 안보이는데에서 처리되는 것 : 백엔드

    • 서버 : 자바쪽에서 서블릿, JSP -> 변하고 변해서 -> Spring boot
    • HTML, css, javascript에서 자바프로그램을 실행하지 못함

자바 webwork - 프로젝트 생성 - dynamic web - 이름 backend - next

  • dd파일 web.xml 체크

  • 생성 완료

  • 정보가 저장되는 곳

  • 서버가 인식하는 곳

  • 프론트엔드는 배포를 했어서 있고 백엔드는 아직 없음

  • html 실행 always 체크

  • 백엔드도 생김

  • 서버가 자바코드를 찾는 위치, 서블릿디렉토리라고 함

  • 서블릿 등록 하는 곳 -> 밑에 source 탭으로 바꿈

  • 서블릿의 lifecycle을 설명하기 위한 전체적인 흐름
    = 요청받은 객체(request)가 메모리에 로딩 됐는지 확인 -> 서블릿 객체를 생성하고(객체는 한번만 생성되고 웹서버가 쓰레드 생성함. 이 안에서 서비스가 호출되고 똑같이 요청방식에따라 doget, dopost로 됨. 요청이 들어올때 마다 쓰레드를 생성. 즉 자신만의 공간을 만든다.) init 메소드 호출 -> service호출 -> 매개변수로 request(클라이언트의 요청정보를 담는 객체), response(클라이언트에게 응답할 정보를 담을 객체)를 만듦. -> get인지 post인지 확인하고 doget, dopost로 db에 접근 -> 서비스가 응답정보를 서블릿컨테이너로 보냄 -> 컨테이너는 자바를 실행할 능력은 있는데 응답할 능력은 없어서 웹서버로 전달하고 -> 응답해줌






<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="https://jakarta.ee/xml/ns/jakartaee" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd" id="WebApp_ID" version="5.0">
  <display-name>backendtest</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.jsp</welcome-file>
    <welcome-file>default.htm</welcome-file>
  </welcome-file-list>
  <servlet>
  	<servlet-name>first</servlet-name>
  	<servlet-class>basic.FirstServlet</servlet-class>
  	
  </servlet>
  <servlet-mapping>
  	<servlet-name>first</servlet-name>
  	<url-pattern>/basic/first.iot</url-pattern>
  	
  </servlet-mapping>
  	<servlet>
  	<servlet-name>second</servlet-name>
  	<servlet-class>basic.SecondServlet</servlet-class>
  	
  </servlet>
  <servlet-mapping>
  	<servlet-name>second</servlet-name>
  	<url-pattern>/iot/second</url-pattern>
  </servlet-mapping>
  
  <servlet>
  	<servlet-name>life</servlet-name>
  	<servlet-class>basic.ServletLifeCycleTest</servlet-class>
  	
  </servlet>
  <servlet-mapping>
  	<servlet-name>life</servlet-name>
  	<url-pattern>/life.html</url-pattern>
  </servlet-mapping>
  
</web-app>

11/14 금 - 서블릿, jSP 구조 파악, 스프링 시작

assignment

  • 모던 웹 책 p20 의존성 주입 책 읽기 및 개념정리

review


흐름

  • register에서 서블릿 버튼을 누르면 - MemberInsertServlet - (DTO를 매개변수로 받음) - MemberDaoImpl - DB


https://blog.naver.com/heaves1/224075584701

  • 회원 목록보기를 눌렀을 때 이동할 수 있게
    register.html - request - MemberlistServlet (/member/list) 1) 요청정보추출 2) 비지니스메소드 호출 3)응답화면 생성 <- DTO 반환 MemberDaoImpl(DBMS에서 코드를 조회) - DBMS

과정 잘 정리해놓을 것 - 구조는 spring가서 똑같음.

  • 이해못함

			for(MemberDTO member:userlist) {
				out.print("<tr>");
				out.print("<td>"+member.getId()+"</td>");
				out.print("<td>"+member.getPass()+"</td>");
				out.print("<td>"+member.getName()+"</td>");
				out.print("<td>"+member.getAddr()+"</td>");
				out.print("<td>"+member.getDeptno()+"</td>");
				out.print("<td>"+member.getPoint()+"</td>");
				out.print("<td> <a href = '/backendtest/member/delete?id="+ member.getId() +" '>삭제</a></td>");
				out.print("</tr>");
				
				
			}

  • redirect vs forward
    = 전혀 다른개념

  • 자바는 왜 서블릿과 jsp를 쓸까?
    = 화면 분리를 해놔서 이제 html에 자바를 써야 하는데 html에 자바를 써야 해서 jsp를 쓴다.
    jsp :실행할때 서블릿 코드로 변환되서 실행됨

  • MVC 패턴

    • view: html 화면, model : DTO, DAO ,conroller : servlet
  • http : stateless 상태정보가 유지가 안됨, 쿠키나 세션으로 유지

register(뷰) - 서블릿(컨트롤러) -> dAO(모델) -> DBMS
^ |
|--------------jsp(뷰)


스프링 시작


-프로젝트만들기

  • generate
  • 탐색기 열고, 폴더에 가져다 놓고 압출 풀기

  • 빌드 문제 시 이렇게 맞춤 , jdk는 버전에 맞게

  • 타임리프 파일 우린 리액트꺼라 필요 없음 - 탬플릿 폴더, 정적(css, html, 자바스크립트) - static 폴더, java - java 폴더
  • DI / AOP 중요한 기술
  • spring MVC
  • spring jdbc
    스프링 :
    스프링부트 : 스프링을 편리하게 사용하기 위한 것

0개의 댓글