반응형

Web Application 개발을 위한 프로그램 설치 및 환경설정

⑴ JDK 설치 및 환경설정

jdk 다운로드 및 환경변수 설정하기

⑵ DBMS 설치 (OralceXE)

[Oracle] 오라클 다운로드 후 작업

⑶ Eclipse 설치

이클립스(eclipse) 다운로드 및 실행

⑷ WAS(Web Application Server) 설치 : Apache Tomcat

https://tomcat.apache.org 사이트에서 Apache Tomcat 다운로드 압축 해제
→ 이클립스에서 사용될 수 있도록 WAS 추가 작업



JRE 경로 필요



→ 설치 완료 후 http://localhost:8080/ 브라우저 접속했을 때 하단의 캡처처럼 나오면 끝!




이클립스에서 WAS 추가 및 사용 방법 (JavaEE Perspective)

⑴ Servers View : WAS 목록 출력 및 제어(시작 또는 중지에 대한 상태 변경)

WAS 추가 : Apache Tomcat 등록


Finish → Apply and Close


그다음엔 이클립스에 서버 선택


→ Open 클릭하면 하단의 Servers 창이 생성됨



→ 저 링크 클릭


→ 하단이 이렇게 바뀜



⑵ 등록된 WAS의 환경설정 : Apache Tomcat 프로그램의 환경 파일 변경(Server.xml)

  • Server 위치 변경 : Apache Tomcat 프로그램 설치 위치(Deploy Path 변경)
  • PORT 변경 : HTTP/1.1(8080 > 8000)

Tomcat v9.0 Server at localhost 더블클릭
경로 설정 후 포트 번호가 겹치지 않게 바꿔준다.

⑶ 클라이언트의 요청과 응답처리를 위해 WAS를 실행상태로 변경

  • WAS 관리 : WAS 등록, WAS 제거, 등록 위치 변경
    • Window > Preferences > Server > Runtime Environments

우클릭 후 START 클릭 - 서버 실행






Web Application 개발

⑴ Dynamic Web Project 생성

  • 프로젝트명은 웹에서 콘텍스트명(ContextName)과 동일
  • 프로젝트의 프로그램을 실행하기 위한 WAS 선택
  • web.xml 생성 : 프로젝트의 WAS 실행환경 설정

무조건 체크 해준다.
프로젝트 폴더안에 WebContent 폴더가 들어있으면 성공



⑵ Project 파일

  • Java Resource : Java 소스파일(Servlet 또는 JavaBean - DTO, DAO)
  • WebContent : CSL(HTML, CSS, JavaScript) 파일 또는 JSP 파일

조합형 한글 UTF-8 설정


⑶ 웹어플리이션 실행(Ctrl + F11) : URL 주소를 이용한 서버 자원을 WAS에게 요청

URL 주소 → http://ServerName : Port/Context/WebFilePath
ex) http://localhost:8000/web/hello.html

  • 요청과 응답은 브라우저를 이용하며 브라우저는 크롬을 사용하는 것을 권장
    • Window > Web Browser : Chrome 변경
  • 크롬이 없는 경우 >> 크롬 설치 후 등록
    • Window > Preferences > General > Web Browser : Chrome 추가



내가 만든 html파일을 실행하면 끝!! 참 간단하죠?

반응형
반응형

어텐션 메커니즘 (Attention Mechanism)

  • seq2seq 모델의 문제점 : 전체 문장에 대해서 context를 단 한 번에 넘겨줌
  • 매 순간마다 데이터를 다 넣어주기 위해 사용

 

Seq2seq model

  • 전체 문장에 대한 정보를 한꺼번에 벡터 하나로 만들어서 넘겨주니까 token에서의 정보는 하나도 안 남아있고, 전체 문장에 대한 Context만 넘어감

 

Attention은 Seq2seq model을 보완하고자 만든 것

 

 

Attention

  • 쿼리에 대해서 모든 키와의 유사도를 각각 구하고, 유사도를 키와 맵핑되어 있는 각각의 value에 반영
  • Query : t 시점의 디코더 셀에서의 은닉 상태
  • Keys : 모든 시점의 인코더 셀의 은닉 상태
  • Values : 모든 시점의 인코더 셀의 은닉 상태

 

