본문 바로가기
국비학원/수업기록

국비 지원 개발자 과정_Day45

by 루팽 2023. 1. 31.

css 선택자

태그선택자 <h1></h1>

h1 {}

 

클래스선택자 <h1 class = “title”>

.title {}

 

아이디 선택자 <h1 id = “title”>

#title {}

 

자바스크립트

window 안의 객체 document.write(”<h1></h1>”)

로컬이 아니라 브라우저에서 실행

 

자바

System.out.println()과 같음

자바는 main() 있음 → exe파일로 실행하는 로컬 프로그램

 

JSP문법

통신필요 -프로토콜필요 → http, https - stateless비상태

out.print(”<h1></h1>”)

 

웹혁명2.0

효율적, 브라우저 API 중요(윈도우, 도큐먼트객체 등 내장객체)

브라우저는 인터프리터 역할, 출력하려면 body태그 안에 입력

 

정적(html, css, js)페이지 처리

개인 pc 다운로드 - 시점, 동기화, 유지문제 발생, 비상태 프로토콜이기에 상태(데이터변화) 관리 필요

클라이언트 사이드 렌더링 → 결정사항 출력

서버사이드 렌더링 → 결정(리액트) -동기, 계속변함, 갭차이 발생 → 쿠키(String만 담을 수 있음-클라이언트, 로컬 pc쪽)와 세션(캐시메모리-서버 쪽)

 

html - id, class, tag name

css - 선택자

js - 아이디

document.getElementById(”id”)

document.querySelector // 배열아님, 객체{}

document.querySelectorAll // 배열[]

 

OOP(상하관계)-AOP(수평관계) 보완, 공통관심사 분리 → 일괄처리

html(화면)-css(색상, 위치, 일괄처리), js(이벤트 감지, 콜백함수, defer-html이 먼저 렌더링(브라우저-API)될 때까지 기다린다음 이벤트 감지)

 

동적페이지

서블릿 → JSP → 스프링

 

<네임카드>

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>네임카드</title>
    <script
      src=""
      crossorigin="anonymous"
    ></script>
    <link rel="stylesheet" href="./member1.css" />
  </head>
  <body class="member1">
    <section class="wrap">
      <!-- header start -->
      <nav class="menu">
        <a href="#">
          <i class="fas fa-bars"></i>
        </a>
        <a href="#">
          <i class="fas fa-sticky-note"></i>
        </a>
      </nav>
      <!-- header end -->
      <!-- profile start -->
      <article class="profile">
        <img src="../images/sample/woman1.png" alt="프로필이미지" />
        <h1>XX부트캠프</h1>
        <p>Back-End Developer</p>
        <a href="#" class="detailBtn">VIEW MORE</a>
      </article>
      <!-- profile end -->
      <ul class="contact">
        <li>
          <i class="fab fa-facebook-f"></i>
          <span>Visit My Facebook page</span>
        </li>
        <li>
          <i class="far fa-envelope"></i>
          <span>jungyunmok@gmail.com</span>
        </li>
      </ul>
      <nav class="others">
        <!-- a[href="member$.html"]*4 자동완성 -->
        <a
          href="http://192.168.10.71:5500/%EB%94%94%EC%9E%90%EC%9D%B83/member1.html"
        ></a>
        <a
          href="http://192.168.10.70:5500/%EC%97%B0%EC%8A%B5%ED%95%98%EA%B8%B0/%EC%97%B0%EC%8A%B5.html"
        ></a>
        <a
          href="http://192.168.10.72:5500/dev_html/%EB%94%94%EC%9E%90%EC%9D%B83/member1.html"
        ></a>
        <a
          href="http://192.168.10.78:5500/html0116/weak3/sample/lecture.html"
          class="on"
        ></a>
      </nav>
    </section>
  </body>
</html>

 

* {
  margin: 0; /* 4면의 외부여백 0 */
  padding: 0; /* 4면의 내부여백 0 */
  box-sizing: border-box; /* 여백을 포함한 크기 계산 */
  /* border: 1px solid red; 여백부분, 스타일을 죽인 부분 */
}

ul {
  list-style: none; /* 리스트 앞 구슬 제거 */
}

a {
  text-decoration: none; /* 링크 밑줄 제거 */
}

body {
  background-color: powderblue; /* 전체문서 배경색 */
}

/* section태그로 전체를 감싸줌 */
.wrap {
  width: 340px; /* 가로 크기 */
  padding: 30px; /* 내부 여백 크기 */
  background-color: white; /* 배경 색상 */
  position: absolute; /* 좌표값에 따른 배치 */
  top: 50%; /* y축 중앙 배치 - 주의, 요소의 왼쪽 상단 모서리기준 위치 */
  left: 50%; /* x축 중앙 배치 */
  transform: translate(-50%, -50%); /* 요소의 중앙 위치를 잡아줌 */
  border-radius: 10px;
}

