본문 바로가기
java

[Java] 서버 프로그래밍 - 특강으로 맛보기, 배운것과 앞으로 배워야할 것 #2

by jinbro 2017. 9. 14.

[미리 정리하기]

- jsp 개념, 사용방법

- jsp가 servlet 변환 -> .java

- jsp / servlet 로딩타임

- web.xml 존재

- 쿠키, 세션

- redirect 와 forward의 차이

- jdbc를 사용하는 이유, mysql 외부 서버에 접속하기위해 필요한 것



[강의내용]

(1) 이클립스 다이나믹 웹어플리케이션 생성부터

- test 폴더 추가하기 : 패키지 생성까지

- web.xml 생성 추가

=> 웹 컨테이너에게 클라이언트가 요청한 URL 주소가 서블릿 요청임을 인식하고, 서블릿 클래스 위치를 알려주기위한 정보가 있는 파일

=> URL과 매핑된 서블릿 클래스를 동적로딩 : 다음 포스팅에서 동적로딩부터 쓰레드 생성, 사이클까지 다룰 예정, 이번엔 jsp부터 살펴봄

=> DD(Deployment Description)라 함

=> 앱 생성할 때 체크해서 추가해도 되고, 톰캣 웹앱스 하위 디렉토리에 있는 예제 프로젝트에 포함된 파일 가져와서 고쳐도됨

=> WebContent/WEB-INF 하위에 위치하게하면 됨

=> xml 문서

 

- 필요한 라이브러리 lib 디렉토리에 옮기기

- 이클립스 사용 시 사용하지않는 프로젝트는 close project 하기

- build path 설정해주기 : 컴파일 빌드 패스 설정해주기(WEB-INF > classes)

 

(2) jsp 파일 생성

- WebContent에 생성

 

 

[jsp]

(1) 이전에는 html만 만들어내는 것이 목적

- 웹서버만 -> 웹어플리케이션 서버가 필요해짐(톰캣 -> 서블릿)

- 모바일 서버에서는 쓰지않음 : 데이터만 필요하기때문에

 

(2) 내부적으로는 서블릿임 : 변환됨

- 최초 이외에 이미 변환된 파일을 실행함 : 서블릿 실행 형태와 같음

 

(3) 사용방법 : <>안에 들어가는 코드는 자바 코드로 변경됨(.java 생성 -> .class 변환)

- <% 자바코드 %> : 일반 자바코드 작성

- <%= 변수명 % > 와 ${ 변수명 } : 변수 호출할 때 사용

- <%-- --%> : jsp 주석, 변환될 때 포함안됨

- <%@ %> : 지시자 역할, .java로 변환될 때 필요한 설정사항을 포함하는 태그

- <%! %> : 객체 타입의 멤버(var, method)를 선언할 때 사용

- 표준액션 : <% %>를 XML의 태그와 같은 모양을 취할 수 있음

- 표준태그라이브러리 : 표준 액션처럼 커스텀 태그 중에 자주 사용되는 것들을 별도로 표준화한 라이브러리

 

(4) 코드 변환 경로 : 이클립스 워크스페이스 하위 디렉토리에 위치함

- /Users/유저명/eclipse-workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/work/Catalina/localhost(맥 기준)

- 코드 변환되기때문에(.java) .java에서 사용되는 변수를 사용할 수 있음 : 쓰지맙시다... 코드가 더러워집니다

- _jspService() 내부로 옮겨감 : 서블릿은 service() -> doGet, doPost가 있지만 내부에서 분기됨

 

(5) 라이프사이클과 속도

- 첫번째 라인 : jsp 요청 -> .java로 변환 -> .class로 변환해서 리턴

- 두번째 라인부터 : 서블릿 두번째 라이프사이클과 마찬가지로 리턴

- 결론 : 스크립트코드방식(JIT) - 최초 퍼포먼스가 떨어짐, 그다음부터는 AOT와는 동일하다고 보면 됨

=> 빠르다고 주장하는 것은 서블릿은 service() 호출 후 doGet, doPost 등 호출 분기가 되는데, jsp는 _jspService()(jsp 파일에서

     .java 파일로 변환된 형태에서 나오는 메서드명임, 내부적인 이름)에서 분기되어서 호출

 

=> jsp가 변환되어 만들어진 .java 파일과 서블릿.java 파일을 비교해보기

 

(6) jsp, 서블릿 로딩타임

- 클래스 파일 동적 로딩 타임 : .class로 변환 - 서블릿 인스턴스 생성(최초 접근만) - init() 호출 - service() 호출( _jspService() )

