💡Back-end 개요
✔Server-Client 구조

: 서버-클라이언트(server-client) 구조란? 데이터를 저장하고 관리하는 서버 부분과 해당 서버에 접속하여 데이터를 열람하는 클라이언트 부분으로 구성된 네트워크 구조
✔ Web Server 구조

: 웹 서버는 클라이언트로부터 HTTP 요청을 받고, 이에 대한 응답을 HTML 형식으로 웹 브라우저에 전달하는 서비스 구조
: HTML의 특성상 멀티미디어와 링크로 구성되어 있는 일반적인 웹 페이지를 구성하는 서비스
✔ WAS (Web Application Server)

: 웹 서버가 웹 애플리케이션 서버에 요청하면 웹 애플리케이션 서버가 해당되는 프로그램을 실행하는 방식
: 사용자가 요청한 서비스의 결과를 스크립트 언어 등으로 가공하여 생성한 동적인 페이지를 사용자에게 보여주는 역할
- 한 프로그램에 여러 요청이 있는 경우 한 개의 프로그램을 실행하여 그 프로그램을 다수 요청 처리
ex) tomcat, Jboss, jeus
✔ Web Server와 WAS 차이
| 장점 | 단점 | |
| Web Server | - 빠른 처리 속도 : 요청에 대한 결과 페이지만 전송 - 구현이 쉬움 : HTML, CSS, JS나 이미지 등 단순한 파일로만으로 구성 |
- 한정적 서비스 : 만들어진 정보만 보여주기 때문에 서비스가 한정적 - 글의 추가, 수정, 삭제가 어려움 : 문서의 내용이 변경될 경우 직접 수정 |
| WAS | - 서비스의 다양성 : 여러 데이터를 활용할 수 있음 - 글의 추가, 수정, 삭제가 쉬움 : 문서의 내용이 변경될 경우 직접 수정하지 않음 |
- 느린 처리 속도 : 데이터를 처리하여 결과를 전송함 - 구현이 어려움 : 서비스에 해당하는 소스를 직접 작성 |
💡 Session과 Cookie
상태정보 유지의 필요성
: HTTP은 stateless(무상태성) 특징을 가지고 있다 !
- 무상태성이란? 서버가 클라이언트의 상태를 보존하지 않는 것. 서버는 client의 요청에 응답을 하고 나면 그 연결을 끊어 버린다.(stateless)
✔ 문제점
: 연결이 끊어지기 때문에 유지되어야 하는 정보들이 사라지는 문제가 발생
ex) 장바구니 기능, 로그인 후 사용자 정보
→ 우리는 사용자의 활동 및 애플리케이션의 현재 상태를 기억하고 유지해야 한다. ( 상태 정보 유지 )
| 방법 | 저장 위치 | 특징 및 사용 예시 |
| 세션(Session) | 서버 | 로그인 상태, 장바구니 정보 |
| 쿠키(Cookie) | 클라이언트 | 사용자 설정, 인증 정보 |
| 로컬 스토리지(Local Storage) | 클라이언트 | 브라우저를 닫아도 데이터 유지, 대용량 데이터 저장 |
| 세션 스토리지(Session Storage) | 클라이언트 | 브라우저를 닫으면 데이터 삭제, 단기 데이터 저장 |
| 상태관리 라이브러리 (State Management Libraries) | 클라이언트 | 리덕스, 모부엑스 등 복잡한 상태 관리 |
| URL 파라미터 및 해시(Hash) | 클라이언트 | 간단한 상태 유지, 검색 결과, 필터 설정 |
쿠키(Cookie)란?
: 클라이언트 즉 사용자 컴퓨터에 데이터를 저장하는 기술
→ 필요시에 해당하는 정보를 서버와 공유하여 정보를 유지
- Map 형식으로 저장
- 데이터 크기, 개수 제한 있음
- 쿠키 유지기간, 유효디렉터리, 유효도메인 설정 가능
✔ Cookie 코드
// 쿠키 생성
// 문자열만 허용
// name - value
Cookie cookie1 = new Cookie("COOKIE_ID", "test12345");
Cookie cookie2 = new Cookie("COOKIE_NAME", "홍길동");
response.addCookie(cookie1);
response.addCookie(cookie2);
Cookie[] cookies = request.getCookies();
for(Cookie c: cookies){
out.print(c.getName() + "," + c.getValue() + "<br>");
}
✔ 개발자도구에서 쿠키 확인 (F12)