→ Attention Value는 Query랑 Key가 들어가서 Value가 곱해져서 다 합쳐진 거임 (먼 소리야ㅎㅎ,,)

 

 

Dot-product Attention

  • 매 순간마다 앞에 있던 것을 다 같이 보겠다는 것
  • 기본적으로 곱하기임

 

→ softmax Layer에서 더 연관이 있는 단어에 weight를 더 많이 줘서 weight들을 전부 더해서 다음에 나올 단어를 예측한다.

 

그 외의 Attention 종류들

 

 

 

Attention 실습

  • 전에 만들었던 glove_lstm_classification.ipynb 에 attention을 추가해서 만듬
    • 다른 거는 똑같고, model 쪽에 attention 추가
from collections import Counter
import urllib.request
import pandas as pd
import numpy as np
import tensorflow as tf

import nltk
from nltk.tokenize import sent_tokenize
from nltk import WordPunctTokenizer

nltk.download('punkt')
from google.colab import drive
drive.mount('/content/drive')
# spam classification data loading
urllib.request.urlretrieve("https://raw.githubusercontent.com/mohitgupta-omg/Kaggle-SMS-Spam-Collection-Dataset-/master/spam.csv", filename="spam.csv")
data = pd.read_csv('spam.csv', encoding='latin-1')
data[:5]
texts = list(data['v2'])
labels = list(data['v1'])

print(texts[:5])
print(labels[:5])

print(Counter(labels))
# glove vector model initialize
glove = {}
with open('/content/drive/My Drive/Colab Notebooks/data/news_sample/glove.6B.50d.txt', 'r', encoding='utf-8') as fr:
    for line in fr.readlines():
        temp = line.strip().split()
        word = temp[0]
        vector = temp[1:]

        glove[word] = list(map(float, vector))
def tokenize(document):
  words = []
  sentences = sent_tokenize(document) # sentence tokenizing

  for sentence in sentences:
    words.extend(WordPunctTokenizer().tokenize(sentence)) # word tokenizing

  return [word.lower() for word in words] # case normalization

def get_vector(sentence):
  tokens = tokenize(sentence)
  vector = [glove[token] if token in glove.keys() else [0]*50 for token in tokens]

  while len(vector) < 256:
    vector.append([0] * 50)
  
  return vector[:256]
x = [get_vector(text) for text in texts]
x_train, x_test = np.array(x[:5000]), np.array(x[5000:])
y = [0 if label == 'spam' else 1 for label in labels]
y_train, y_test = np.array(y[:5000]), np.array(y[5000:])

 

  • 모델 생성
    • tf.keras.layers.LSTM(128) → 자동으로 LSTM이 다대일로 해서 제일 마지막 결과만 여기 layer에서 출력해준다.
    • (tf.keras.layers.LSTM(128, return_sequences=True))
      → 모든 칸에 대해서 반환
    • Query밖에 없고 Key와 Value가 필요한 경우
      → 세 개를 똑같은걸 넣어줄 때 salf-attention이라고 함
    • tf.keras.layers.Attention()([lstm_layer, lstm_layer, lstm_layer])
      → 원래는 Query, Key, Value 순서대로 넣어야 되는데 지금 Query 하나밖에 없기 때문에 똑같은 거를 넣어줌,, 이거를 salf-attention이라고 함
input_layer = tf.keras.layers.Input(shape=(x_train.shape[1], x_train.shape[2]))
lstm_layer = tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(128, return_sequences=True))(input_layer)
attention = tf.keras.layers.Attention()([lstm_layer, lstm_layer, lstm_layer])
flatten = tf.keras.layers.Flatten()(attention)
dense1_layer = tf.keras.layers.Dense(64, activation = 'relu')(flatten)
dense2_layer = tf.keras.layers.Dense(2, activation = 'softmax')(dense1_layer)

model = tf.keras.Model(inputs=input_layer, outputs=dense2_layer)
model.summary()

 

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(x_train, y_train, epochs=2)

 

model.evaluate(x_test, y_test, verbose=2)

결과

 

glove 벡터를 가지고 넣어줬는데 모델 자체에 embedding Layer를 추가할 수 있음! 그럼 vocabulary 아이디만 넣어주고 모델을 활용할 수 있음

 

 

