HttpHelloWorldServer.java
package org.jboss.netty.example.http.helloworld;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
/**
* An HTTP server that sends back the content of the received HTTP request
* in a pretty plaintext form.
*/
public class HttpHelloWorldServer {
private final int port;
public HttpHelloWorldServer(int port) {
this.port = port;
}
public void run() {
// Configure the server.
ServerBootstrap bootstrap = new ServerBootstrap(
new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));
// Enable TCP_NODELAY to handle pipelined requests without latency.
bootstrap.setOption("child.tcpNoDelay", true);
// Set up the event pipeline factory.
bootstrap.setPipelineFactory(new HttpHelloWorldServerPipelineFactory());
// Bind and start to accept incoming connections.
bootstrap.bind(new InetSocketAddress(port));
}
public static void main(String[] args) {
int port;
if (args.length > 0) {
port = Integer.parseInt(args[0]);
} else {
port = 8080;
}
new HttpHelloWorldServer(port).run();
}
}
HttpHelloWorldServerPipelineFactory.java
package org.jboss.netty.example.http.helloworld;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.handler.codec.http.HttpContentCompressor;
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
import static org.jboss.netty.channel.Channels.*;
public class HttpHelloWorldServerPipelineFactory implements ChannelPipelineFactory {
public ChannelPipeline getPipeline() throws Exception {
// Create a default pipeline implementation.
ChannelPipeline pipeline = pipeline();
// Uncomment the following line if you want HTTPS
//SSLEngine engine = SecureChatSslContextFactory.getServerContext().createSSLEngine();
//engine.setUseClientMode(false);
//pipeline.addLast("ssl", new SslHandler(engine));
pipeline.addLast("decoder", new HttpRequestDecoder());
// Uncomment the following line if you don't want to handle HttpChunks.
//pipeline.addLast("aggregator", new HttpChunkAggregator(1048576));
pipeline.addLast("encoder", new HttpResponseEncoder());
// Remove the following line if you don't want automatic content compression.
pipeline.addLast("deflater", new HttpContentCompressor());
pipeline.addLast("handler", new HttpHelloWorldServerHandler());
return pipeline;
}
}
HttpHelloWorldServerHandler.java
package org.jboss.netty.example.http.helloworld;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponse;
import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.*;
import static org.jboss.netty.handler.codec.http.HttpHeaders.*;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.*;
import static org.jboss.netty.handler.codec.http.HttpVersion.*;
public class HttpHelloWorldServerHandler extends SimpleChannelUpstreamHandler {
private static final byte[] CONTENT = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' };
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
Object msg = e.getMessage();
Channel ch = e.getChannel();
if (msg instanceof HttpRequest) {
HttpRequest req = (HttpRequest) msg;
if (is100ContinueExpected(req)) {
Channels.write(ctx, Channels.future(ch), new DefaultHttpResponse(HTTP_1_1, CONTINUE));
}
boolean keepAlive = isKeepAlive(req);
HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
response.setContent(ChannelBuffers.wrappedBuffer(CONTENT));
response.headers().set(CONTENT_TYPE, "text/plain");
response.headers().set(CONTENT_LENGTH, response.getContent().readableBytes());
if (!keepAlive) {
ChannelFuture f = Channels.future(ch);
f.addListener(ChannelFutureListener.CLOSE);
Channels.write(ctx, f, response);
} else {
response.headers().set(CONNECTION, Values.KEEP_ALIVE);
Channels.write(ctx, Channels.future(ch), response);
}
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
throws Exception {
e.getCause().printStackTrace();
e.getChannel().close();
}
}
运行HttpHelloWorldServer,用浏览器访问127.0.0.1:8080
Hello World
pipeline
DefaultChannelPipeline{
(decoder = org.jboss.netty.handler.codec.http.HttpRequestDecoder),
(encoder = org.jboss.netty.handler.codec.http.HttpResponseEncoder),
(deflater = org.jboss.netty.handler.codec.http.HttpContentCompressor),
(handler = org.jboss.netty.example.http.helloworld.HttpHelloWorldServerHandler)
}
http request
DefaultHttpRequest(chunked: false)
GET / HTTP/1.1
Host: 127.0.0.1:8080
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:26.0) Gecko/20100101 Firefox/26.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
http response
DefaultHttpResponse(chunked: false)
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 11
Connection: keep-alive