세션(Session)이란?
: 서버에 사용자 데이터를 저장하는 기술
- 세션 ID는 클라이언트의 브라우저에 쿠키로 저장
- 브라우저를 닫거나 세션 타임아웃이 발생할 때 까지 유지
- 서버의 메모리나 저장 공간에 따라 제한, 클라이언트 측의 크기 제한 X
- 서버에 저장하여 비교적 안전
- 세션 ID가 도난당하지 않도록 HTTPS를 사용하는 것을 권장
ex) 사용자의 로그인 상태 유지, 장바구니 정보 저장 등
✔Session 코드
주요 코드
// 세션 값 설정
// 이름 타입은 String, 값 타입은 Object (자동형 변환)
session.setAttribute("apple",1);
// 세션 값 확인
String userId = (String)session.getAttribute("apple");
out.print(userId);
세션 생성 코드
// 1. req 객체에서 session 가져오기
HttpSession session = req.getSession();
String sessionId = session.getId(); // 쿠키로 저장될 클라이언트의 고유 ID
System.out.println("sessionId : " + sessionId);
// 2. 세션에 데이터 넣는 방법 (객체로 저장함으로, 숫자 문자 객체 모두 OK)
session.setAttribute("SESSION_ID", "test1");
// 3. 세션 시간 설정하기 (옵션, default : 30분)
session.setMaxInactiveInterval(60); // 초단위, 60초 셋팅
세션 확인 코드
// getSession(true) : session이 있으면 세션을 가져오고, 없으면 세션을 생성함 (default)
// getSession(false) : session이 있으면 세션을 가져오고, 없으면 null로 반환됨
HttpSession session = req.getSession(false);
if(session == null) {
System.out.println("세션이 없습니다");
return;
}
// 세션값 확인하는 방법
String userID = (String) session.getAttribute("SESSION_ID");
out.print(userID);
💡 Servlet
Servlet이란?

Server + Applet 합성어로 Dynamic Web Page 개발을 위한 자바 기반 최초의 Web 애플리케이션 프레임 워크
- Client의 요청(Request)을 받고, 요청에 따른 응답(Response)을 HTML 형식으로 동적으로 생성할 수 있도록 지원한다.
- 사용자는 Servlet Class를 상속받아 메소드를 재정의함으로써 요청 처리 과정을 체계적으로 프로그래밍할 수 있다 !
서블릿 동작 구조

- Request ( 사용자 요청 )
: 사용자의 요청으로 브라우저에서 요청한 URL과 브라우저 정보, 추가적인 데이터를 가지고 있는 객체 - Servlet Container
: 사용자의 요청에 따라 동작 할 로직을 정의한 클래스
-> 컨테이너란? 실제 서버에 동작하는 상태 - 서블릿 doGet, doPost 호출
: 요청 URL에 따라 실제 동작할 Servlet Container를 실제로 호출하는 과정,
→ Thread를 통해 멀티 태스킹으로 처리
서블릿 설계 규약
- 모든 서블릿은 javax.servlet.Servlet 인터페이스를 상속 받아 구현한다.
- 서블릿 구현 시 Servlet 인터페이스와 ServletConfig 인터페이스를 javax.servlet.GenericServlet에 구현한다.
- HTTP프로토콜을 사용하는 서블릿은 javax.servlet.http.HttpServlet클래스는 javax.servlet.GenericServlet을 상속한 클래스로 서블릿은 HttpServlet클래스를 상속 받는다.
- 서블릿 Exception처리를 하기 위해서는 javax.servlet.ServletException을 상속 받아야 한다.
서블릿 라이프 사이클


