순수 자바코드로 HttpServer 만들기 - 29

순수 자바코드로 HttpServer 만들기

1. 시나리오 코드

package ch01;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

public class SimpleHttpServer {

	public static void main(String[] args) {
		// 8080 <- https, 80 <-- http (포트번호 생략 가능하다)
		try {
			// 포트 번호 8080으로 HTTP 서버 생성
			HttpServer httpServer = HttpServer.create(new InetSocketAddress(8080), 0);

			// 서버에대한 설정

			// 프로토콜 정의(경로, 핸들러 처리)
			// 핸들러 처리를 내부 정적 클래스로 사용
			httpServer.createContext("/test", new MyTestHandler());
			httpServer.createContext("/hello", new HelloHandler());

			// 서버 시작
			httpServer.start();
			System.out.println(">> My Http Server started on port 8080");

		} catch (IOException e) {
			e.printStackTrace();
		}
	} // end of main

	// http://localhost:8080/test <- 주소 설계
	static class MyTestHandler implements HttpHandler {

		@Override
		public void handle(HttpExchange exchange) throws IOException {

			// 사용자의 요청 방식(METHOD), GET, POST 알아야 우리가 동작 시킬 수 있다.
			String method = exchange.getRequestMethod();
			System.out.println("method : " + method);

			if ("GET".equalsIgnoreCase(method)) {
				// GET 요청시 여기서 동작
				// System.out.println("여기는 GET 방식으로 호출됨");

				// path: /test 라고 들어오면 어떤 응답처리를 내려 주면된다.
				handleGetRequest(exchange);
			} else if ("POST".equalsIgnoreCase(method)) {
				// POST 요청시 여기서 동작
				// System.out.println("여기는 POST 방식으로 호출됨");
				handlePostRequest(exchange);
			} else {
				// 지원하지 않는 메서드에 대한 응답
				String response = "Unsupported Method : " + method;
				exchange.sendResponseHeaders(405, response.length()); // Method Not Allowed
				OutputStream os = exchange.getResponseBody();
				os.write(response.getBytes());
				os.flush();
				os.close();
			}

		}

		// GET 요청시 동작 만들기
		private void handleGetRequest(HttpExchange exchange) throws IOException {
			String response = """
					<!DOCTYPE html>
					<html lang=ko>
						<head></head>
						<body>
							<h1 style="background-color:red"> Hello path by /test </h1>
						</body>
					</html>
				""";
			// String response = "hello GET ~~~~~"; // 응답 메세지

			exchange.sendResponseHeaders(200, response.length());
			OutputStream os = exchange.getResponseBody();
			os.write(response.getBytes());
			os.close();
		}

		// POST 요청시 동작 만들기
		private void handlePostRequest(HttpExchange exchange) throws IOException {
			// POST 요청은 HTTP 메세지에 바디 영역이 존재한다.
			String response = """
						<!DOCTYPE html>
						<html lang=ko>
							<head></head>
							<body>
								<h1 style="background-color:red"> Hello path by /test </h1>
							</body>
						</html>
					""";
			// HTTP 응답 메시지 헤더 설정
			exchange.setAttribute("Content-Type", "text/html; charset=UTF-8");
			exchange.sendResponseHeaders(200, response.length());
			
			// getResponseBody
			OutputStream os = (exchange.getResponseBody());
			os.write(response.getBytes());
			os.close();
		}

	} // end of MyTestHandler

	static class HelloHandler implements HttpHandler {

		@Override
		public void handle(HttpExchange exchange) throws IOException {
			String method = exchange.getRequestMethod();
			System.out.println(" hello method : " + method);
		}

	}
}

2. 도전 과제

도전과제 1단계

HTTP 서버에서 바이트 기반 스트림에서 문자 기반 스트림으로 변경해서 HTTP 응답 메세지를 내려라

private void handleGetRequest(HttpExchange exchange) throws IOException {
    String response = """
            <!DOCTYPE html>
            <html lang=ko>
                <head></head>
                <body>
                    <h1 style="background-color:red"> Hello path by /test </h1>
                </body>
            </html>
        """;
    byte[] str = response.getBytes();
    exchange.sendResponseHeaders(200, response.length());
    OutputStream os = exchange.getResponseBody();
    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os));
    writer.write(response);
    writer.close();
}

도전과제 2단계(프로토콜 직접 설계)

순수 자바 코드로 HTTP Client 측 코드 작성 순수 자바 코드로 HTTP 서버측 코드 작성 테스트 처리하라

public class HttpGetClient2 {

	public static void main(String[] args) {
		
		// 자바 기본 코드로 HTTP 요청을 만들어 보자
		
		// HTTP 통신 하기 위한 준비물
		// 서버 주소(경로준비)
		String urlString = "http://localhost:8080/test";
		
		// 1. URL 클래스를 만들어 준다.
		// 2. Connection 객체를 만들어 준다. (URL --> 멤버로 Connection 객체를 뽑을 수 있다.)
		try {
			URL url = new URL(urlString);
			HttpURLConnection conn = (HttpURLConnection)url.openConnection();
			BufferedReader buIn = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String inputLine;
			while ((inputLine = buIn.readLine()) != null) {
				System.out.println(inputLine);
			}
			buIn.close();
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}

}

결과

<서버측>

>> My Http Server started on port 8080
method : GET

<클라이언트측>

	<!DOCTYPE html>
	<html lang=ko>
		<head></head>
		<body>
			<h1 style="background-color:red"> Hello path by /test </h1>
		</body>
	</html>

Java 유용한 클래스 - 3 으로 돌아가기