Embedding + lstmm + attention 분류 실습 - embedding_layer_lstm_attention_classification.ipynb

from collections import Counter
import urllib.request
import pandas as pd
import numpy as np
import tensorflow as tf

import nltk
from nltk.tokenize import sent_tokenize
from nltk import WordPunctTokenizer

nltk.download('punkt')
# spam classification data loading
urllib.request.urlretrieve("https://raw.githubusercontent.com/mohitgupta-omg/Kaggle-SMS-Spam-Collection-Dataset-/master/spam.csv", filename="spam.csv")
data = pd.read_csv('spam.csv', encoding='latin-1')
data[:5]
texts = list(data['v2'])
labels = list(data['v1'])

print(texts[:5])
print(labels[:5])

print(Counter(labels))

 

  • vocab을 만드는 코드 생성
  • vector는 vocab이라는 것을 받아서 vocab에 있으면 vocab에 token ID 만 줄 거임, 없을 때는 vocab에 unk을 넣어서 줄거임
  • vector가 256보다 작을 때는 <pad>라고 줄 거임
def tokenize(document):
  words = []
  sentences = sent_tokenize(document) # sentence tokenizing

  for sentence in sentences:
    words.extend(WordPunctTokenizer().tokenize(sentence)) # word tokenizing

  return [word.lower() for word in words] # case normalization

def make_vocab(documents):
  word2index = {'<unk>':0, '<pad>':1}
  for document in documents:
    tokens = tokenize(document)
    for token in tokens:
      if token not in word2index.keys():
        word2index[token] = len(word2index)

  return word2index

def get_vector(sentence, vocab):
  tokens = tokenize(sentence)
  vector = [vocab[token] if token in vocab.keys() else vocab['<unk>'] for token in tokens]

  while len(vector) < 256:
    vector.append(vocab['<pad>'])
  
  return vector[:256]

 

  • vocab을 어떻게 만들었는지 확인, tokenize에 있는 결과 확인, vector 결과 확인
vocab = make_vocab(texts)
print(vocab)
print(texts[0])
print(tokenize(texts[0]))
print(get_vector(texts[0], vocab))

→ get_vector(texts[0], vocab) : 19까지는 ID가 있고 나머지 뒤에 1들은 pad가 채워짐 (256보다 짧기 때문에)

 

  • x_train = 5000 * 256
x = [get_vector(text, vocab) for text in texts]
x_train, x_test = np.array(x[:5000]), np.array(x[5000:])
y = [0 if label == 'spam' else 1 for label in labels]
y_train, y_test = np.array(y[:5000]), np.array(y[5000:])
print(x_train.shape)

결과

 

 

  • 256개의 token에 대해서 embedding Layer가 붙어야 함
    • tf.keras.layers.Embedding(len(vocab), 100) → 100 : 사이즈 → 임베딩 테이블이 word2vec랑 똑같이 생김 → 각 vocab에 대해서 100차원짜리 임베딩 테이블 생성
    • tf.keras.layers.Dropout(0.5)(embedding_table(input_layer)) → 임베딩 테이블에 input이 들어가서 dropout
    • 이렇게 만들면 glove 벡터를 따로 불러서 넣어줄 필요 없이 자체적으로 word2vec 모델을 안에 내장해버림,, → word2vec 모델도 실시간으로 같이 한꺼번에 학습됨! 학습 속도는 느려질 수 있음
input_layer = tf.keras.layers.Input(shape=(x_train.shape[1]))
embedding_table = tf.keras.layers.Embedding(len(vocab), 100)
embedded_layer = tf.keras.layers.Dropout(0.5)(embedding_table(input_layer))
lstm_layer = tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(128, return_sequences=True))(embedded_layer)
attention = tf.keras.layers.Attention()([lstm_layer, lstm_layer, lstm_layer])
flatten = tf.keras.layers.Flatten()(attention)
dense1_layer = tf.keras.layers.Dense(64, activation = 'relu')(flatten)
dense2_layer = tf.keras.layers.Dense(2, activation = 'softmax')(dense1_layer)

model = tf.keras.Model(inputs=input_layer, outputs=dense2_layer)
model.summary()

 

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(x_train, y_train, epochs=2)

model.evaluate(x_test, y_test, verbose=2)

 

