基于阻塞式IO建立的Http Server
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLServerSocketFactory;
import org.apache.http.HttpConnectionFactory;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpServerConnection;
import org.apache.http.HttpStatus;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.DefaultBHttpServerConnection;
import org.apache.http.impl.DefaultBHttpServerConnectionFactory;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpProcessor;
import org.apache.http.protocol.HttpProcessorBuilder;
import org.apache.http.protocol.HttpRequestHandler;
import org.apache.http.protocol.HttpService;
import org.apache.http.protocol.ResponseConnControl;
import org.apache.http.protocol.ResponseContent;
import org.apache.http.protocol.ResponseDate;
import org.apache.http.protocol.ResponseServer;
import org.apache.http.protocol.UriHttpRequestHandlerMapper;
public class Main {
static final int port = 8080;
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread() {//注册钩子监听
public void run() {
System.out.println("nothing is should be saved before jvm shutdown");
}
});
try {
new Main().start( port);
} catch (Exception e) {
System.exit(1);
}
}
void start(int port) throws IOException{
HttpProcessorBuilder builder = HttpProcessorBuilder.create();
builder.add(new ResponseDate());
builder.add(new ResponseServer());
builder.add(new ResponseContent());
builder.add(new ResponseConnControl());
HttpProcessor httpPro = builder.build();
UriHttpRequestHandlerMapper reqistry = new UriHttpRequestHandlerMapper();
reqistry.register("*", new BussinessHandlder());//注册业务处理类
HttpService service = new HttpService(httpPro, reqistry);
SSLServerSocketFactory factory = null;
if (port == 8443) {// 处理SSL连接
try {
ClassLoader cl = Main.class.getClassLoader();
URL url = cl.getResource("my.keystore");
if (url == null) {
throw new FileNotFoundException("keystore not found !");
}
KeyStore keystore = KeyStore.getInstance("jks");
keystore.load(url.openStream(), "secret".toCharArray());
KeyManagerFactory kmfactory = KeyManagerFactory
.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmfactory.init(keystore, "secret".toCharArray());
KeyManager[] keymanagers = kmfactory.getKeyManagers();
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(keymanagers, null, null);
factory = sslcontext.getServerSocketFactory();
} catch (UnrecoverableKeyException | KeyManagementException
| KeyStoreException | NoSuchAlgorithmException
| CertificateException | IOException e) {
factory = null;
}
}
//启动数据接收监听
new RequestListener(port,service,factory).start();
}
static class BussinessHandlder implements HttpRequestHandler{
@Override
public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException {
System.out.println(Thread.currentThread().getName()+":"+request.getRequestLine().getMethod());
response.setStatusCode(HttpStatus.SC_OK);
StringEntity entity = new StringEntity( "<html><body>"+new Random().nextDouble()+"</body></html>", ContentType.create("text/html", "UTF-8"));
response.setEntity(entity);
}
}
static class RequestListener extends Thread{
private static final ExecutorService executors = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*2);
private final HttpConnectionFactory<DefaultBHttpServerConnection> connFactory;
private final ServerSocket socket;
private final HttpService service;
public RequestListener(final int port,final HttpService service, final SSLServerSocketFactory factory) throws IOException {
this.connFactory = DefaultBHttpServerConnectionFactory.INSTANCE;
this.socket = (factory!=null?factory.createServerSocket(port):new ServerSocket(port));
this.service = service;
}
@Override
public void run() {
while(!Thread.interrupted()){
try {
Socket socket = this.socket.accept();
HttpServerConnection conn = this.connFactory.createConnection(socket);
Thread worker = new WorkerThread(this.service,conn);
worker.setDaemon(true);
executors.execute(worker);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
static class WorkerThread extends Thread{
private final HttpService service;
private final HttpServerConnection conn;
public WorkerThread(HttpService service, HttpServerConnection conn) {
this.service = service;
this.conn = conn;
}
@Override
public void run() {
HttpContext context = new BasicHttpContext();
try {
while (!Thread.interrupted() && conn.isOpen()) {
this.service.handleRequest(this.conn, context);
}
} catch (IOException | HttpException e) {
e.printStackTrace();
}finally{
try {
this.conn.shutdown();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
下面是基于httpCore NIO 建立的非阻塞式的异步http server
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.Random;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.nio.DefaultHttpServerIODispatch;
import org.apache.http.impl.nio.DefaultNHttpServerConnection;
import org.apache.http.impl.nio.DefaultNHttpServerConnectionFactory;
import org.apache.http.impl.nio.SSLNHttpServerConnectionFactory;
import org.apache.http.impl.nio.reactor.DefaultListeningIOReactor;
import org.apache.http.impl.nio.reactor.IOReactorConfig;
import org.apache.http.nio.NHttpConnectionFactory;
import org.apache.http.nio.entity.NStringEntity;
import org.apache.http.nio.protocol.BasicAsyncRequestConsumer;
import org.apache.http.nio.protocol.BasicAsyncResponseProducer;
import org.apache.http.nio.protocol.HttpAsyncExchange;
import org.apache.http.nio.protocol.HttpAsyncRequestConsumer;
import org.apache.http.nio.protocol.HttpAsyncRequestHandler;
import org.apache.http.nio.protocol.HttpAsyncService;
import org.apache.http.nio.protocol.UriHttpAsyncRequestHandlerMapper;
import org.apache.http.nio.reactor.IOEventDispatch;
import org.apache.http.nio.reactor.ListeningIOReactor;
import org.apache.http.protocol.HttpContext;
import org.apache.http.protocol.HttpProcessor;
import org.apache.http.protocol.HttpProcessorBuilder;
import org.apache.http.protocol.ResponseConnControl;
import org.apache.http.protocol.ResponseContent;
import org.apache.http.protocol.ResponseDate;
import org.apache.http.protocol.ResponseServer;
public class Main {
static int port = 8080;
static String hostname = "127.0.0.1";
public static void main(String[] args) {
Runtime.getRuntime().addShutdownHook(new Thread() {//注册钩子监听
public void run() {
System.out.println("nothing is should be saved before jvm shutdown");
}
});
try {
new Main().start( );
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
void start() throws IOException{
HttpProcessorBuilder builder = HttpProcessorBuilder.create();
builder.add(new ResponseDate());
builder.add(new ResponseServer());
builder.add(new ResponseContent());
builder.add(new ResponseConnControl());
HttpProcessor httpPro = builder.build();
UriHttpAsyncRequestHandlerMapper reqistry = new UriHttpAsyncRequestHandlerMapper();
reqistry.register("*", new BussinessHandlder());
HttpAsyncService service = new HttpAsyncService(httpPro, reqistry);
NHttpConnectionFactory<DefaultNHttpServerConnection> factory ;
if (port == 8443) {// 处理SSL连接
try {
ClassLoader cl = Main.class.getClassLoader();
URL url = cl.getResource("my.keystore");
if (url == null) {
throw new FileNotFoundException("keystore not found !");
}
KeyStore keystore = KeyStore.getInstance("jks");
keystore.load(url.openStream(), "secret".toCharArray());
KeyManagerFactory kmfactory = KeyManagerFactory
.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmfactory.init(keystore, "secret".toCharArray());
KeyManager[] keymanagers = kmfactory.getKeyManagers();
SSLContext sslcontext = SSLContext.getInstance("TLS");
sslcontext.init(keymanagers, null, null);
factory = newSSLNHttpServerConnectionFactory(sslcontext,null,ConnectionConfig.DEFAULT);
} catch (UnrecoverableKeyException | KeyManagementException
| KeyStoreException | NoSuchAlgorithmException
| CertificateException | IOException e) {
factory = new DefaultNHttpServerConnectionFactory(ConnectionConfig.DEFAULT);
}
}else{
factory = new DefaultNHttpServerConnectionFactory(ConnectionConfig.DEFAULT);
}
IOEventDispatch eventDispath = new DefaultHttpServerIODispatch(service, factory);
IOReactorConfig.Builder configBuilder = IOReactorConfig.custom();
configBuilder.setIoThreadCount(Runtime.getRuntime().availableProcessors()*2);
configBuilder.setSoTimeout(3000);
configBuilder.setConnectTimeout(3000);
IOReactorConfig config = configBuilder.build();
ListeningIOReactor reactor = new DefaultListeningIOReactor(config);
reactor.listen(new InetSocketAddress(hostname, port));
reactor.execute(eventDispath);
}
static class BussinessHandlder implements HttpAsyncRequestHandler<HttpRequest>{
@Override
public void handle(HttpRequest request, HttpAsyncExchange exchange, HttpContext context)throws HttpException, IOException {
System.out.println(Thread.currentThread().getName()+":"+request.getRequestLine().getMethod());
HttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.SC_OK);
NStringEntity entity = new NStringEntity( "<html><body>"+new Random().nextDouble()+"</body></html>", ContentType.create("text/html", "UTF-8"));
response.setEntity(entity);
exchange.submitResponse(new BasicAsyncResponseProducer(response));
}
@Override
public HttpAsyncRequestConsumer<HttpRequest> processRequest( HttpRequest request, HttpContext context) throws HttpException, IOException {
return new BasicAsyncRequestConsumer();
}
}
}