- 첫 번째 요청일 경우, 객체를 생성하며 init()메소드를 호출함
- 이 후 작업이 실행될 때마다 service()메소드가 요청한 HTTP Type에 따른 doGet(), doPost() 호출
- 최종적으로 서블릿이 서비스 되지 않았을 때 destroy() 호출
- destroy()는 보통 서버가 종료되었을 때, 서블릿의 내용이 변경되어 재 컴파일 될 때 호출
서블릿 메소드와 객체
✔ doGet
: client에서 데이터 전송 방식을 get 방식으로 전송하면 호출되는 메소드
💭 get 방식
URL창에 “?” 뒤에 데이터를 입력하는 방법(쿼리스트링)
데이터가 여러 개일 경우 &로 묶어서 보냄
→ 데이터 검색에 많이 사용하고, 데이터 크기 한계가 있으며 보안에 취약
ex) https://www.google.com/search?q=쿼리스트링
📛 반드시 ServletException 처리 해야 함
✔ doPost
: client에서 데이터 전송 방식을 post 방식으로 전송하면 호출되는 메소드
💭 post 방식
HTTP BODY에 내용을 보내는 방식으로 데이터 크기 제한이 없고 보안이 뛰어남
📛 반드시 ServletException 처리 해야 함
✔ HttpServletRequest
: HTTP Serlvet을 위한 요청 정보 제공
- 인터페이스나 인터페이스 구현은 컨테이너가 자동 생성
→ 메소드만 이용 - 상속 : javax.servlet.ServletRequest
| 메소드 명 | 내 용 |
| getParameter(String) | client가 보내준 값이 저장된 명칭이 매개변수와 같은 명칭에 저장된 값을 불러오는 메소드 |
| getParameterNames() | client가 보내준 값을 저장한 명칭을 불러오는 메소드 |
| getParameterValues(String) | client가 보내준 값이 여러 개일 경우 그 값을 배열로 불러오는 메소드 |
| getParameterMap() | client가 보내준 값이 전체를 Map방식으로 불러오는 메소드 |
| setAttribute(String, object) | request객체에 전달하고 싶은 값을 String 이름으로 Object저장하는 메소드 |
| getAttribute(String) | 매개변수와 동일한 객체 속성값 불러오는 메소드 |
| removeAttribute(String) | request객체에 저장되어 매개변수와 동일한 속성값 삭제하는 메소드 |
| setCharacterEncoding(String) | 전송 받은 request객체의 값들의 CharaterSet을 설정해주는 메소드 |
| getRequestDispatcher(String) | 컨테이너 내에서 request, response객체를 전송하여 처리할 컨포넌트(jsp파일 등)를 불러오는 메소드 |
| forward() | 메소드와 같이 사용 |
✔ HttpServletResponse
: 요청에 대한 처리 결과를 작성하기 위해 사용하는 객체
- 인터페이스나 인터페이스 구현은 컨테이너가 자동 생성 → 메소드만 이용
- 상속 : javax.servlet.ServletResponse
| 메소드 명 | 내용 |
| setContentType(String) | 응답으로 작성하는 페이지의 MIME type을 정하는 메소드 |
| setCharacterEncoding(String) | 응답하는 데이터의 CharacterSet을 지정해주는 메소드 |
| getWriter() | 문자를 페이지에 전송을 위한 Stream을 가져오는 메소드 |
| getOutputStream() | byte단위로 페이지에 전송을 위한 Stream을 가져오는 메소드 |
| sendRedirect(String) | client가 매개변수의 페이지를 다시 서버에 요청하게 하는 메소드 |
서블릿 필터