반응형
반응형

Annoy

  • 임베딩 들은 similarity를 직접 구하는 게 많이 사용되는데 특히 추천 같은 경우에서는 다른 사람들의 리스트와 내 리스트가 비슷한 경우에는 제일 비슷한 사람의 리스트에서 내가 보지 않은 리스트들을 추천해줌 (예로 들어 넷플릭스)
  • 모든 유저랑 내 기록이랑 similarity 구하는데 유저가 많으면 너무 오래 걸리기 때문에 그런 문제를 해결하기 위해서 나온 Annoy 라이브러리

 

Nearest Neighbor (근접 이웃)

  • 새로운 데이터를 입력 받았을 때, 가장 가까이 있는 것이 무엇이냐를 중심으로 새로운 데이터의

 

 

 

→ 이제까지는 분류모델을 학습을 했는데 각각의 데이터가 있으면 새로 들어온 데이터의 제일 근접한 같은 분류를 하기도 함

 

Annoy (Approximate Nearest Neighbors Oh Yeah)

  • 빠르게 벡터 유사도 검색을 수행할 수 있는 라이브러리
  • 정확한 벡터보다는 유사한 벡터를 찾기 때문에 정확도는 조금 낮아질 수 있으나 속도가 매우 빨라짐
  • Tree를 활용하여 유사한 벡터를 검색
  • Tree를 만드는 과정을 build라고 하며, build 된 Tree는 수정이 불가능

https://github.com/spotify/annoy

 

Annoy 실습 예제

  • 전에 만들었던 use_dnn_classification.ipynb 을 수정해서 만듬
    • 모델 생성해주고 정의하는 부분까지 동일함
!pip install tensorflow_text
!pip install annoy

from annoy import AnnoyIndex
from collections import Counter
import urllib.request
import pandas as pd
import numpy as np

import tensorflow as tf
import tensorflow_hub as hub
import tensorflow_text
# spam classification data loading
urllib.request.urlretrieve("https://raw.githubusercontent.com/mohitgupta-omg/Kaggle-SMS-Spam-Collection-Dataset-/master/spam.csv", filename="spam.csv")
data = pd.read_csv('spam.csv', encoding='latin-1')
data[:5]

 

 

texts = list(data['v2'])
labels = list(data['v1'])
print(texts[:5])
print(labels[:5])
print(Counter(labels))

# 모델 가져오기
model_url = 'https://tfhub.dev/google/universal-sentence-encoder-multilingual/3'
model = hub.load(model_url)
x = model(texts)
x_train, x_test = np.array(x[:5000]), np.array(x[5000:])
y = [0 if label == 'spam' else 1 for label in labels]
y_train, y_test = np.array(y[:5000]), np.array(y[5000:])

 

  • 지금 vector_size가 512이기 때문에 AnnoyIndex에 넣어주고 어떤 방법을 활용해서 거리를 구 할 건지 설정 → 'dot' 이 기본
  • Tree인덱스를 만들고 Tree 인덱스에 5000개를 넣는다.
# annoy indexing
vector_size = 512
index = AnnoyIndex(vector_size, 'dot')
data = []
vectors = model(texts)
for idx in range(len(vectors)):
  data.append({'idx':idx, 'text':texts[idx], 'vector':vectors[idx], 'label':labels[idx]})
  if idx < 5000: #indexing only 5000 samples, the others will be used for evaluation.
    index.add_item(idx, vectors[idx])

index.build(50)
index.save('spam_mail.annoy')

결과

 

 

 

 

  • 5000부터 나머지 데이터에 대해서 비교
    • 검색하는 방법 : load_index.get_nns_by_vector(data[5000]['vector'], 100)
      → 100은 몇 개를 검색할지 지정
# evaluation. check accuracy with nearest label
load_index = AnnoyIndex(vector_size, 'dot')
load_index.load('spam_mail.annoy')

result = load_index.get_nns_by_vector(data[5000]['vector'], 100)
print(result)

 

 

→ 5000번에 대한 데이터에서 제일 가까운 순서대로 100개 출력

 

  • 4번 데이터의 text와 label , 5000번 데이터의 text와 label 확인
print(data[4]['text'], data[4]['label'])
print(data[5000]['text'], data[5000]['label'])

 