- 최초 실행을 클라이언트가 아니라 개발팀에서 실행하는 것이 좋음 : 실제로 해보니 초기 로딩타임이 꽤나 있음

- 멀티쓰레드 : 최초 생성된 객체(서블릿)를 재사용하는 방식

=> 하나의 서블릿 인스턴스를 돌려쓰는 형태라서 멤버변수가 공유됨 : 위험합니다

 

- 서버 코드 리프레시되고 최초 접근이 이뤄져야 .class 파일이 생성됨 : 코드만 변경해서는 안됨

 

(7) 에러 처리 페이지는 변경합시다

- 내부 코드가 노출됩니다 : 이후에 자세하게 다뤄봄

 

(8) jsp 태그 분석

1) <%@ %>

- 코드 : <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

- 코드2 : <%@ page import = "java.util.ArrayList, java.util.Calendar" %>

- 코드3: <%@ include file="b2.jsp" %>(정적 include : 조심할점은 html, body 태그 등을 없애야함, 변수명 겹침을 피해야함)

=> .java 변환될 때 하나의 .java에 포함되기때문에
=>
<jsp:include  page="b3.jsp"></jsp:include> : 동적 include 사용

 

- 표준액션태그 : 자바 코드를 태그화 시킨 것(사용할일은 없을듯), 페이지 공유하는 것처럼 만들기위해서

=> 자바 코드에서는 : request 파라미터를 사용, RequestDispatcher 등등(구현하려고 하는 형태에 따라 다름)

 

- 표준액션태그 : jsp:useBean(인스턴스 생성), jsp:set/getProperty(인스턴스 필드값), jsp:forward(포워드 기능) 등이 있음

=> .jsp를 .java로 변경할 때 필요한 설정사항을 씀, 필요한 패키지를 import 할 때 사용함(클라이언트가 아니라 톰캣 변환 설정 사항임)

=> language : 원래는 visualbasic, php 등에도 사용하려고 했으나 안받아줌, 그래서 있어도 없어도 됨

=> import : .java에서 import 해야할 패키지가 있을 때 사용

=> include : 페이지에 페이지를 삽입하기위한 설정 속성(문서의 html)

=> session : 세션 사용여부(객체 생성 여부)

=> .java 변환 코드(import만) : import java.util.ArrayList;  import java.util.Calendar; (IDE에서 추천해주고 추가까지 해줌)

 

2) <%! %>

- jsp 코드는 _jspService() 내부에 생성됨 : .java로 변환되었을 때

- <%! 를 사용하면 객체타입의 멤버로 선언됨 : global var, global method

- .jsp 코드가 내부적으로 변환되고 리턴되는 것을 알아야함

 

3) ${ }

- request 파라미터로 넘어오는 값을 출력할 수 있음

- request Attribute(속성값)을 출력할 수 있음

- 파라미터 가져오기 : ${ param.파라미터명 }

- 속성값 출력하기 : ${ 속성명 }

 

4) JSTL : JSP Standard Tag Library

- JSP에서 자주 사용하는 커스텀태그 라이브러리(표준 X)

- 서버에서 처리를 하지 굳이 사용하지않음

- jar 집어넣고 커스텀 태그<%@ taglib %> 해줘야함 : 표준이 아니기때문에

- <c:set /> 과 같이 사용

=> c라는 네임스페이스(프리픽스) 사용을 위해 taglib 임포트 해줘야함

 

- <c:set>으로 선언한 변수는 ${}로 호출 가능

- <c:forEach>를 사용하려고 사용

 

 

(9) jsp 문법에서 쓸 수 있는 주요 객체 : .java로 변환되었을 때 HttpServlet 객체 구현 타입의 멤버 객체

- request

- response

- out

- page : this(jsp - servlet)

- session : 세션 객체, jsp 사용 시 <%@ %> false 처리할 경우 HttpSession 인스턴스 생성해줘야함(기본값 true)

 

 

(10) redirect : 2가지 방법이 있음, 보여지는 것은 같지만 url이 다름(servlet도 같음, 결국 변환되는 것이니깐 같은 코드)

- response.sendRedirect("페이지파일명");

=> response.sendRedirect("f2.jsp");

 

- dispatcher.forward()

=> RequestDispatcher dispatcher = request.getRequestDispatcher("f2.jsp");

      dispatcher.forward(request, response);

 

- 차이점 : 단절된 2번의 요청에 대한 2번의 응답인지, 일관된 1번의 요청에 대한 1번의 응답인지 차이

