新建Maven项目
目录结构:
ClientHandler
public class ClientHandler implements Runnable {
private Socket socket;
//新建构造方法,实话化时将传入的socket赋值
public ClientHandler(Socket socket){
this.socket = socket;
}
public void run() {
/**
* 一问一答交互方式
* 1. 解析请求
* 2. 处理请求
* 3. 发送响应
*/
try {
//实例化HttpRequest对象,解析请求
HttpRequest request = new HttpRequest(socket);
} catch (Exception e) {
e.printStackTrace();
}
}
}
WebServer
public class WebServer {
private ServerSocket server;
public WebServer(){
try {
System.out.println("服务端正在启动");
server = new ServerSocket(8088);
System.out.println("启动完成");
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
WebServer server = new WebServer();
server.start();
}
private void start() {
try {
System.out.println("等待客户端链接");
//阻塞线程,等待一个客户端链接,连接后继续执行
Socket socket = server.accept();
System.out.println("一个客户端链接了");
ClientHandler handler = new ClientHandler(socket);
Thread t = new Thread(handler);
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
HttpRequest
/**
* 该类对象对应客户端的一次请求
* 包含请求中的各种属性
* 请求行中的请求方法/路径/版本 消息头中的信息等
*/
public class HttpRequest {
//请求行三个属性
private String method;
private String url;
private String protocol;
//消息头中的信息
//消息正文中的信息
//客户端发送过来的socket
private Socket socket;
//通过socket获得的输入流
private InputStream is;
/**
* 构造方法
* 初始化当前类的socket和is
* 获得请求信息
*/
public HttpRequest(Socket socket){
try {
this.socket = socket;
this.is = socket.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("HttpRequest开始解析请求。。。");
//1.解析请求行
parseRequestLine();
//2.解析消息头
parseHeaders();
//3.解析消息正文
parseContent();
System.out.println("HttpRequest解析请求结束");
}
//解析请求行
public void parseRequestLine(){
System.out.println("开始请求请求行");
try {
String line = readLine();
System.out.println("请求行信息获得"+line);
//按空格拆分
String[] data = line.split("\\s");
method = data[0];
url = data[1];
protocol = data[2];
System.out.println("method"+method);
System.out.println("url"+url);
System.out.println("protocol"+protocol);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("请求行解析结束");
}
//解析消息头
public void parseHeaders(){
System.out.println("开始解析消息头");
try {
while (true){
String line = readLine();
//消息头结束时会有个空行,读取到空行表示消息头结束
if ("".equals(line)){
break;
}
System.out.println("消息头"+line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
//解析消息正文
public void parseContent(){
}
//从客户端发送过来的请求中读取一行信息
public String readLine() throws IOException {
//定义一个可变长度字符串接受一行文字
StringBuilder builder = new StringBuilder();
int d = -1;
//定义两个值,什么都行只要不是13和10,保证循环不退出
char c1 = 'a', c2 = 'a';
//读取低八位,如果不为-1则证明还有下一个字节
while((d=is.read()) != -1){
c2 = (char)d;
//按照http规定协议判断是否在换行
if (c1==13 && c2==10){
break;
}
//append累加,c2已经转换成为charl,不要再转换了
builder.append(c2);
//c2吃赋值给c1,作为下次循环的上一个字符
c1=c2;
// System.out.print((char) d);
}
return builder.toString().trim();
}
}