学习笔记——request
一、学习重点
二、学习内容
案例
import java.io.IOException; import java.io.InputStream; public class IOUtils { // 读取流中的数据 public static String readString(InputStream inputStream) { System.out.println(inputStream+"-----------------------------"); try{ int len = 0; while(len == 0){ len = inputStream.available(); } byte[] buffer = new byte[len]; inputStream.read(buffer); return new String(buffer,0,len); } catch (IOException e) { e.printStackTrace(); } return null; } }
import java.util.HashMap; import java.util.Map; /** * 将接收的请求转化为请求对象 */ public class Request { // 请求的协议 private String protocol; // 请求的方式 private String type; // uri private String uri; // 请求头 private Map<String, String> header = new HashMap<>(); // 请求体 private String body; public String getProtocol() { return protocol; } public void setProtocol(String protocol) { this.protocol = protocol; } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getUri() { return uri; } public void setUri(String uri) { this.uri = uri; } public Map<String, String> getHeader() { return header; } public void setHeader(Map<String, String> header) { this.header = header; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } // 可以手动添加请求头信息 public void addHeader(String key,String value){ this.header.put(key,value); } @Override public String toString() { return "Request{" + "protocol='" + protocol + '\'' + ", type='" + type + '\'' + ", uri='" + uri + '\'' + ", header=" + header + ", body='" + body + '\'' + '}'; } }
/** * 处理请求 */ public class RequestHandler { /** * 将获取的请求封装成一个request对象 * */ public static Request hand(String requestMessage){ Request request = new Request(); // 操作字符串 // 字符串截取 String[] headerAndBody = requestMessage.split("\r\n\r\n"); // 判断有没有请求体 if(headerAndBody.length > 1){ request.setBody(headerAndBody[1]); } // 将请求行和首部信息截取 String[] lineAndHeader = headerAndBody[0].split("\r\n"); String line = lineAndHeader[0]; String[] lines = line.split(" "); request.setType(lines[0]); request.setUri(lines[1]); request.setProtocol(lines[2]); // 遍历请求头 for (int i = 1; i < lineAndHeader.length; i++) { String[] split = lineAndHeader[i].split(":"); request.addHeader(split[0],split[1]); } return request; } }
import java.util.HashMap; import java.util.Map; /** * 响应 */ public class Response { // 协议 private String protocol = "HTTP/1.1"; // 响应码 private String code = "200"; // 信息 private String message = "OK"; // 响应头 private Map<String, String> header = new HashMap<>(); // 响应体 private String body; public String getProtocol() { return protocol; } public void setProtocol(String protocol) { this.protocol = protocol; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public Map<String, String> getHeader() { return header; } public void setHeader(Map<String, String> header) { this.header = header; } public String getBody() { return body; } public void setBody(String body) { this.body = body; } // 添加响应头的方法 public void addHeader(String key,String value) { header.put(key,value); } @Override public String toString() { return "Response{" + "protocol='" + protocol + '\'' + ", code='" + code + '\'' + ", message='" + message + '\'' + ", header=" + header + ", body='" + body + '\'' + '}'; } }
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.Map; /** * 处理响应的工具类 */ public class ResponseHandler { // 定义我们的网站的根目录 private static final String BASE_PATH = "E:\\www\\"; /** * 生成一个响应字符串 */ public static String build(String path) { String htmlPath = BASE_PATH + path; try(FileInputStream fis = new FileInputStream(htmlPath)) { // 使用输入流读取文件的内容 String body = IOUtils.readString(fis); Response response = new Response(); response.setBody(body); response.addHeader("Content-Type","text/html;charset=UTF-8"); response.addHeader("Content-Length",String.valueOf(body.length())); return build(response); } catch (FileNotFoundException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } } public static String build(Response response) { StringBuilder strb = new StringBuilder(); strb.append(response.getProtocol()).append(" ").append(response.getCode()) .append(" ").append(response.getMessage()).append("\r\n"); for(Map.Entry<String,String> entry : response.getHeader().entrySet()) { strb.append(entry.getKey()).append(":").append(entry.getValue()).append("\r\n"); } if(response.getBody() != null) { strb.append("\r\n").append(response.getBody()); } System.out.println(strb.toString()); return strb.toString(); } }
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; public class UserThread implements Runnable { private final Socket socket; public UserThread(Socket socket) { this.socket = socket; } @Override public void run() { try(InputStream inputStream = socket.getInputStream(); OutputStream outputStream = socket.getOutputStream()) { String requestMessage = IOUtils.readString(inputStream); System.out.println("请求信息:" + requestMessage); Request request = RequestHandler.hand(requestMessage); String uri = request.getUri(); System.out.println("uri->" + uri); // 按照http协议的响应格式封装响应信息 if(!"/favicon.ico".equals(uri)){ // 直接使用输出流输出到浏览器 String response = ResponseHandler.build(uri); System.out.println("响应信息:" + response); outputStream.write(response.getBytes()); } } catch (IOException e) { throw new RuntimeException(e); } } }
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; /** * 我们的目的实现一个小程序, * 在浏览器中输入URL能够打开一个文件夹下面的HTML页面 * * 接请求,给响应 * * 我们不妨把请求和响应封装成两个对象, * 毕竟这个字符串操作太费劲了。 * */ public class MainServer { public static void main(String[] args) throws IOException { try{ ServerSocket serverSocket = new ServerSocket(8888); Socket server = serverSocket.accept(); InputStream inputStream = server.getInputStream(); String requestMessage = IOUtils.readString(inputStream); System.out.println(requestMessage + "................"); Request request = RequestHandler.hand(requestMessage.toString()); String uri = request.getUri(); uri = uri.substring(1); String response = ResponseHandler.build(uri); OutputStream outputStream = server.getOutputStream(); outputStream.write(response.getBytes()); inputStream.close(); server.close(); outputStream.flush(); }catch(Exception e) { e.printStackTrace(); } } }
三、学习总结
😵今天讲的内容刚刚好就是我的本专业内容,网络工程有好多需要记忆的点,和Java联系在一起有点懵,继续加油!!!
又是被三次握手四次挥手折磨的一次,为什么背了好几次的我次次都要重新背,忘性好大,😔!
四、理解程度
需要进一步理解!!!
五、笔记内容
C/S架构:Client/Server客户端/服务器,QQ,360,腾讯会议,游戏
B/S架构:Browser/Server浏览器/服务器,
移动互联,手机端为主,C/S架构,
Java主要要做的就是架构中的Server端。
1.静态资源:所有用户访问后,得到的结果都是一样的。html
2.动态资源:每个用户访问后,得到的结果可能不一样。爱奇艺,
web服务器。
接收用户的请求,处理请求,给出响应。
通过浏览器访问我们的ServerSocket服务器,我们通过浏览器给我们的ServerSocket服务器发起了请求
我要访问服务器!!!
通过IP地址 + 端口号
本机的IP地址:
1.cmd---ipconfig
2.127.0.0.1---本机(个人建议,任何情况都好使)
3.localhost---本机(前提条件:你的电脑要联网,激活一下网卡)
127.0.0.1:8080
我们通过浏览器访问我们的ServerSocket,得到了一堆信息,看不懂。
其实发送过来的信息,报文。浏览器传递过来的一些消息。
User-Agent:告诉服务器我是从什么样的客户端来的。
Host: 127.0.0.1:8080,主机地址,目标主机。
貌似浏览器也是通过Socket和我们的服务器建立了TCP连接
我们不妨把浏览器给我们的服务器发送的信息称之为“请求”,
而且这个请求格式满足了http的协议。
请求:客户端--->服务器
响应:服务器--->客户端
我需要给浏览器一个响应!!!
我们一般情况下,给浏览器做出响应,需要遵循浏览器的格式要求:
public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(8080); // 等待客户端的连接 Socket accept = serverSocket.accept(); // 获取一个输入流来读取客户端发送的数据 InputStream inputStream = accept.getInputStream(); byte [] buf = new byte[1024]; int len; while((len = inputStream.read(buf)) != -1){ System.out.println(new String(buf,0,len)); } inputStream.close(); accept.close(); }
import java.io.IOException; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class Server02 { public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(8888); System.out.println("服务器启动成功..."); Socket server = serverSocket.accept(); OutputStream outputStream = server.getOutputStream(); // 按照http协议的格式封装一个报文数据 String response = "HTTP/1.1 200 OK\r\n"+ "Content-Length: 39\r\n" + "Content-Type: text/html;charset=UTF-8\r\n\r\n" + "<h1>hello server</h1>"; outputStream.write(response.getBytes()); outputStream.flush(); // 这个流不要着急关,因为突然的关闭会导致浏览器和服务器断开连接 } }
重定向
假如我要访问的是www.baidu.com,结果页面展示的是www.jd.com
重定向会重新定位到新的页面,而且地址栏的地址也会随之变化。
public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(8888); System.out.println("服务器启动成功..."); Socket server = serverSocket.accept(); OutputStream outputStream = server.getOutputStream(); // 按照http协议的格式封装一个报文数据 String response = "HTTP/1.1 302 Moved Temporarily\r\n"+ "Location: https://www.baidu.com\r\n\r\n"; outputStream.write(response.getBytes()); outputStream.flush(); // 这个流不要着急关,因为突然的关闭会导致浏览器和服务器断开连接 }
面试题:三次握手 四次挥手
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY