简单的基于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 }