→ 5000번의 벡터를 넣어서 test를 했을 때 나온 text랑 제일 비슷한 text는 4번 text이다.

→ 라벨은 ham으로 동일하다는 것은 accuracy는 맞다고 할 수 있음

 

  • 5000개를 다 검사
    • idx에서 label이랑 result[0]에 있는 label이랑 같으면 count를 올리고, total은 그냥 올림
# evaluation. check accuracy with nearest label
load_index = AnnoyIndex(vector_size, 'dot')
load_index.load('spam_mail.annoy')

count = 0
total = 0
for idx in range(5000, len(data)):
  result = load_index.get_nns_by_vector(data[idx]['vector'], 100)
  if data[idx]['label'] == data[result[0]]['label']:
    count += 1
  total += 1

print(count/total)

결과

 

→ 분류를 굳이 하지 않아도 제일 유사한 문장의 label과 비교를 했을 때 성능이 98점이 나옴

→ 이렇게 검색을 하면 전체 검색보다 훨씬 빠르기 때문에 이런 식으로 서비스 사용하기도 함

 

왜 100개를 검색을 했는가?
Tree를 50개를 생성을 했는데 제대로 동작을 하려면 무조건 트리의 개수보다 많아야 함
→ 트리의 두세 배를 검색하게 되면 100개를 검색하면 각 트리에서 두배를 검색을 한 다음 그 100개를 가져와서 100개를 정렬하는 것임,,
→ 라이브러리 동작 방식이 100개를 검색하는 것과 1개를 검색하는 것이 성능이 너무 달라지기 때문에 100개를 검색을 하게 됨

각 트리에서 나눠져서 동시에 검색을 하기 때문에 Tree의 개수가 많으면 훨씬 빠르고 성능이 좋음

 

반응형
반응형

저는 대학 졸업하기 전에 서울로 올라와서 Java 국비지원 학원을 6개월 동안 열심히 다니고, 학원 다니면서 학교를 졸업했는데요.
서울살이가 처음인데 진짜 놀러안가고 열심히 공부했던 것 같아요 ㅋㅋㅋ
생각보다 개발이 너무 재미있어서 그랬네요

원래는 학원 수료하고 난 후 바로 취업을 하려고 준비했으나 개인적인 문제로 몇 개월 동안 본가에서 쉬면서 Python을 공부해보자! 해서 책 사서 혼자 공부했는데요.
 
우선 파이썬을 공부하게 된 첫번째 이유는!!
파이썬 문법을 처음 봤을 때 간단하고 읽기 쉬워서 그 부분에 매력을 느꼈고,
두 번째 이유는 요즘 파이썬이 국내나 해외에서 많이 떠오르는 언어라는 것을 들었습니다 ㅎㅎ
AI 때문인가봐요~
 
일단 뭐든 배워놓으면 쓸데는 있겠지 라는 생각으로 공부하기 시작했고, 얼마 지나지 않아서 서울시에서 하는 AI 교육을 신청했는데
코딩테스트와 면접을 거치고 2개월 간 교육을 듣게 됐습니다 🫡
굉장히 짧은 시간이었지만 그동안 배운 내용을 이 블로그에 고스란히 담을 수 있던 소중한 시간들이었습니다 🥰
 
AI 교육을 수료하고 취업준비를 시작한 지 한 달째 면접을 5군데 정도 돌아다녔는데요!!
 
보통 신입은 코딩을 할줄 안다고 해도 다시 교육을 받기 때문에 기술면접은 깊게 파고들지 않는 것 같아요. (아닐수도)
70% 이상은 인성면접이라고 보면 될 것 같아요. (회사 바이 회사)

면접 복기 했을 때, 많이 받았던 질문들을 뽑아왔습니당
 

