본문 바로가기
Java

[JAVA] HTTP로 이미지 업로드 및 다운로드 하기

by teamnova 2023. 11. 13.

오늘은 HTTP로 이미지 업로드 및 다운로드 하기를 진행해보겠습니다. 

 

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
import java.nio.file.Paths;

public class SimpleHttpClient {
    // 클라이언트에서 이미지를 업로드하기 위한 경로
    // Mac OS 기준입니다. 자신의 OS에 맞게 절대 경로를 수정해주세요.
    static String clientUploadServerPath = "/Users/컴퓨터이름/Downloads/client-upload-server";

    // 클라이언트에서 다운로드받은 이미지를 저장할 경로
    // Mac OS 기준입니다. 자신의 OS에 맞게 절대 경로를 수정해주세요.
    static String clientDownloadBoxPath = "/Users/컴퓨터이름/Downloads/client-download-box";

    public static void main(String[] args) throws Exception {
        HttpClient client = HttpClient.newHttpClient();

        // 간단한 GET 요청 보내기
        System.out.println("Sending GET request...");
        sendGetRequest(client);

        // 간단한 POST 요청 보내기
        System.out.println("Sending POST request...");
        sendPostRequest(client);

        // 이미지 업로드 요청
        System.out.println("Uploading image...");
        uploadImage(client, Paths.get(clientUploadServerPath + "/0000-to-upload.png"));

        // 이미지 다운로드 요청
        System.out.println("Downloading image...");
        downloadImage(client, "uploaded.jpeg", Paths.get(clientDownloadBoxPath + "/uploaded.jpeg"));
    }

    private static void sendGetRequest(HttpClient client) throws Exception {
        HttpRequest getRequest = HttpRequest.newBuilder()
                .uri(new URI("http://localhost:8000/test"))
                .GET()
                .build();

        // GET 요청 응답 처리
        HttpResponse<String> getResponse = client.send(getRequest, HttpResponse.BodyHandlers.ofString());
        System.out.println("GET Response: " + getResponse.body());
    }

    private static void sendPostRequest(HttpClient client) throws Exception {
        String postData = "This is a POST request body";

        HttpRequest postRequest = HttpRequest.newBuilder()
                .uri(new URI("http://localhost:8000/test"))
                .POST(HttpRequest.BodyPublishers.ofString(postData))
                .build();

        // POST 요청 응답 처리
        HttpResponse<String> postResponse = client.send(postRequest, HttpResponse.BodyHandlers.ofString());
        System.out.println("POST Response: " + postResponse.body());
    }

    private static void uploadImage(HttpClient client, Path imagePath) throws Exception {
        HttpRequest postRequest = HttpRequest.newBuilder()
                .uri(new URI("http://localhost:8000/test/upload"))
                .POST(HttpRequest.BodyPublishers.ofFile(imagePath))
                .header("Content-Type", "image/jpeg") // 확장자에 따라 변경 필요
                .build();

        // 이미지 업로드 응답 처리
        HttpResponse<String> postResponse = client.send(postRequest, HttpResponse.BodyHandlers.ofString());
        System.out.println("Upload Response: " + postResponse.body());
    }

    private static void downloadImage(HttpClient client, String filenameClientWant, Path savePath) throws Exception {
        HttpRequest getRequest = HttpRequest.newBuilder()
                .uri(new URI("http://localhost:8000/test/download/" + filenameClientWant))
                .GET()
                .build();

        // 이미지 다운로드 응답 처리
        HttpResponse<Path> getResponse = client.send(getRequest, HttpResponse.BodyHandlers.ofFile(savePath));
        System.out.println("Image saved to: " + getResponse.body());
    }
}
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.logging.Logger;

public class SimpleHttpServer {
    private static final Logger logger = Logger.getLogger(SimpleHttpServer.class.getName());
    // 이미지 저장을 위한 서버 디렉토리 경로
    // Mac OS 기준입니다. 자신의 OS에 맞게 절대 경로를 수정해주세요.
    private static final String IMAGE_DIRECTORY = "/Users/컴퓨터이름/Downloads/server-image-box";