.wrap .menu a {
  font-size: 20px;
  color: rgb(55, 55, 150);
}

/* 
float 속성을 주면 부모가 감싸주던 값이 0을 ㅗ되어
아이콘을 감싸주지 못함
가상 선택자를 선언하여 문제 해결
 */
.wrap .menu::after {
  content: "";
  display: block;
  clear: both;
}

.wrap .menu a:nth-of-type(1) {
  float: left;
}

.wrap .menu a:nth-of-type(2) {
  float: right;
}

.wrap .profile {
  width: 100%;
  text-align: center;
}

.wrap .profile img {
  width: 200px;
  height: 200px;
  border-radius: 50%;
  margin-top: 10px;
  margin-bottom: 20px;
}

.wrap .profile h1 {
  font: bold 22px/1 "arial";
  color: rgb(55, 55, 150);
  margin-bottom: 5px;
}

.wrap .profile p {
  font: bold 12px/1 "arial";
  color: rgb(55, 55, 150);
  margin-bottom: 20px;
}

/* a태그 css활용하여 버튼으로 바꿔보기 */
.wrap .profile .detailBtn {
  display: block;
  width: 180px;
  height: 32px;
  /* 시계방향으로 지정 */
  margin: 0px auto 20px;
  font: bold 16px/30px "arial";
  text-align: center;
  background-color: rgb(55, 55, 150);
  color: white;
  text-shadow: 2px 2px 3px rgb(110, 144, 255);
  border-radius: 16px;
}

/* 
인라인 요소는 기본적으로 가운데 정렬이 되고
만약 block요소를 주면 기본적으로 왼쪽 정렬이 된다
이것을 가운데로 옮기려면 margin에 auto를 준다
*/

.wrap .contact {
  margin-bottom: 20px;
}

.wrap .contact li {
  width: 100%;
  padding: 10px 0px;
  border-bottom: 1px solid rgb(55, 55, 150);
}

.wrap .contact li i {
  width: 20%;
  text-align: center;
  color: rgb(55, 55, 150);
}

.wrap .contact li span {
  font: 12px/1 "orbiarialtron";
  color: rgb(55, 55, 150);
  /* 글자간 간격 벌려주기 */
  letter-spacing: 1px;
}

.wrap .others {
  text-align: center;
  font-size: 0;
}

/* a태그(anchor) 인라인요소 - 크기가 없다 */
.wrap .others a {
  display: inline-block;
  width: 30px;
  height: 30px;
  border-radius: 50%;
  margin: 0px 10px;
}

.wrap .others a:nth-of-type(1) {
  background-color: rgb(110, 110, 247);
}

.wrap .others a:nth-of-type(2) {
  background-color: rgb(84, 201, 110);
}

.wrap .others a:nth-of-type(3) {
  background-color: rgb(230, 214, 79);
}

.wrap .others a:nth-of-type(4) {
  background-color: rgb(240, 109, 86);
}

 

<회원가입>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원가입</title>
<script type="text/javascript">
	//이런 식으로 이벤트를 주면 마지막 1개만 처리됨
	// 원시적 방법
	function join() {
		console.log("old join")
	}
	//arrow function
	join = ()=>{
		console.log("arrow join")
		const frm = document.querySelector("#f_join")
		frm.submit()
	}
</script>
</head>
<body>
	<!-- 
Restful API에서 제안하는 메소드 중 하나 get 방식
쿼리스트링을 통해 사용자가 입력한 값을 전달함
주소창에 모두 노출됨 - 보안에 취약
쿼리스트링을 통해 넘길 수 있는 값에 한계가 있음 - 브라우저마다 다름
단위 테스트 가능함
링크를 걸 수 있음 -> post방식은 불가능(전부 포장되어있기에)
action: 서버쪽으로 전달해서 아래 요청을 처리하는 페이지 URL 작성함
 -->
	<form id="f_join" method="get" action="./joinAction.jsp">
		<label>아이디</label>
		<input type="text" id="mem_id" name="mem_id" placeholder="아이디" required>
		<br />
		<label>비밀번호</label>
		<input type="text" id="mem_pw" name="mem_pw" placeholder="비밀번호" required>
		<br />
		<label>이름</label>
		<input type="text" id="mem_name" name="mem_name" placeholder="이름" required>
		<br />
		<label>생년월일</label>
		<input type="date" id="mem_birth" name="mem_birth" placeholder="생년월일" required>
		<br />
		<label>프로필사진</label>
		<input type="file" id="mem_img" name="mem_img" placeholder="프로필사진" required>
		<br />
		<label>우편번호</label> <input type="text" id="mem_zipcode" name="mem_zipcode" placeholder="우편번호">
		<button>우편번호찾기</button>
		<br />
		<input type="text" id="mem_address" name="mem_address" size=30 placeholder="주소">
		<br />
		<button id="btnJoin" onclick="join()">가입</button>
		<script>
			//이렇게 이벤트를 주면 2개가 모두 실행됨
			const joinBtn = document.querySelector("#btnJoin") // 아이디는 #
			console.log(joinBtn)
			joinBtn.addEventListener('click', () => {
				console.log('가입버튼 호출1')
			})
			joinBtn.addEventListener('click', () => {
				console.log('가입버튼 호출2')
			})
		</script>
	</form>