1차 면접 (실무진 면접)

  • 보통 지원한 팀의 실무자분들이 들어와서 이 사람이 우리 팀에 들어오면 잘 섞일 수 있을지에 대해서 물어보기 때문에 성격에 대한 좋은 인상을 심어주는 것이 좋습니다!
  • 수행했던 프로젝트에 대한 질문들이 많기 때문에 프로젝트에 대한 것은 무조건 다시 복기하고 가야해요. 복기 안 하더라도 열심히 했다면 무리 없이 대답할 수 있을거에요.
  • 왜 개발자가 되려고 하는 이유 (비전공자의 경우)
  • 프로젝트 진행 했을 때 힘들었던 점과 극복한 경험
  • 프로젝트 진행 중 의견 충돌이 날 때 해결 방법
  • 내가 지원한 회사가 어떤 일을 하고 어떤 언어를 사용하는지 회사 사이트 들어가서 자세히 공부하는 것을 추천 (회사 지원동기)
  • 내가 제출한 이력서와 자기소개서 내에서 질문 (성격의 장단점, 자신의 강점)
  • 그 외의 이력서에 기재한 기술들에 대한 질문들과 아주 기본적인 지식에 대한 질문들이 있을 수 있음!

 

2차 면접 (임원 면접)

  • 만약 임원중에 CTO(최고기술경영자)가 있다면 기술 질문이 들어올 수 있습니다. 언제나 방심은 금물
  • 1차 면접에서 기술에 대한 검증은 끝났기 때문에 2차에서는 인성면접 위주로 봅니다.
  • 다른 언어에 대한 두려움이 있는지 (다른 언어를 공부해야 하는 상황이 생길 경우)
  • 5년 또는 10년 후 나의 모습
  • 어떤 개발자가 되고 싶은지
  • 살면서 힘들었던 경험
  • 본인 역량보다 높은 일을 줘서 힘들 경우 어떻게 할 것인지
  • 쉴 때 뭐하는지 (스트레스 핸들링)

 
형광펜 표시해놓은 부분은 2개 이상의 회사에서 들었던 질문이에요!
 
제 경험상 모르는 부분은 당당하게 모른다고 말하는 것이 좋은 것 같아요. 이 사람이 알고 있는지 모르고 있는지 다 티가 나기 때문에 솔직하게 말합시다 ㅎㅎ
저는 5초 생각하다가 기억이 잘 안 나면 잘 모르겠습니다. 라고 답변을 했는데 말하고 생각날 때도 많았어요.
그럴 경우에는 마지막에 이야기해도 되니 굳이 지어내지는 않았으면 좋겠습니다~
오히려 솔직하게 말하는 이런 점이 플러스요인이 될 가능성도 있어요 ㅎㅎ
 
자기소개는 지원한 직무에 맞게 준비하고, 만약 기술 블로그나 깃허브를 한다면 이력서에 첨부해놓는 게 좋겠죠~ (꾸준히 공부하고 정리해 놓는다는 증거)
 
 
 
 

반응형

'메모장' 카테고리의 다른 글

2023 정보처리기사 필기 시험 후기  (1) 2023.03.20
반응형

1번째 포스팅 참고 ☞ 신입 개발자 기술면접 준비하기 (1) - Java

 

API(Application Programming Interface) 란?

응용프로그램에서 사용할수 있도록 운영체제나 프로그래밍언어가 제공하는 기능을 제어할 수 있게 만든 인터페이스

  • API : 애플리케이션 소프트웨어를 구축하고 통합하기 위한 정의 및 프로토콜 세트로 애플리케이션 프로그래밍 인터페이스를 나타낸다.
  • 데이터와 기능의 집합을 제공하여 컴퓨터 프로그램간 상호작용을 촉진하며, 서로 정보를 교환가능 하도록 하는 것

 

API의 장점

  • API를 사용하면 구현 방식을 알지 못해도 제품 또는 서비스가 서로 커뮤니케이션할 수 있으며 애플리케이션 개발을 간소화하여 시간과 비용을 절약할 수 있습니다.
  • 새로운 툴과 제품을 설계하거나 기존 툴과 제품을 관리하는 경우 API는 유연성을 제공하고 설계, 관리, 사용 방법을 간소화하며 혁신의 기회를 제공합니다.
  • API는 리소스에 대한 액세스 권한을 제공하고 보안과 제어를 유지할 수 있게 해주며 액세스 권한을 어떻게, 누구에게 제공할지 여부만 결정하면 됨

 