: 웹 프로젝트에서 요청을 받기 전 전처리 역할
- javax.servlet.Filter인터페이스를 상속받아 구현
- post방식의 데이터 한글 처리 역할로 사용
- 필터 클래스를 만들어 web.xml에 등록 후 사용
- 필터 구현: Filter interface
- 필터 등록: <filter>
- 필터 매핑 : <filter-mapping>
- @WebFilter annotaion 사용
✔ 필터 구현
public class FlowFilterOne implements Filter{
public void init(FilterConfig filterConfig ){
System.out.println(“init() call”);
}
public void doFilter(){
System.out.println(“doFilter() call”);
}
public void destroy(){
System.out.println(“destroy() call”);
}
}
FilterClass implements FilterInterface
- init(FilterConfig config) : 필터 객체 생성시 호출, 초기화 담당
- destroy() : 필터 객체 삭제시 호출됨, 자원해제담당
- doFilter(ServletRequest request, ServletResponse response, FilterChain ch) : 필터 실행시 호출됨.
서블릿 래퍼
: 필터 클래스로부터 전달받은 데이터를 가공하여 다시 필터에게 반환하는 클래스
- 데이터 가공이 필요한 시점이 요청일 경우, HttpServletRequestWrapper클래스
- 응답일 경우, HttpServletResponseWrapper클래스
// HttpServletRequestWrapper
public SampleWrapper(HttpServletRequest wrapper){
super(wrapper);
}
// HttpServletResponseWrapper
public SampleWraper(HttpServletResponse wrapper){
super(wrapper);
}
💡 MVC
MVC란?

: 화면(View-JSP), 제어(Controller-Sevlet), 데이터 연동(Model-DB)로 코드를 분리하여 서로 간의 영향도를 줄이고 코드를 간결하게 관리하여 코드 설계 품질을 향상시킬 수 있는 기법
MVC 구성요소 3가지
✔ View
: User Interface (UI) 를 담당하는 코드
: 사용자로부터 입력 받고, 결과를 화면에 보여주기 위한 역할
ex) 고객과 소통하는 역할 = 프론트 직원
✔ Controller
: View와 Model의 중간다리 역할
: View로 부터 전달 받은 사용자 입력(요청)을 분석하고, 이에 필요한 데이터를 Model로 부터 전달 받아 올바른 결과의 View를 구성하도록 전달
ex) 일은 하지 않고 시키기만 하는 역할 = 관리직
✔ Model
: 데이터를 처리하기 위한 로직을 구성
: DBMS와 상호작용 하거나 DATA를 가공하는 역할
: 비즈니스 로직이라고도 부르며, 요청 받고 실제 필요한 데이터를 가공하는 역할
ex) 노동자
더 자세한 내용
[JAVA]MVC Pattern
MVC 패턴이란?: SW 공학, 아키텍처 디자인 패턴 중 하나로 Model - View - Controller의 약자: MVC의 핵심은 화면(View), 제어(Controller), 데이터 연동(Model)을 구성하는 로직(코드)를 분리하여 서로 간의 영향도
min-jii.tistory.com
MVC1 vs MVC2
✔ MVC1

: View와 Controller를 모두 JSP가 담당하는 형태
- 구현 난이도는 쉬우나, JSP 하나에서 MVC가 구성됨으로 재사용성이 낮고, 유지보수가 어렵다
→ 현재는 사용되지 않음.
✔ MVC2

: MVC1의 단점을 개선
- Controller 역할을 서블릿과 같은 서버 측 컴포넌트가 담당하고,
View는 JSP 또는 다른 템플릿 기술을 사용하여 순수하게 사용자 인터페이스만을 처리 - Model, View, Controller가 더욱 명확하게 분리되어 있어, 각각 독립적으로 개발 및 관리할 수 있으며,
전체적인 애플리케이션의 테스트와 유지보수가 용이
→ Spring MVC에서 활용
MVC 응답 처리 방식
✔ RequestDispatcher
: 사용자의 요청을 다른 서블릿이나 JSP 페이지에 전달할 때 사용하는 클래스
✔ 응답할 View가 동적 페이지인 경우 (JSP)

// 1. request 내장 객체를 통해 RequestDispatcher 객체 생성
RequestDispatcher view = request.getRequestDispatcher("/result.jsp" );
// 2. 대상 View에서 필요한 정보를 request 영역에 저장
request.setAttribute("member", member);
// 3. request와 response를 인자 값으로 전달하여 정보 전송
view.forward( request, response );
✔ 응답할 View가 정적 페이지인 경우