=> response.sendRedirect : http://localhost:8080/sam2/f2.jsp

    - 요청이 2번, 응답 2번 : 다시 접속하라고 서버에서 클라이언트로 다시 클라이언트에서 서버로 서버가 결과 응답

    - 서로 다른 각각의 요청을 날리는 것 : 새로운 요청, 요청은 이전 요청을 기억하지못함(데이터가 이어지지않음)

    - 모바일에서는 다시 접속하라는 것을 알지못함 : forward를 사용해야함(2번째 방법)

 

=> request.getRequestDispatcher : http://localhost:8080/sam2/f1.jsp?name=jinbro 

    -  요청 1번, 응답 1번 : 1번의 흐름에 요청-응답처리 모두, 서버 내부적으로만 처리 

    -  그래서 요청 주소는 변경되지않음 : 내부적으로 서버만 이동하는 것이므로

    -  중간에서 처리해서 응답할 수 있음 : 요청할 때 받은 쿼리스트링(파라미터)을 가지고 처리 후 서버 내부 이동처리할 수 있음

    => 예제코드 g1.jsp, g2.jsp 참고

   

    - request와 response를 넘겨줘서 연속되게 요청/응답하게끔

 

 

[쿠키와 세션] : h, i 계열 예제코드

(1) 공통점 : 데이터 저장(상태 유지)

(2) 차이점 : 데이터 저장장소, 클라이언트 하드디스크(쿠키)와 서버 메모리(세션, 응용프로그램 - 서버 프로그램) 상 차이

 

(3) 알아야 하는 지식

- HTTP : 접속되고 난 후 접속을 끊어버림 - 접속이 유지된다면 과부하(HTTP 의 장점)

- 쿠키와 세션 : 다시 들어갈 때 나를 알리기위해(이전 요청), 연속된 서비스가 가능하도록 해줌

=> 연결되어있는 것이 아님, 그런 효과

 

- 쿠키 : 클라이언트에 저장(쿠키 사용함을 설정해야함 - 보통은 사용함으로 설정되어져있음) , 8kb까지 저장

- 세션 : 서버에 저장(메모리 상에서만 상주하다가 응용프로그램 종료되면 제거), 세션 ID 할당

- 웹 : 쿠키와 세션 사용(헤더를 통해서 전달됨)

- 모바일 : 쿠키, 세션을 거의 사용x, 파라미터로 전달

 

(4) 쿠키 객체 타입 : Cookie(response, request의 메서드로 쿠키 객체를 다룰 수 있음)

- request.getCookies() / response.addCookie() : 서버에서 addCookie 하지않으면 null 상태

- 쿠키는 고유 이름을 가짐 : 같은 이름은 무조건 같은 1개의 쿠키

- 기본적으로 쿠키 지속 저장시간은 프로세스가 종료될 때까지 : setMaxAge로 더 유지, 짧게 유지할 수 있음

- 쿠키 수정, 삭제는 따로 메서드가 존재하는 것이 아니라 같은 이름으로 새롭게 생성하면 됨

=> 새로운 값을 할당 혹은 빈문자열 할당

 

(5) 세션 설명 및 객체 타입

- 메모리 안정성 유지를 위해 서버에서 임의로 제거함 : 시간 제한

- 쿠키로 요청마다 세션 ID 부여 : 같은 세션ID라면 최초 1회 발급

- HttpSession에 저장하며 가져온 세션을 저장, request.getSession(true)으로 세션(세션ID)을 가져오거나 새롭게 생성 후 리턴

- setAttribute : 세션 데이터 추가(로그인 했을 때) / removeAttribute : 세션 데이터 삭제 / invalidate : 세션 끝내기(로그아웃 기능)

=> invalidate() : 세션 객체 null, 세션 객체 날린 후 리다이렉트 페이지에는 session 자동생성되지않도록(jsp 경우)

=> 결론은 jsp로 간단한 자바 작업을 해도 로직은 서블릿에서만 합시다 : 변환되어도... 자동으로 세팅되는 것들이 있으니


[JDBC와 mysql 외부 서버 연결]

(1) Sequel Pro : 맥 mysql서버 gui 관리 응용프로그램

- 테이블 만들고 예시로 사용할 쿼리 ㄱ

 

(2) JDBC : JDBC 관련 유틸리티 객체 타입화해서 사용(JDBCUtil.java - 디비 연결과 연결끊기, 연결해서 사용하는 것은 따로 타입화해서 사용)

- 관계형 데이터베이스(RDBMS) 접속, SQL문 실행하기위해 제공되는 API

- 표준화된 방법 : 다양해진 RDBMS, 일관화된 API

=> JDBC 소개 문서 : https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/

 

- JDBC 드라이버 : 자바 프로그램의 요청을 DB가 이해할 수 있는 프로토콜로 변환해주는 클라이언트 사이드 어탭터