</body>
</html>

 

REST(Representational State Transfer)

자원(html)을 이름(tag, class, id, name)으로 구분하여 해당 자원의 상태(정보, 쿠키와 세션으로 관리하는 것들)를 주고받는(요청 request와 응답 return) 모든 것을 의미

자원(resource)의 표현(input태그 파라미터로 넘김(메소드기준) → 톰캣서버가 듣기)에 의한 상태 전달

 

자원

해당 소프트웨어가 관리하는 모든 것 문서, 그림, 데이터, 해당 소프트웨어 자체 등

 

자원의 표현

그 자원을 표현하기 위한 이름 DB의 학생 정보가 자원일 때, ‘students’를 자원의 표현으로 정한다.

 

상태(정보) 전달

데이터가 요청되는 시점에서 자원의 상태(정보)를 전달

JSON 혹은 XML를 통해 데이터를 주고받는 것이 일반적

 

브라우저가 mime타입(메인|서브타입으로 작성됨)으로 구분

list, map ←→ JSON 변환 자유자재

 

월드 와이드 웹(www)과 같은 분산(멀티티어) 하이퍼미디어 시스템을 위한 소프트웨어 개발 아키텍처의 한 형식

미들웨어-정적페이지(html, css, js)

백엔드 - 서버

→ java/servlet(server+Applet → http프로토콜 api 있음)/jsp(view역할까지 할 수 있음)

→ backend 필요 엔진 3개(servlet과 jsp가 있어야 웹서비스제공가능)

 

REST는 기본적으로 웹의 기존 기술과 HTTP 프로토콜을 그대로 활용하기 때문에 웹의 장점을 최대한 활용할 수 있는 아키텍처 스타일

네트워크 상에서 Client와 Server 사이의 통신 방식(http 프로토콜) 중 하나

 

REST의 장점

HTTP 프로토콜의 인프라를 그대로 사용하므로 REST API 사용을 위한 별도의 인프라를 구출할 필요가 없음

HTTP 표준 프로토콜에 따르는 모든 플랫폼에서 사용가능

Hypermedia API의 기본을 충실히 지키면서 범용성을 보장

REST API 메시지가 의도하는 바를 명확하게 나타내므로 의도하는 바를 쉽게 파악 가능

여러 가지 서비스 디자인에서 생길 수 있는 문제를 최소화

서버와 클라이언트의 역할을 명확하게 분리

 

REST의 단점

표준이 존재하지 않음

사용할 수 있는 메소드가 4가지뿐

HTTP Method 형태가 제한적

 

비동기 통신 권장

1. ajax 기술 - XMLHttpRequest 객체 - 비동기 통신 객체

비동기 처리 권장(대부분 업무 적용됨) 사항

0→1→2→3(요청에 대한 응답 다운로드 중)→4(응답완료, 다운종료)

상태값의 변화를 추적하는 속성이나 함수 지원 - XMLHttpRequestAPI

상태값이 0에서 시작해서 4가 될 때까지 지속적으로 체크를 하다가 완료되면 그때 콜백함수를 호출하는 시스템

 

2. Fetch API - javascript(바닐라스크립트)

다른 이종간의 API사용, 라이브러리 사용, 연계(연동)할 때 js(바닐라스크립트)가 나을 때도

 

form태그로 사용자가 입력한 정보를 전송

rest가 권장하는 get, post방식으로 전송가능

단 전송을 위해서는 submit()를 반드시 호출해야 함

GET방식 요청은 주소창에 사용자가 입력한 정보가 쿼리스트링으로 노출됨

단위테스트용으로 사용가능하지만 보안상 위험

실제 서비스될 때는 post방식으로 전환해야 함

UI솔루션의 디폴트 rest값은 항상 post

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	// 1, 2번 라인은 page directive라고 함
	// 스크립틀릿 선언 - 자바영역
	// <input type = "text" name = "mem_id" >
	String mem_id = request.getParameter("mem_id"); // 여기에 사용되는 속성이 name이다
	out.print("사용자가 입력한 아이디 =>" + mem_id); // 로컬이 아니라 브라우저에 출력됨 -> 여기의 자바는 서블릿이다
	
	String mem_pw = request.getParameter("mem_pw");
	out.print("비번은 " + mem_pw);