REST란?

  • REST는 Representational State Transfer 의 약자로서 웹의 장점을 최대한 활용할 수 있는 아키텍처
  • 최근의 서버 프로그램은 다양한 브라우저와 안드로이드폰, 아이폰과 같은 모바일 디바이스에서도 통신을 할 수 있어야 한다.
  • REST 아키텍처는 Hypermedia API의 기본을 충실히 지키면서 범용성을 보장한다.
  • HTTP URI(Uniform Resource Identifier)를 통해 자원(Resource)을 명시하고, HTTP Method(POST, GET, PUT, DELETE)를 통해 해당 자원에 대한 CRUD Operation을 적용하는 것을 의미한다.

 

RESTful 이란?

  • RESTful은 일반적으로 REST라는 아키텍처를 구현하는 웹 서비스를 나타내기 위해 사용되는 용어이다.

 

Http 응답상태코드

  • 성공(Success)
    • 200 상태코드 : 정상적으로 수행
    • 201 상태코드 : 자원(Resource) 생성 요청. 성공적으로 수행됨
  • 클라이언트 에러(Client Error)
    • 400 상태코드 : 클라이언트 요청이 부적절할 경우 응답 코드
    • 401 상태코드 : 클라이언트가 권한이 없는 자원을 요청하였을 때 응답 코드
    • 403 상태코드 : 보호되는 자원을 요청하였을 때 응답 코드
    • 405 상태코드 : 클라이언트가 요청한 리소스에서는 사용 불가능한 Method를 이용했을 때 응답 코드
  • 기타
    • 301 상태코드 : 클라이언트가 요청한 리소스에 대한 URI가 변경되었을 때 응답코드
    • 500 상태코드 : 서버에 뭔가 문제가 있을 때 사용하는 응답 코드
  • 500 : 서버쪽 오류로 인한 상태코드

 

MVC(Model - View - Controller) 패턴이란?

  • 애플리케이션을 세가지의 역할로 구분한 개발 방법론
  • 사용자가 Controller를 조작하면 Controller는 Model을 통해서 데이터를 가져오고 그 정보를 바탕으로 시각적인 표현을 담당하는 View를 제어해서 사용자에게 전달하게 된다.
  1. 사용자가 웹 사이트에 접속한다. (User)
  2. Controller는 사용자가 요청한 웹 페이지를 서비스하기 위해서 모델을 호출한다.
  3. 모델은 데이터베이스나 파일과 같은 데이터 소스를 제어한 후에 그 결과를 리턴한다.
  4. Controller는 Model이 리턴한 결과를 View에 반영한다.
  5. 데이터가 반영된 View는 사용자에게 보여진다.

 

MVC Model-1

  • JSP로 구현한 기존 웹 어플리케이션은 모델 1 구조로 웹 브라우저의 요청을 JSP 페이지가 받아서 처리하는 구조이다.
  • JSP 페이지 안에서 모든 정보를 표현(View)하고 저장(Model)하고 처리(Control)되므로 재사용이 힘들고, 읽기도 힘들어 가독성이 떨어진다.
  • 정의 : 모든 클라이언트 요청과 응답을 JSP가 담당하는 구조
  • 장점 : 단순한 페이지 작성으로 쉽게 구현이 가능하다. 중소형 프로젝트에 적합
  • 단점 : 웹 어플리케이션이 복잡해지면 유지보수 문제가 발생된다.

MVC Model-2

  • MVC1 구조와 달리 웹 브라우저의 요청을 하나의 서블릿이 받게 됨
  • 서블릿은 웹 브라우저의 요청을 알맞게 처리한 후 그 결과를 JSP 페이지로 포워딩
  • 정의 : 클라이언트의 요청처리와 응답처리, 비지니스 로직 처리하는 부분을 모듈화시킨 구조
  • 장점 : 처리작업의 분리로 인해 유지보수와 확장이 용이하다.
  • 단점 : 구조 설계를 위한 시간이 많이 소요되므로 개발 기간이 증가한다.

 

Spring MVC 프레임워크

  • 스프링이 제공하는 트랜젝션 처리, DI, AOP를 손쉽게 사용
  • 스트럿츠2와 같은 프레임워크와 연동이 쉬움

Spring MVC 주요 구성요소 및 처리 흐름

  • 다른 mvc 프레임워크와 마찬가지로 컨트롤러를 사용하여 요청을 처리
  • 스프링에서는 DispatcherServlet이 MVC에서의 컨트롤러(Controlle)부분을 처리

