[java] 자바 네티 (Java Netty)를 사용하여 HTTP 통신을 구현하는 방법은?

네티 (Netty)는 자바 기반의 고성능 네트워크 애플리케이션 프레임워크로, 다양한 프로토콜을 간단하게 처리할 수 있습니다. HTTP 프로토콜을 사용하여 통신하는 애플리케이션을 구현하기 위해서는 네티 (Netty)를 활용할 수 있습니다. 이번 글에서는 자바 네티 (Java Netty)를 사용하여 HTTP 통신을 구현하는 방법을 알아보겠습니다.

1. 프로젝트 설정

먼저, Maven 을 사용하여 네티 (Netty)를 프로젝트에 추가합니다. pom.xml 파일에 다음 종속성을 추가합니다:

<dependencies>
    <dependency>
        <groupId>io.netty</groupId>
        <artifactId>netty-all</artifactId>
        <version>4.1.63.Final</version>
    </dependency>
</dependencies>

2. HTTP 서버 구성

다음으로, HTTP 서버를 구성해보겠습니다. HttpServer 클래스를 생성하고, 다음 코드를 추가합니다:

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpServerCodec;

public class HttpServer {
    public static void main(String[] args) throws InterruptedException {
        EventLoopGroup bossGroup = new NioEventLoopGroup(1);
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap serverBootstrap = new ServerBootstrap();
            serverBootstrap.group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<>() {
                    protected void initChannel(Channel ch) throws Exception {
                        ch.pipeline().addLast(new HttpServerCodec());
                    }
                });

            serverBootstrap.bind(8080).sync()
                .channel().closeFuture().sync();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}

위 코드에서 8080 포트로 서버를 바인딩하고, HttpServerCodec 핸들러를 사용하여 HTTP 요청 및 응답을 처리합니다.

3. 요청 및 응답 처리

HTTP 요청을 처리하기 위해 ChannelInboundHandler를 상속받은 핸들러 클래스를 구현합니다. 예를 들어, HttpRequestHandler 클래스를 생성하고, 다음 코드를 추가합니다:

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpVersion;

public class HttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
        if (request.method() == HttpMethod.GET) {
            // GET 요청 처리
            String responseMessage = "Hello, Netty!";
            ByteBuf responseContent = ctx.alloc().buffer();
            responseContent.writeBytes(responseMessage.getBytes());

            HttpResponse response = new DefaultFullHttpResponse(
                HttpVersion.HTTP_1_1, HttpResponseStatus.OK, responseContent);
            response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain");
            response.headers().set(HttpHeaderNames.CONTENT_LENGTH, responseContent.readableBytes());

            ctx.write(response);
        } else {
            // 지원하지 않는 HTTP 메소드 에러 응답
            HttpResponse response = new DefaultHttpResponse(
                request.protocolVersion(), HttpResponseStatus.METHOD_NOT_ALLOWED);
            ctx.write(response);
        }

        ctx.flush();
    }
}

위 코드는 channelRead0 메소드에서 수신된 FullHttpRequest 객체를 처리합니다. GET 요청일 경우 “Hello, Netty!”라는 메시지를 담은 HTTP 응답을 생성하고, 그 외의 메소드일 경우 “지원하지 않는 HTTP 메소드”라는 응답을 생성합니다.

4. 핸들러 등록

마지막으로, 앞에서 작성한 HttpRequestHandler를 서버 부트스트랩에 등록해야 합니다. 이를 위해 HttpServer 클래스의 ChannelInitializer에서 핸들러를 추가하도록 코드를 수정합니다:

serverBootstrap.group(bossGroup, workerGroup)
    .channel(NioServerSocketChannel.class)
    .childHandler(new ChannelInitializer<>() {
        protected void initChannel(Channel ch) throws Exception {
            ch.pipeline().addLast(new HttpServerCodec());
            ch.pipeline().addLast(new HttpRequestHandler());
        }
    });

이제 HTTP 서버를 실행하고, 브라우저에서 http://localhost:8080 으로 접속해보면 “Hello, Netty!”라는 응답을 확인할 수 있을 것입니다.

결론

자바 네티 (Java Netty)를 사용하여 HTTP 통신을 구현하는 방법에 대해 알아보았습니다. 네티 (Netty)를 사용하면 간단하고 효율적으로 네트워크 애플리케이션을 개발할 수 있습니다. 이를 통해 웹 서버, 클라이언트, 프록시 등 다양한 네트워크 애플리케이션을 구현할 수 있습니다.

참고 자료