Http服务器版本2.

import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class HttpServerV2 { //1、修改代码格式 //2、解析url中的包含的参数 //3、演示cookie工作流程 private ServerSocket serverSocket = null; public HttpServerV2(int port) throws IOException { serverSocket = new ServerSocket(port); } public void start() throws IOException { System.out.println("服务器启动"); ExecutorService executorService = Executors.newCachedThreadPool(); while (true) { Socket clienSocket = serverSocket.accept(); executorService.execute(new Runnable() { @Override public void run() { try { process(clienSocket); } catch (IOException e) { e.printStackTrace(); } } }); } }private void process(Socket clienSocket) throws IOException {try { //1、读取请求并解析 HttpRequest request = HttpRequest.build(clienSocket.getInputStream()); System.out.println("request: "+request); HttpResponse response = HttpResponse.build(clienSocket.getOutputStream()); //2、根据请求计算响应 response.setHeader("content-type","text/html"); if (request.getUrl().startsWith("/hello")) { response.setStatus(200); response.setMessage("OK"); response.writeBody("hello"); } else if (request.getUrl().startsWith("/calc")) { String aStr =request.getParameters("a"); String bStr = request.getParameters("b"); int a = Integer.parseInt(aStr); int b = Integer.parseInt(bStr); int result = a + b; response.setStatus(200); response.setMessage("OK"); response.writeBody("result = "+result+""); } else if (request.getUrl().startsWith("/cookie")){ response.setStatus(200); response.setMessage("OK"); response.setHeader("set-cookie","user=yfy time="+ System.currentTimeMillis()/1000); response.writeBody("set-cookie"); } else{ response.setStatus(200); response.setMessage("OK"); response.writeBody("default"); }//3、把响应写回到客户端 response.flush(); } catch (IOException e) { e.printStackTrace(); } finally { clienSocket.close(); } }public static void main(String[] args) throws IOException { HttpServerV2 serverV2 = new HttpServerV2(9090); serverV2.start(); } }

import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.util.HashMap; import java.util.Map; public class HttpResponse { //表示一个HTTP响应 private String version = "HTTP/1.1"; private int status; //状态码 private String message; //状态码的描述信息 private Map headers = new HashMap<>(); private StringBuilder body = new StringBuilder(); //方便拼接 //需要把响应写回到客户端时,写到outputStream中去 private OutputStream outputStream = null; public static HttpResponse build(OutputStream outputStream) { HttpResponse response = new HttpResponse(); response.outputStream = outputStream; return response; }public void setVersion(String version) { this.version = version; }public void setStatus(int status) { this.status = status; }public void setMessage(String message) { this.message = message; }public void setHeader(String key, String value) { headers.put(key,value); }public void writeBody(String content) { body.append(content); }public void flush() throws IOException { BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream)); bufferedWriter.write(version +" "+ status +" "+ message + "\n"); headers.put("content-Length: " ,body.toString().getBytes().length+""); for (Map.Entry entry : headers.entrySet()) { System.out.println(entry.getKey()+":"+entry.getValue()+"\n"); } bufferedWriter.write("\n"); bufferedWriter.write(body.toString()); bufferedWriter.flush(); } }

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Map; public class HttpRequest { private String method; private String url; private String version; private Map headers = new HashMap<>(); private Map parameters = new HashMap<>(); //请求的构造逻辑,也使用工厂模式 //此处的参数是从socket中获取到的InputStream对象 public static HttpRequest build(InputStream inputStream) throws IOException { HttpRequest request = new HttpRequest(); //此处的逻辑中,不能把bufferedread写到try中,写进去意味着bufferedreader会被关闭 //影响clientSocket的状态 //等到整个请求处理完了再关闭 BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); //build的过程就是解析请求的过程 //1、解析首行 String firstLine = bufferedReader.readLine(); String[] firstLineTokens = firstLine.split(" "); request.method = firstLineTokens[0]; request.url = firstLineTokens[1]; request.version = firstLineTokens[2]; //2、解析url中的参数 /index.html?a=10&b=20 int post = request.url.indexOf("?"); if (post != -1) { //看看url中是否有?,如果没有说明不带参数,也就不用解析 String parameters = request.url.substring(post+1); //a=10&b=20 parseKV(parameters, request.parameters); } //3、解析header String line = ""; while ((line = bufferedReader.readLine()) != null && line.getBytes().length != 0){ String[] headerTokens = line.split(": "); request.headers.put(headerTokens[0],headerTokens[1]); } //4、解析body return request; }private static void parseKV(String input, Map output) { //按照&切分成若干组键值对 String[] KVTokens = input.split("&"); //按照切分结果再进行=切分 for(String KV : KVTokens) { String[] result = KV.split("="); output.put(result[0],result[1]); } }//给这个类构造一些getter方法 //请求的对象是从网络上解析来的,所以不需要setterpublic String getMethod() { return method; }public String getUrl() { return url; }public String getVersion() { return version; }public String getHeader (String key) { return headers.get(key); }public String getParameters (String key) { return parameters.get(key); }@Override public String toString() { return "HttpRequest{" + "method='" + method + '\'' + ", url='" + url + '\'' + ", version='" + version + '\'' + ", headers=" + headers + ", parameters=" + parameters + '}'; } }

【Http服务器版本2.】

    推荐阅读