DispatcherServlet의 역할

  • 클라이언트의 요청을 전달받아 요청에 맞는 컨트롤러가 리턴한 결과값을 View에 전달하여 알맞은 응답을 생성

HandlerMapping의 역할

  • 클라이언트의 요청 URL을 어떤 컨트롤러가 처리할지 결정

Controller의 역할

  • 클라이언트의 요청을 처리한 뒤 결과를 DispatcherServlet에게 리턴

ModelAndView의 역할

  • 컨트롤러가 처리한 결과 정보를 뷰 선택에 필요한 정보를 담음

ViewResolver의 역할

  • 컨트롤러의 처리 결과를 생성할 뷰를 결정

View의 역할

  • 컨트롤러의 처리 결과 화면을 생성, JSP 또는 Velocity 템플릿 파일 등을 뷰로 사용

 

Spring MVC 개발

  • 클라이언트에 요청을 받을 DispatcherServlet을 web.xml 파일에 설정
  • 클라이언트의 요청을 처리할 컨트롤러 작성
  • ViewResolver 설정(컨트롤러가 전달한 값을 이용해서 응답 화면을 생성할 뷰를 결정)
  • JSP나 Velocity 등을 이용하여 뷰영역의 코드를 작성

 

RIA(Rich Internet Application)

  • 일반 데스크톱 애플리케이션과 같이 풍부한 유저 인터페이스를 제공하고, 다이나믹하며 모든 처리 과정을 새로고침 없이 할 수 있도록 지원해주는 웹 애플리케이션

 

AJAX(Asynchronous JavaScript and XML) 특징

  • 플러그인을 사용하지 않고 브라우저만으로 이용 가능
  • 페이지 이동없이 어떤 문서를 요청하고 응답된 결과를 가져다가 동적 처리 할 수 있도록 하는 JavaScript 라이브러리
  • 웹 서버에서 수신한 HTML 및 XML 데이터를 처리하는 데는 DOM을 사용

장점

  • 접근이 용이하며, 페이지 이동없이 고속으로 화면전환 가능
  • 비동기 통신 가능
  • 수신 데이터량을 축소할수 있으며, 웹 클라이언트에게 처리를 위임 가능
  • 화려한 유저 인터페이스 제공 등
  • 다양한 오픈 소스 프레임워크(Prototype, Dojo, jQuery, Google Web Toolkit 등) 제공

단점

  • 브라우저 호환성에 자유롭지 못하다
  • JavaScript는 유지보수 및 디버깅이 어렵다
  • Ajax가 포함된 HTML 문서를 제공한 웹 서버가 아닌 다른 웹 서버로 요청을 보낼 수 없고, 클라이언트 PC의 파일에 접근할 수 없다.

 

Ajax 기반 기술들

  • XMLHttpRequest : 웹 브라우저와 웹 서버간 비동기 통신을 위한 JavaScript 객체
  • DOM(Document Object Model) : 마크업 문서의 특정 노드를 객체 단위로 조작할 수 있는 일관된 방법 제공
  • JSON(JavaScript Object Notation) : 구조화된 텍스트 데이터의 교환을 위한 자바스크립트 표현식
  • XSL : XML 문서를 XML 또는 HTML 문서로 변환하기 위한 언어

 

XML(Extensible Markup Language)

  • HTML은 고정된 태그 집합이고, 디스플레이 기능에 치중ㅎ 다양한 비즈니스 데이터 표현 불가능하여 한계가 있음
  • 인터넷 환경에서 구조화된 문서를 전송 가능하도록 설계된 표준 마크업 언어
  • SGML의 서브셋 형태로 SGML과 HTML의 장점을 수용하여 만들어진 언어

XML 장점

  • 호환성
  • 독립성
  • 확장성
  • 다양한 포맷으로 변경 가능
  • 검색 능력의 향상

 

DOM

  • 파서가 문서 전체 또는 일부를 읽어서 메모리에 객체의 트리를 구성해서 xml 어플리케이션에 제공
  • SAX에 비해 읽기 성능은 낮지만 Random Access 및 쓰기 기능이 제공됨
  • 표준 인터페이스를 구현한 객체 기반 접근
반응형

+ Recent posts