    public static void main(String[] args) throws Exception {
        // 8000 포트에서 서버 초기화
        HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
        // URL 경로별 처리
        server.createContext("/test", new TestHandler());
        server.createContext("/", new ErrorHandler());
        server.setExecutor(null);
        // 서버 시작 메시지 로깅
        logger.info("Server started at port 8000.");
        // 서버 시작
        server.start();
    }

    static class TestHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange exchange) throws IOException {
            // 받은 요청 로깅
            logger.info("Received request: " + exchange.getRequestMethod() + " " + exchange.getRequestURI());

            String requestPath = exchange.getRequestURI().toString();

            if ("GET".equals(exchange.getRequestMethod())) {
                if (requestPath.startsWith("/test/download/")) {
                    // 이미지 다운로드 처리
                    handleImageDownload(exchange, requestPath);
                } else {
                    // 일반 GET 요청 처리
                    handleGetRequest(exchange);
                }
            } else if ("POST".equals(exchange.getRequestMethod()) && requestPath.equals("/test/upload")) {
                // 이미지 업로드 처리
                handleImageUpload(exchange);
            } else {
                // 지원하지 않는 메소드에 대한 경고 로깅
                logger.warning("Unsupported request method: " + exchange.getRequestMethod());
                exchange.sendResponseHeaders(405, -1); // 405 Method Not Allowed
            }
        }

        private void handleGetRequest(HttpExchange exchange) throws IOException {
            // 간단한 텍스트 응답 처리
            String response = "Hello, HTTP!";
            exchange.sendResponseHeaders(200, response.length());
            OutputStream os = exchange.getResponseBody();
            os.write(response.getBytes());
            os.close();
        }

        private void handleImageDownload(HttpExchange exchange, String requestPath) throws IOException {
            // 요청받은 파일명 추출
            String filename = requestPath.replace("/test/download/", "");
            Path imagePath = Paths.get(IMAGE_DIRECTORY, filename);

            if (!Files.exists(imagePath)) {
                // 파일이 없을 경우 404 응답
                String response = "File not found!";
                exchange.sendResponseHeaders(404, response.length());
                OutputStream os = exchange.getResponseBody();
                os.write(response.getBytes());
                os.close();
                return;
            }

            // 이미지 파일 응답 처리
            byte[] imageBytes = Files.readAllBytes(imagePath);
            exchange.sendResponseHeaders(200, imageBytes.length);
            OutputStream os = exchange.getResponseBody();
            os.write(imageBytes);
            os.close();
        }

        private void handleImageUpload(HttpExchange exchange) throws IOException {
            // 업로드된 이미지의 Content-Type 추출
            String contentType = exchange.getRequestHeaders().getFirst("Content-Type");
            String fileExtension = contentType.split("/")[1];

            // 이미지 저장 경로 설정
            Path savePath = Paths.get(IMAGE_DIRECTORY, "uploaded." + fileExtension);
            // 이미지 저장
            Files.write(savePath, exchange.getRequestBody().readAllBytes());

            // 업로드 성공 응답 처리
            String response = "Image uploaded successfully!";
            exchange.sendResponseHeaders(200, response.length());
            OutputStream os = exchange.getResponseBody();
            os.write(response.getBytes());
            os.close();
        }
    }

    static class ErrorHandler implements HttpHandler {
        @Override
        public void handle(HttpExchange exchange) throws IOException {
            // 유효하지 않은 요청 경로에 대한 경고 로깅
            logger.warning("Invalid request path: " + exchange.getRequestURI());

            // 404 에러 응답 처리
            String errorResponse = "404 Error: Invalid path!";
            exchange.sendResponseHeaders(404, errorResponse.length());
            OutputStream os = exchange.getResponseBody();
            os.write(errorResponse.getBytes());
            os.close();
        }
    }
}