>JAVA로 HTTP 웹 서버를 구현해본다.

먼저 JAVA의 쓰레드, 스트림에 대한 이해가 필요하다.

ServerSocket 클래스가 요청에 클라이언트와 연결을 담당한다.

요청이 오면 쓰레드를 실행 시킨다. (여러 요청에 대한 응답을 하기 위해)

요청이 오면 HTTP 메시지에는

POST /user/create HTTP/1.1 -> request line

이 오고 여기서 url을 파싱한다.

그 밑에 HOST와 기타정보들이 들어있다. -> request header

그리고 빈공백 라인 뒤에

userId=inee -> request body

응답메시지에는 한가지만 다르다 request line이 아니라 status line !

브라우저는 index.html받아도 js,css,image등 태그가 있으면 계속 요청하게 되어있다.

POST방식으로 헤더에 content-length 가 표시된다.

html은 get과 post만 지원한다. ( form태그만 get,post 지원 )

AJAX정도 지원해야 PUT, DELETE 쓸 수 있다.

get, post만 쓴다면 get은 읽기용 , post는 변경작업 이라두고 추후 put, delete등으로 세분화 할 수 있다.

많은 프레임워크에서 리다이렉트 302상태코드에 대응하고 있다.

2.x 성공

3.x 리다이렉션

4.x 클라이언트 문제

5.x 서버 오류

웹서버에서 응답헤더에 set-cookie 설정을 하면 브라우저는 쿠키를 가지고 있게 된다. 그러다 다시 웹서버에 요청하게 되면 그 cookie를 요청때 다시 보내준다.

웹서버에서 content-type을 css도 지원해야 브라우저가 css를 받아 표현 할 수 있다.

>리펙토링 해보자.

테스트코드 기반으로 개발하면

  1. 클래스의 버그를 빨리 찾을 수 있다.

  2. 디버깅하기가 쉽다.

  3. 마음 놓고 리펙토링 할 수 있다. 보통 테스트하는데 시간을 많이 소요하는데 프로덕션 코드 수정해도 테스트코드가 있으면 금방 테스트 가능하다.

로직의 복잡도가 높아 추가적인 테스트가 필요하는 메소드가 private이면?!

  1. defalut접근제어자로 수정하고 메소드 처리 결과를 반환하도록 수정해 테스트 할 수 있다.

  2. 메소드 구현 로직을 새로운 클래스로 분리한다.

객체지향 설계 연습할때 요구사항 명확한 체스게임, 지뢰찾기 게임등으로 연습 필요.

OCP - 변화는 최소화 하면서 기능 확장에 유용해야된다.

분기로 복잡도가 높으면 메소드들도 추출해보자.

그리고 나서 메소드들이 혹시 원형이 같다면 인터페이스로 분리 해보자.

인터페이스로 분리하고 나니 새로운 기능 추가될때 인터페이스와 매핑만 추가하면 된다.

여기서 더 추가해서 인터페이스 <- 추상클래스 로 상속구조를 만들어 추상클래스에 get/post에 따라 추상메소드를 만들면 더욱 세분화 할 수 있다.

서블릿이 구현한 웹서버의 Controller, HttpRequest, HttpResponse를 추상화해 인터페이스로 정의해 놓은 표준.

서블릿 컨테이너(톰캣,Jetty,JBoss)가 서블릿에 대한 구현을 한 것이다.

서버가 시작 될 때 서블릿 인스턴스를 생성해, 요청 URL과 서블릿 인스턴스를 연결한다.

>지금까지 개발한 웹서버에는 문제점이 있다.

HTTP 요청과 응답 헤더, 본문 처리와 같은 데 시간을 투자함으로써 비지니스 로직에 투자할 시간이 없고 동적 HTML 만드는게 한계가 있고 데이타가 영구적이지 않다.

따라서 서블릿컨테이너, 서블릿/JSP를 활용해서 문제를 해결해보자.

embedded tomcat 다운 받아서 lib폴더에 jar파일들 의존 시키면 된다.

java소스에서 Tomcat을 생성해서 실행 시키면 톰캣이 실행된다. ( 마치 webserver 역할과 같다. )

그리고 Servlet 클래스 상속받아서 구현하면 된다. ( Controller 역할과 비슷하다. )

Servlet구현클래스 파일은 webapp/WEB-INF/classes 밑에 있어야 된다는 스펙이 있다. (path 설정 바꿔주면 된다. )

서블릿 컨테이너는 @WebServlet 어노테이션으로 요청 URL과 서블릿을 연결하는 Map을 생성한다.

변경된 자바는 톰캣을 재시작 해야 재컴파일해서 정상 작동 된다.

서블릿 컨테이너의 중요한 역할 중의 하나는 서블릿 클래스의 인스턴스 생성,요청 URL과 서블릿 인스턴스 매핑, 클라이언트 요청에 해당하는 서블릿 찾아 서블릿에 작업을 위임하는 역할이다.

그리고 서블릿에 대한 생명주기 관리를 한다.

이 점은 EJB컨테이너와 스프링컨테이너와도 비교된다.

EJB컨테이너는 EJB의 생명주기를 관리하고 스프링은 빈의 생명주기를 관리한다.

서블릿 컨테이너는 멀티스레드로 동작한다.

즉, 접속자마다 각자 스레드를 돌린다.

RequestMapping은 static으로 한번 초기화되면 쭉 재사용된다.

따라서 각자 스레드를 가지지만 같은 서블릿 인스턴스를 사용할 수 있다.

이점은 문제가 발생 할 수 있기에 방어를 잘 해야한다.

results matching ""

    No results matching ""