简单服务器开发(六)服务器截获请求URI
之前的开发步骤:简单服务器开发
开始处理客户端的请求,首先我们需要知道客户端访问的是哪一个资源,我们怎么才能知道客户端访问的哪个资源呢?
答案当然是在服务器端获取客户端请求的URI,请求的URI在HTTP请求协议的请求行上。所以我们需要读取请求协议的第一行数据,
然后从这些数据中解析出URI,从而得出客户要访问的是服务器端的哪个资源。
(1) URL 和 和 URI 是什么?它们之间是什么关系?
A、 URL(Uniform Resource Locator) 是统一资源定位符,例如在浏览器地址栏上直接输入的请求路径 http://127.0.0.1:8080/oa/index.html 就是一个 URL ,通过它可以定位网络中的某个资源。
B、 URI(Uniform Resource Identifier) 是统一资源标识符,只是代表网络中某个资源的名称,不具备定位功能,或者说 URI 是 URL 的一部分。例如上面的 URL 中/oa/index.html 就是一个 URI 。
(2) HTTP 协议请求协议的请求行由三部分组成:请求方式+URI+ 协议版本号,我们需要获取的就是请求行上的 URI
(3) 在 在 HandlerRequest.java 中 编写程序读取请求行
A、解析 客户请求的 字符串,截获 URI
B、通过 BufferedReader 获取请求消息
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); // 获取 requestURI :String requestURI = br.readLine().split(“ ”)[1]; 打印输出 requestURI 到控制台
(4)启动 httpserver,打开浏览器,输入 URL:http://127.0.0.1:8080/oa/index.html 进行访问测试
package com.zda.httpserver.core; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.Socket; import com.zda.httpserver.util.Logger; /** * 处理客户端请求 * @author zda * @version 1.0 * @since 1.0 */ public class HandlerRequest implements Runnable { public Socket clientSocket; public HandlerRequest(Socket clientSocket){ this.clientSocket = clientSocket; } @Override public void run() { //处理客户端请求 BufferedReader br = null; Logger.log("httpserver thread: " + Thread.currentThread().getName()); try { //接收客户端消息 br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); //打印客户端消息 /*String temp = null; while((temp = br.readLine()) != null){ System.out.println(temp); }*/ //获取请求协议的请求行 String requestLine = br.readLine();// GET /oa/index.html HTTP/1.1 //获取URI -> 请求行(requestLine) -> 请求方式 URI 请求协议版本号 -> 三者之间是通过一个空格进行连接 String requestURI = requestLine.split(" ")[1];//{"GET","/oa/index.html","HTTP/1.1"} System.out.println(requestURI); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ //关闭资源 if(br != null){ try { br.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(clientSocket != null){ try { clientSocket.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
输出
上面的多个请求:
这是浏览器自身的机制,底层发送了很多次请求,保证用户请求的资源一定被拿到。