http服务器主类
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class HttpServerV3 {
static class User {
public String userName;
public int age;
public String school;
}
private ServerSocket serverSocket = null;
private HashMap<String, User> session = new HashMap<>();
public HttpServerV3(int port) throws IOException {
serverSocket = new ServerSocket(port);
}
public void start() throws IOException {
System.out.println("服务器启动");
ExecutorService executorService = Executors.newCachedThreadPool();
while (true) {
Socket clientSocket = serverSocket.accept();
executorService.execute(new Runnable() {
@Override
public void run() {
process(clientSocket);
}
});
}
}
public void process(Socket clientSocket) {
try {
HttpRequest request = HttpRequest.build(clientSocket.getInputStream());
HttpResponse response = HttpResponse.build(clientSocket.getOutputStream());
if ("GET".equalsIgnoreCase(request.getMethod())) {
doGet(request, response);
} else if ("POST".equalsIgnoreCase(request.getMethod())) {
doPost(request, response);
} else {
response.setStatus(405);
response.setMessage("方法不明");
}
response.flush();
} catch (IOException | NullPointerException e) {
e.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void doGet(HttpRequest request, HttpResponse response) throws IOException {
if (request.getUrl().startsWith("/index.html")) {
String sessionId = request.getCookie("sessionId");
User user = session.get(sessionId);
if (sessionId == null || user == null) {
response.setStatus(200);
response.setMessage("OK");
response.setHeader("Content-Type", "text/html; charset=utf-8");
InputStream inputStream = HttpServerV3.class.getClassLoader().getResourceAsStream("index.html");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line = null;
while ((line = bufferedReader.readLine()) != null) {
response.writeBody(line + "\n");
}
bufferedReader.close();
} else {
response.setStatus(200);
response.setMessage("OK");
response.setHeader("Content-Type", "text/html; charset=utf-8");
response.writeBody("<html>");
response.writeBody("<div>" + "您已经登陆了! 无需再次登陆! 用户名: " + user.userName + "</div>");
response.writeBody(+user.age + "</div>");
response.writeBody("<div>" + user.school + "</div>");
response.writeBody("</html>");
}
}
}
private void doPost(HttpRequest request, HttpResponse response) {
if (request.getUrl().startsWith("/login")) {
String userName = request.getParameter("username");
String password = request.getParameter("password");
if ("kevin".equals(userName) && "123".equals(password)) {
response.setStatus(200);
response.setMessage("OK");
response.setHeader("Content-Type", "text/html; charset=utf-8");
String sessionId = UUID.randomUUID().toString();
User user = new User();
user.userName = "kevin";
user.age = 20;
user.school = "school";
session.put(sessionId, user);
response.setHeader("Set-Cookie", "sessionId=" + sessionId);
response.writeBody("<html>");
response.writeBody("<div>欢迎您! " + userName + "</div>");
response.writeBody("</html>");
} else {
response.setStatus(403);
response.setMessage("Forbidden");
response.setHeader("Content-Type", "text/html; charset=utf-8");
response.writeBody("<html>");
response.writeBody("<div>登陆失败</div>");
response.writeBody("</html>");
}
}
}
public static void main(String[] args) throws IOException {
HttpServerV3 serverV3 = new HttpServerV3(900);
serverV3.start();
}
}
处理请求
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<String, String> headers = new HashMap<>();
private Map<String, String> parameters = new HashMap<>();
private Map<String, String> cookies = new HashMap<>();
private String body;
public static HttpRequest build(InputStream inputStream) throws IOException {
HttpRequest request = new HttpRequest();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String firstLine = bufferedReader.readLine();
String[] fistLineTokens = firstLine.split(" ");
request.method = fistLineTokens[0];
request.url = fistLineTokens[1];
request.version = fistLineTokens[2];
int post = request.url.indexOf("?");
if (post != -1) {
String queryString = request.url.substring(post + 1);
parseKv(queryString, request.parameters);
}
String line = "";
while ((line = bufferedReader.readLine()) != null && line.length() != 0) {
String[] headerToken = line.split(": ");
request.headers.put(headerToken[0],headerToken[1]);
}
String cookie = request.headers.get("Cookie");
if (cookie != null) {
parseCookie(cookie, request.cookies);
}
if ("POST".equalsIgnoreCase(request.method)
|| "PUT".equalsIgnoreCase(request.method)) {
int contentLength = Integer.parseInt(request.headers.get("Content-Length"));
char[] buffer = new char[contentLength];
int len = bufferedReader.read(buffer);
request.body = new String(buffer, 0, len);
parseKv(request.body, request.parameters);
}
return request;
}
private static void parseCookie(String cookie, Map<String, String> cookies) {
String[] kvTokens = cookie.split(";");
for ( String kv : kvTokens) {
String[] result = kv.split("=");
cookies.put(result[0],result[1]);
}
}
private static void parseKv (String queryString, Map < String, String > parameters){
String[] kvTokens = queryString.split("&");
for (String kv : kvTokens) {
String[] result = kv.split("=");
parameters.put(result[0], result[1]);
}
}
public String getMethod() {
return method;
}
public String getUrl() {
return url;
}
public String getVersion() {
return version;
}
public String getHeaders(String key) {
return headers.get(key);
}
public String getParameter(String key) {
return parameters.get(key);
}
public String getCookie(String key) {
return cookies.get(key);
}
public String getBody() {
return body;
}
}
处理响应
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 {
private String version = "HTTP/1.1";
private int status;
private String message;
private Map<String, String> headers = new HashMap<>();
private StringBuilder body = new StringBuilder();
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<String, String> entry : headers.entrySet()) {
bufferedWriter.write(entry.getKey() + ": " + entry.getValue() + "\n");
}
bufferedWriter.write("\n");
bufferedWriter.write(body.toString());
bufferedWriter.flush();
}
}
登录页面html
<html>
<head>
<title>登陆页面</title>
<meta charset="utf-8">
</head>
<body>
<!-- 注释 -->
<form method="post" action="/login">
<div style="margin-bottom: 10px">
<input type="text" name="username" placeholder="请输入姓名">
</div>
<div style="margin-bottom: 10px">
<input type="password" name="password" placeholder="请输入密码">
</div>
<div>
<input type="submit" value="登陆">
</div>
</form>
</body>
</html>
fiddler抓取数据包
登录界面
第一次登录成功
第二次使用cookie进行免密登录