%>

 

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>joinResult.html</title>
</head>
<body>
	<div id="d_result"></div>
	<script type="text/javascript">
	let user_id = 'kiwi';
	let user_pw = '12345';
	user_id = window.prompt("아이디를 입력하세요.");
	user_pw = window.prompt("비번을 입력하세요.");
	
	const myHeaders = new Headers();
	myHeaders.append("Cookie", "JSESSIONID=43789CE5C9AB6510D88ED1B00055C6FA");

	const requestOptions = {
	  method: 'GET',
	  headers: myHeaders,
	  redirect: 'follow'
	};

	fetch(`http://localhost:9000/member/joinAction.jsp?mem_id=${user_id}&mem_pw=${user_pw}`, requestOptions)
	  .then(response => response.text())
	  .then(result => {
		  const dresult = document.querySelector("#d_result");
		  dresult.innerText = result
	  })
	  .catch(error => console.log('error', error));
	</script>
</body>
</html>

 

<해커뉴스 step 1>

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>해커뉴스API - [step1]</title>
    <!-- 
      선언부에서 자바스크립트를 import하면 html은 순차적으로 읽기가 진행되므로
      12번에서 div태스가 존재한다는 사실을 알 수가 없다.
      그러면 undefined가 발생함
      해결 방법은 script 속성으로 defer를 추가한다
      브라우저가 news.html을 서버로부터 다운로드하고 document를 스캔해서
      DOM tree를 그릴 때까지(태그 정보를 모두 다 읽을때까지) 기다린다
      보통 전역변수 선언이나 함수선언은 head태그 안에서 작성함
    -->
    <script defer src="./news.js"></script>
  </head>
  <body>
    <!-- div#root 자동완성 - 자바스크립트에서 쓸 때는 id -->
    <div id="root"></div>
  </body>
</html>

 

const requestOptions = {
  method: "GET",
  redirect: "follow",
};

fetch("https://api.hnpwa.com/v0/news/1.json", requestOptions)
  .then((response) => response.json())
  // .then((result) => console.log(result))
  .then((result) => {
    // ul태그를 js를 활용해서 생성하기
    const ul = document.createElement("ul"); // DOM API -> 구조가 잘 안보임
    for (let i = 0; i < 20; i++) {
      const li = document.createElement("li"); // li태그를 20개 생성
      // <li>뉴스제목</li>
      console.log(result[i].title);
      li.innerHTML = result[i].title; // 해커뉴스에서 반환값으로 제공되는 json에서
      // for문에서 만들어진 li태그를 ul태그에 넣기
      ul.appendChild(li);
    } // end of for문
    // news.html문서의 body에 정의된 <div id = root><ul></ul></div>
    document.getElementById("root").appendChild(ul);
  })
  // 에러가 발생하면 그 때 출력
  .catch((error) => console.log("error", error));

 

<해커뉴스 step 2>

<!DOCTYPE html>
<html lang="ko">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>해커뉴스API - [step2]</title>
    <script defer src="new2.js"></script>
  </head>
  <body>
    <div id="root"></div>
  </body>
</html>

 

var requestOptions = {
  method: "GET",
  redirect: "follow",
};

var requestOptions2 = {
  method: "GET",
  redirect: "follow",
};

const NEWSURL = "https://api.hnpwa.com/v0/news/1.json";
const CONTENTURL = "https://api.hnpwa.com/v0/item/@id.json";
// 제목을 클릭했을 때 보여줄 다중댓글 출력하기위한 div 생성하기
const content = document.createElement("div");

window.addEventListener("hashchange", () => {
  const id = this.location.hash.substr(1);
  fetch(CONTENTURL.replace("@id", id), requestOptions2)
    .then((response) => response.json())
    .then((result) => {
      // <div><h1>제목1</h1><h1>제목2</h1><h1>제목3</h1></div>
      const title = this.document.createElement("h1");
      title.innerHTML = result.title;
      //13번에서 생성한 div태그에 넣기
      content.appendChild(title);
    })
    .catch((error) => console.log("error", error));
});

fetch(NEWSURL, requestOptions)
  .then((response) => response.json())
  .then((result) => {
    const news = result;
    const ul = document.createElement("ul");
    for (let i = 0; i < 10; i++) {
      const div = document.createElement("div");
      div.innerHTML = `
    <li>
      <a href='#${news[i].id}'>
        ${news[i].title}(${news[i].comments_count})
      </a>
    </li>
    `;
      ul.appendChild(div.firstElementChild);
    }
    document.getElementById("root").appendChild(ul);
    document.getElementById("root").appendChild(content);
  })
  .catch((error) => console.log("error", error));

댓글