写点什么

实现一个简单的 HTTP,京东 java 面试问题大全及答案大全

用户头像
极客good
关注
发布于: 刚刚

String newUrl = url.substring(url.indexOf("?") + 1);


//然后将新的 newUrl 用“&”进行分隔变成 key=value 的形式


String[] newUrlArr = newUrl.split("&");


//遍历这个新的 newUrl


for (String kvs : newUrlArr) {


//然后 newUrl 里面的每一个 key=value 用“=”进行分隔


String[] item = kvs.split("=");


//然后放进 map 里面也就是 parents 里面


parments.put(item[0], item[1]);


}


}


}


//如果外部类要去使用的话,我们必须提供 get 方法


public String getMethod() {


return method;


}


public String getUrl() {


return url;


}


public String getVersion() {


return version;


}


//然后手动实现两个 map 的 get 方法


public String getParents(String key){


return this.parments.get(key);


}


public String getRequestHeader(String key){


return this.requsetHeader.get(key);


}


}

[](

)Response


import java.io.PrintWriter;


import java.util.HashMap;


import java.util.Map;


/**


  • 输出信息


*/


public class myHttpResponse {


//1.首行信息【http 版本号+状态码+状态描述符】


//版本号,因为版本号是固定的,不可修改的,那么我们可以设置成静态变量,并且用 final 修饰,然后返回的是 HTTP/1.1


private static final String version = "HTTP/1.1";


//状态码


private Integer state;


//状态描述符


private String stateMessage;


//2.header(响应报文头)其中(Content—Type 和 Content—Length)很重要,而且它是以 key: value 的形式存储的


Map<String,String> responseHeader = new HashMap<>();


//3.空行


//4.body


//这个是服务器自定义返回的一个信息,因为 String 的性能很低,而且会产生很多的垃圾,所以我们使用 StringBuffer


StringBuffer responseBody = new StringBuffer();


//这里要严格遵循 HTTP 协议的格式输出


public void flush(PrintWriter writer){


//1.先输出首行,注意:按照空格进行分隔


writer.println(String.format("%s %d %s",version,this.state,this.stateMessage));


//2.写入 header 内容(Content—Type(会自己进行设置)和 Content—Length(不会进行设置,所以要自己写))


for (Map.Entry<String,String> item:responseHeader.entrySet()){


//key Value,拼接输出时要以“: ”(冒号+空格)进行分隔输出


writer.println(String.format("%s: %s",item.getKey(),item.getValue()));


}


//添加一个 Content—Length


writer.println("Content—Length: "+responseBody.toString().getBytes().length);


//输出空行


writer.println();


//输出 body


writer.println(responseBody.toString());


}


//因为它是需要写入的,所以需要提供 set 方法,需要手动添加一个 header 方法


public void setState(Integer state) {


this.state = state;


}


public void setStateMessage(String stateMessage) {


this.stateMessage = stateMessage;


}


//每次可能就只写入一段内容那么就每次把 body 内容加进去


public void setResponseBody(String body) {


this.responseBody.append(body);


}


//需要设置两个值,一个 key,一个 value,然后把这个 key 和 value 放入 responseHeader 中


public void setResponseHeader(String key,String value){


this.responseHeader.put(key,value);


}


}


Server(服务器端)


import java.io.*;


import java.net.ServerSocket;


import java.net.Socket;


import java.util.concurrent.LinkedBlockingQueue;


import java.util.concurrent.ThreadPoolExecutor;


import java.util.concurrent.TimeUnit;


public class MyHttpServer2 {


private ServerSocket serverSocket = null;


public MyHttpServer2(int port) throws IOException {


serverSocket = new ServerSocket(port);


}


public void start() throws IOException {


System.out.println("服务器正常启动了~");


//为了让一个服务器响应多个客户端,所以我们使用线程池


ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10,15,100,TimeUnit.SECONDS,


new LinkedBlockingQueue<>(10));


while(true){


//首先等待客户端连接,此处的客户端就是浏览器


Socket clientSocket = serverSocket.accept();


threadPoolExecutor.submit(()->{


//然后处理接收到的消息


try {


procescsSocket(clientSocket);


} catch (IOException e) {


e.printStackTrace();


}


});


}


}


private void procescsSocket(Socket clientSocket) throws IOException {


//从 Socket 中拿到两个对象,一个是 Reader 读取对象,一个是响应对象 Writer


try(


BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));


PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(clientSocket.getOutputStream()))


) {


//然后我们


【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


就可以用我们刚刚声明的方法进行封装


myHttpRequest request = new myHttpRequest();


//然后给他的值设置内容,然后这里实现了代码的复用,就不用每次写获取响应的代码了


request.init(bufferedReader);


//打印首行信息


System.out.println(String.format("首行信息: %s %s %s",request.getMethod(),request.getUrl(),request.getVersion()));


//业务处理,不同的访问地址(url)返回不同的页面


myHttpResponse response = new myHttpResponse();


//响应的页面类型为 html


response.setResponseHeader("Content-Type","text/html; charset=utf-8");


//if(requesr.getUrl.indexOf("/404") != -1)等同于 if(request.getUrl().startsWith("/404"))


if(request.getUrl().startsWith("/404")){


//然后 404 页面


response.setState(404);


response.setStateMessage("not found");


//如果是 404body 可以为空


}else if(request.getUrl().startsWith("/302")){


//跳转到指定的页面,如跳转到百度,如果是跳转,一定要设置一个 header Location-> https://www.baidu.com;


response.setState(302);


response.setResponseHeader("Location","https://www.baidu.com");


response.setStateMessage("Location");


//此时跳转到另一个页面了,所以 body 也可以为空


}else {


//正常返回页面


response.setState(200);


response.setStateMessage("OK");


//此时正常返回页面,那么显示一个 body 内容,此时因为有中文,所以一定要注意设置编码格式

用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
实现一个简单的HTTP,京东java面试问题大全及答案大全