简单的 http 服务器
简单的基于socket和NIO的 http server示例:
项目路径:https://github.com/windwant/windwant-demo/tree/master/httpserver-demo
1. Request:
1 package org.windwant.httpserver; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 6 /** 7 * Created by windwant on 2016/6/12. 8 */ 9 public class Request { 10 11 private InputStream in; 12 13 public String getUri() { 14 return uri; 15 } 16 17 private String uri; 18 19 public Request(){} 20 21 public Request(InputStream in){ 22 this.in = in; 23 } 24 25 public void read(){ 26 StringBuffer sb = new StringBuffer(); 27 int i = 0; 28 byte[] b = new byte[2048]; 29 try { 30 i = in.read(b); 31 for (int j = 0; j < i; j++) { 32 sb.append((char)b[j]); 33 } 34 takeUri(sb); 35 } catch (IOException e) { 36 e.printStackTrace(); 37 } 38 } 39 40 public void takeUri(StringBuffer sb){ 41 int i = sb.indexOf(" "); 42 if(i > 0){ 43 int j = sb.indexOf(" ", i + 1); 44 if(j > 0){ 45 uri = sb.substring(i + 1, j).toString(); 46 System.out.println("http request uri: " + uri); 47 if(!(uri.endsWith("/index.html") || uri.endsWith("/test.jpg"))){ 48 uri = "/404.html"; 49 System.out.println("http request uri rewrite: " + uri); 50 } 51 } 52 } 53 } 54 55 }
2. Response:
1 package org.windwant.httpserver; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileNotFoundException; 6 import java.io.IOException; 7 import java.io.OutputStream; 8 import java.nio.ByteBuffer; 9 import java.nio.channels.SocketChannel; 10 11 /** 12 * Created by windwant on 2016/6/12. 13 */ 14 public class Response { 15 private static final int BUFFER_SIZE = 1024; 16 17 public void setRequest(Request request) { 18 this.request = request; 19 } 20 21 Request request; 22 23 OutputStream out; 24 25 SocketChannel osc; 26 27 public Response(OutputStream out){ 28 this.out = out; 29 } 30 31 public Response(SocketChannel osc){ 32 this.osc = osc; 33 } 34 35 public void response(){ 36 byte[] b = new byte[BUFFER_SIZE]; 37 File file = new File(HttpServer.WEB_ROOT, request.getUri()); 38 try { 39 StringBuilder sb = new StringBuilder(); 40 if(file.exists()){ 41 FileInputStream fi = new FileInputStream(file); 42 int ch = 0; 43 while ((ch = fi.read(b, 0, BUFFER_SIZE)) > 0){ 44 out.write(b, 0, ch); 45 } 46 out.flush(); 47 }else{ 48 sb.append("HTTP/1.1 404 File Not Found \r\n"); 49 sb.append("Content-Type: text/html\r\n"); 50 sb.append("Content-Length: 24\r\n" ); 51 sb.append("\r\n" ); 52 sb.append("<h1>File Not Found!</h1>"); 53 out.write(sb.toString().getBytes()); 54 } 55 } catch (FileNotFoundException e) { 56 e.printStackTrace(); 57 } catch (IOException e) { 58 e.printStackTrace(); 59 } 60 } 61 62 public void responseNIO(){ 63 byte[] b = new byte[BUFFER_SIZE]; 64 File file = new File(HttpServer.WEB_ROOT, request.getUri()); 65 try { 66 StringBuilder sb = new StringBuilder(); 67 if(file != null && file.exists()){ 68 FileInputStream fi = new FileInputStream(file); 69 while (fi.read(b) > 0){ 70 osc.write(ByteBuffer.wrap(b)); 71 b = new byte[BUFFER_SIZE]; 72 } 73 }else{ 74 sb.append("HTTP/1.1 404 File Not Found \r\n"); 75 sb.append("Content-Type: text/html\r\n"); 76 sb.append("Content-Length: 24\r\n" ); 77 sb.append("\r\n" ); 78 sb.append("<h1>File Not Found!</h1>"); 79 osc.write(ByteBuffer.wrap(sb.toString().getBytes())); 80 } 81 } catch (FileNotFoundException e) { 82 e.printStackTrace(); 83 } catch (IOException e) { 84 e.printStackTrace(); 85 } 86 } 87 88 }
3. HttpServer:
1 package org.windwant.httpserver; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.io.OutputStream; 6 import java.net.InetAddress; 7 import java.net.ServerSocket; 8 import java.net.Socket; 9 10 /** 11 * Created by windwant on 2016/6/12. 12 */ 13 public class HttpServer { 14 public static final String WEB_ROOT = System.getProperty("user.dir") + "\\src\\test\\resources\\webroot"; 15 public static final int SERVER_PORT = 8888; 16 public static final String SERVER_IP = "127.0.0.1"; 17 18 public static void main(String[] args) { 19 HttpServer httpServer = new HttpServer(); 20 httpServer.await(); 21 } 22 23 public void await(){ 24 ServerSocket serverSocket = null; 25 try { 26 serverSocket = new ServerSocket(SERVER_PORT, 1, InetAddress.getByName(SERVER_IP)); 27 while (true){ 28 Socket socket = serverSocket.accept(); 29 InputStream in = socket.getInputStream(); 30 OutputStream out = socket.getOutputStream(); 31 Request request = new Request(in); 32 request.read(); 33 34 Response response = new Response(out); 35 response.setRequest(request); 36 response.response(); 37 socket.close(); 38 } 39 } catch (IOException e) { 40 e.printStackTrace(); 41 } 42 } 43 }
4. HttpNIOServer:
1 package org.windwant.httpserver; 2 3 import java.io.IOException; 4 import java.net.InetSocketAddress; 5 import java.net.ServerSocket; 6 import java.nio.ByteBuffer; 7 import java.nio.channels.SelectionKey; 8 import java.nio.channels.Selector; 9 import java.nio.channels.ServerSocketChannel; 10 import java.nio.channels.SocketChannel; 11 import java.util.Iterator; 12 import java.util.Set; 13 import java.util.concurrent.ExecutorService; 14 import java.util.concurrent.Executors; 15 16 /** 17 * Created by windwant on 2016/6/13. 18 */ 19 public class HttpNIOServer { 20 21 private ServerSocketChannel serverSocketChannel; 22 23 private ServerSocket serverSocket; 24 25 private Selector selector; 26 27 Request request; 28 29 private ExecutorService es; 30 31 private static final Integer SERVER_PORT = 8888; 32 33 public void setShutdown(boolean shutdown) { 34 this.shutdown = shutdown; 35 } 36 37 private boolean shutdown = false; 38 39 40 public static void main(String[] args) { 41 HttpNIOServer server = new HttpNIOServer(); 42 server.start(); 43 System.exit(0); 44 } 45 46 HttpNIOServer(){ 47 try { 48 es = Executors.newFixedThreadPool(5); 49 serverSocketChannel = ServerSocketChannel.open(); 50 serverSocketChannel.configureBlocking(false); 51 serverSocket = serverSocketChannel.socket(); 52 serverSocket.bind(new InetSocketAddress(SERVER_PORT)); 53 54 selector = Selector.open(); 55 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); 56 System.out.println("server init..."); 57 } catch (IOException e) { 58 e.printStackTrace(); 59 } 60 } 61 62 public void start(){ 63 try { 64 while (!shutdown){ 65 selector.select(); 66 Set<SelectionKey> selectionKeySet = selector.selectedKeys(); 67 Iterator<SelectionKey> it = selectionKeySet.iterator(); 68 while (it.hasNext()){ 69 SelectionKey selectionKey = it.next(); 70 it.remove(); 71 handleRequest(selectionKey); 72 } 73 } 74 } catch (IOException e) { 75 e.printStackTrace(); 76 } 77 } 78 79 public void handleRequest(SelectionKey selectionKey){ 80 ServerSocketChannel ssc = null; 81 SocketChannel ss = null; 82 try { 83 if(selectionKey.isAcceptable()){ 84 ssc = (ServerSocketChannel) selectionKey.channel(); 85 ss = ssc.accept(); 86 87 ss.configureBlocking(false); 88 ss.register(selector, SelectionKey.OP_READ); 89 }else if(selectionKey.isReadable()){ 90 ss = (SocketChannel) selectionKey.channel(); 91 ByteBuffer byteBuffer = ByteBuffer.allocate(2048); 92 StringBuffer sb = new StringBuffer(); 93 while (ss.read(byteBuffer) > 0){ 94 byteBuffer.flip(); 95 int lgn = byteBuffer.limit(); 96 for (int i = 0; i < lgn; i++) { 97 sb.append((char)byteBuffer.get(i)); 98 } 99 byteBuffer.clear(); 100 } 101 if(sb.length() > 0) { 102 request = new Request(); 103 request.takeUri(sb); 104 ss.register(selector, SelectionKey.OP_WRITE); 105 } 106 }else if(selectionKey.isWritable()){ 107 ss = (SocketChannel) selectionKey.channel(); 108 ByteBuffer rb = ByteBuffer.allocate(2048); 109 Response response = new Response(ss); 110 response.setRequest(request); 111 response.responseNIO(); 112 ss.register(selector, SelectionKey.OP_READ); 113 } 114 } catch (IOException e) { 115 e.printStackTrace(); 116 } 117 } 118 }