response.sendRedirect("/error.html");
MVC 실습하기 (회원 정보 등록 및 삭제)
📌View
입력용 - webapp/memeber.jsp
<%@ page contentType="text/html;charset=UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<title>Member Page</title>
</head>
<body>
<h2>Member Registration</h2>
<form action="/member_insert" method="post">
ID: <input type="text" name="id"/><br/>
Password: <input type="password" name="password"/><br/>
Name: <input type="text" name="name"/><br/>
<input type="submit" value="Register"/>
</form>
<h2>Member Deletion</h2>
<form action="/member_delete" method="post">
ID: <input type="text" name="id"/><br/>
<input type="submit" value="Delete"/>
</form>
</body>
</html>
출력용 - webapp/ views/member_result.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>회원정보 처리 결과를 담는 페이지</title>
</head>
<body>
<br>
<hr color="blue">
<h3>insert 정보</h3>
insertion member : <%= request.getAttribute("member")%>
<hr color="red">
<h3>delete 정보</h3>
deletion member_id : <%=request.getAttribute("member_id")%>
</body>
</html>
📌Controller
DispatcherServlet.java
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/")
public class DispatcherServlet extends HttpServlet {
private MemberController memberController = new MemberController();
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws
ServletException, IOException {
String uri = request.getRequestURI();
if (uri.equals("/member_insert")) {
memberController.insert(request, response);
} else if (uri.equals("/member_delete")) {
memberController.delete(request, response);
}
}
}
controller/MemberController.java
public class MemberController {
private MemberDAO memberDAO = new MemberDAO();
public void insert(HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
MemberVO member = new MemberVO();
member.setId(request.getParameter("id"));
member.setPassword(request.getParameter("password"));
member.setName(request.getParameter("name"));
memberDAO.insertMember(member);
request.setAttribute("member", member);
RequestDispatcher rd =
request.getRequestDispatcher("views/member_result.jsp");
rd.forward(request, response);
}
public void delete(HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
String id = request.getParameter("id");
memberDAO.deleteMember(id);
request.setAttribute("member_id", id);
RequestDispatcher rd =
request.getRequestDispatcher("views/member_result.jsp");
rd.forward(request, response);
}
}
📌Model
dao/MemberDAO.java
import java.util.HashMap;
import java.util.Map;
public class MemberDAO {
private Map<String, MemberVO> members = new HashMap<>();
public void insertMember(MemberVO member) {
members.put(member.getId(), member);
}
public void deleteMember(String id) {
members.remove(id);
}
}
vo/MemberVo.java
public class MemberVO {
private String id;
private String password;
private String name;
// getters and setters
public String getId() {
return id
;
}
public void setId(String id) {
this
.id = id;
}
public String getPassword() {
return password
;
}
public void setPassword(String password) {
this
.password = password;
}
public String getName() {
return name
;
}
public void setName(String name) {
this
.name = name;
}
@Override
public String toString() {
return "MemberVO{"
+
"id='" + id + '\\''
+
", password='" + password + '\\''
+
", name='" + name + '\\''
+
'}'
;
}
}
💡 느낀점
Spring을 본격적으로 배우기 전 Servlet에 대하여 공부하였다 !
서블릿을 배우는 이유는 Spring에 비해 직관적이라 Spring을 들어가기 전 개념을 정리하기에 좋다고 한다.
본격적으로 백엔드에 대해 공부하는 첫번째 섹션이여서 매우 설렜으며, 그 다음 섹션인 Spring을 들어가기 전 백엔드를 맛볼 수 있는 좋은 기회였다 ㅎㅎ
Servlet은 Spring에 비해 강의가 많이 않아 교육과정이 더욱 더 유익하였다 😊
스프링아 기다려 --🎈

'[KB IT's Your Life] Today I Learnd' 카테고리의 다른 글
| [KB IT's Your Life] 6주차 컴포넌트 백엔드: 게시판 만들기💡 (3) | 2024.09.02 |
|---|---|
| [KB IT's Your Life] 5주차 컴포넌트 백엔드: Rest 실습 프로젝트💡 (0) | 2024.08.26 |
| [KB IT's Your Life] 4주차 컴포넌트 백엔드: MyBatis실습 프로젝트💡 (0) | 2024.08.18 |
| [KB IT's Your Life] 3주차 컴포넌트 백엔드2 💡 (6) | 2024.08.12 |
| [KB IT's Your Life] 1주차 데이터베이스 활용 & 모델링 💡 (1) | 2024.07.27 |