=> 외부 RDBMS 서버 연결을 제공

 

- Java Database Connectivity

- 사용하기 : 우리는 각 벤더사마다 다루는 방법이 아닌 제공되는 API 사용방법을 익히자

1) 외부 디비 설치, 시작, 디비 - 테이블 생성 : 자바 개발환경은 모두 설치되어있다는 전제

2) 각 디비 홈페이지에서 JDBC 드라이버 제공 : http://mvnrepository.com/ 에서 mysql 검색 - MySQL Connector/J

3) JDBC 드라이버 메모리 로드 : Class.format("클래스 풀네임");

- ClassNotFoundException 발생할 수 있음 : 예외처리 필요, 던지지 맙시다...

 

4) Connection 구현체 리턴받기 : Connection conn = DriverManager.getConnection("jdbc:mysql://아이피:3306//디비명", "계정", "비번");

- getConnection 인자로 전달되는 값에 따라 특정 데이터베이스 벤더가 구현한 Connection 타입 인스턴스 반환

- 제대로 반환 받았다면 성공적으로 연결되었다는 것

 

5) conn 객체의 메서드

- SQL 실행 - 기능에 맞게 각 서블릿 혹은 컨트롤러(.java)에서 사용(conn을 얻어오는 JDBCUtil.getConnection 실행)될 것

- CRUD 구현 : DAO 객체 타입 - Database Access Object, 데이터베이스의 데이터에 액세스하는 객체, 조회, 조작 메서드를 가짐

- SQL문은 java.sql.PreparedStatement 사용 : conn.prepareStatement("쿼리문")으로 PreparedStatement 인스턴스 리턴받음

- SELECT 쿼리 : ResultSet(디비용 컬렉션)형을 반환함

- 생각해야할 것은 쿼리 실행 시 syntax 에러나 잘못된 요청에 의해 예외가 발생할 수 있음 : 예외처리!

 

6) 자원 반환

- 반드시 반환받아야함

- SQL 문 실행으로 예외가 발생한다하더라도 실행 후 반드시 반환 : SQL 실행 관련 try ~ catch 후 finally 에 반환 코드 등록

- close() 메서드를 두가지로 나눠야함 : select 문을 사용했을 경우(ResultSet 사용함 - JDBC에서 사용되는 컬렉션)와 이외의 경우

(코드)

try{

 

} catch(SQLException e){

 

} finally {

    /* 코드는 여기에 */

}

 

 

(3) JDBC - 드라이버로 연동해서 사용한 결과

 

[알아볼 것]

(1) redirect, requestGetDispatcher 요청 흐름

- request.setAttribute 사용까지 : 요청시 서버에 값을 전달할 때 사용하는 방법

 

(2) 웹스코프 : 요청할 때 보내준 값이 어디까지 사용되나

- request

- session

- web : request.setAttribute로 데이터 공유

- application

 

(3) JUnit 사용방법 익히기

 

 

[알아야할 것]

(1) .jsp는 .java로 변환됨 : 에러 발생이나 어떠한 처리를 해줄 때 어떤 부분에서 그만하고 싶으면 return;을 날려줘야함

- .jsp에서 작성한 코드는 .java 파일을 보면 _jspService() - 메서드 내 코드로 들어감 : 동작 중인 메서드 중단할 때 return

 

(2) 모바일 하이브리드앱에서는 일반적으로 쿠키, 세션을 사용하지않고 파라미터로 사용 :  request.getParameter("")로 얻음

- 웹에서는 파라미터 조작이 가능하기때문에 쿠키, 세션을 사용해서 데이터 유지

- 모바일까지 사용하는 서버를 개발해야하기때문에 모바일 돌아가는 과정도 알아야함

 

(3) 서버의 자원을 사용하는 것과 클라이언트 자원을 사용하는 것 구분해야함

- 지금까지 나온 개념 중에 쿠키를 제외하면 서버 자원을 사용 : 요청을 받아들이는 것부터가 서버 자원 사용(서버 프로세스의 쓰레드)

 

(4) 응답코드에 따른 분기처리 : 1xx, 2xx, 3xx, 4xx, 5xx

(5) 클라이언트 포멧(헤더) 혹은 요청포멧(request.setAttribute)에 따라 응답 달리하기 : 서버 역할(데이터 응답)

- Attribute와 Parameter 차이까지 파악하기

 

(6) 현업에서는 db 테이블 구성할 때 ip와 시간은 반드시 넣어야함

- 테이블명 앞에는 tbl_테이블명 붙임

- 그리고 GUI 관리툴 씁시다 : 맥은 Sequel Pro가 좋네요


댓글