下面是 Java 如何实现一个 http 服务器的完整攻略:
1. 了解 HTTP 协议
HTTP(Hypertext Transfer Protocol,超文本传输协议)是一个应用层协议,用于在 Web 上传输超文本。在实现自己的 http 服务器之前,需要先对 HTTP 协议有一个基本的了解。
2. 实现一个 HTTP 请求处理器
在 Java 中,可以使用 Socket 来实现 ServerSocket,来监听和处理 HTTP 请求。通过读取 Socket InputStream 中的请求数据,解析请求头以及请求体,处理请求并返回响应。下面是一个简单的示例:
import java.io.*;
import java.net.*;
import java.util.*;
public class HttpServer implements Runnable {
private Socket client;
public HttpServer(Socket client) {
this.client = client;
}
public void run() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
String line = reader.readLine();
String[] request = line.split(" ");
String method = request[0];
String path = request[1];
String query = null;
int pos = path.indexOf('?');
if (pos != -1) {
query = path.substring(pos + 1);
path = path.substring(0, pos);
}
String protocol = request[2];
Map<String, String> headers = new HashMap<String, String>();
while ((line = reader.readLine()) != null && !line.isEmpty()) {
int pos2 = line.indexOf(':');
if (pos2 != -1) {
String name = line.substring(0, pos2).trim();
String value = line.substring(pos2 + 1).trim();
headers.put(name, value);
}
}
StringBuilder body = new StringBuilder();
while (reader.ready()) {
body.append((char)reader.read());
}
OutputStream out = client.getOutputStream();
out.write("HTTP/1.1 200 OK\r\n".getBytes());
out.write("Content-Type: text/html\r\n".getBytes());
out.write("\r\n".getBytes());
out.write("<h1>Hello World</h1>".getBytes());
out.flush();
client.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(8080);
while (true) {
Socket client = server.accept();
Thread thread = new Thread(new HttpServer(client));
thread.start();
}
}
}
该示例只实现了最简单的 HTTP GET 请求处理,并返回一个固定的响应。对于其他的 HTTP 请求(如 POST 请求),还需要在代码中进行处理。
3. 实现静态资源服务器
以上的示例只是简单地返回一个字符串作为响应,实际上,我们需要处理各种文件类型的请求,如 HTML、CSS、JavaScript、图片等。我们可以根据请求路径的后缀名来判断请求的资源类型,并读取相应的文件进行返回。
import java.io.*;
import java.net.*;
import java.util.*;
public class StaticServer implements Runnable {
private Socket client;
public StaticServer(Socket client) {
this.client = client;
}
public void run() {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
String line = reader.readLine();
String[] request = line.split(" ");
String method = request[0];
String path = request[1];
String query = null;
int pos = path.indexOf('?');
if (pos != -1) {
query = path.substring(pos + 1);
path = path.substring(0, pos);
}
String protocol = request[2];
Map<String, String> headers = new HashMap<String, String>();
while ((line = reader.readLine()) != null && !line.isEmpty()) {
int pos2 = line.indexOf(':');
if (pos2 != -1) {
String name = line.substring(0, pos2).trim();
String value = line.substring(pos2 + 1).trim();
headers.put(name, value);
}
}
String baseDir = "";
if (path.endsWith(".html")) {
baseDir = "html";
} else if (path.endsWith(".css")) {
baseDir = "css";
} else if (path.endsWith(".js")) {
baseDir = "js";
} else if (path.endsWith(".jpg") || path.endsWith(".jpeg") || path.endsWith(".png") || path.endsWith(".gif")) {
baseDir = "img";
} else {
return;
}
byte[] data = null;
try {
File file = new File(baseDir + path);
InputStream input = new FileInputStream(file);
OutputStream output = client.getOutputStream();
data = new byte[input.available()];
input.read(data);
input.close();
String contentType = "text/html";
if (path.endsWith(".css")) {
contentType = "text/css";
} else if (path.endsWith(".js")) {
contentType = "text/javascript";
} else if (path.endsWith(".jpg")) {
contentType = "image/jpeg";
} else if (path.endsWith(".jpeg")) {
contentType = "image/jpeg";
} else if (path.endsWith(".png")) {
contentType = "image/png";
} else if (path.endsWith(".gif")) {
contentType = "image/gif";
}
output.write(("HTTP/1.1 200 OK\r\nContent-Type: " + contentType + "\r\n\r\n").getBytes());
output.write(data);
output.flush();
output.close();
} catch (FileNotFoundException ex) {
OutputStream output = client.getOutputStream();
output.write("HTTP/1.1 404 Not Found\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n".getBytes());
output.write("<h1>404 Not Found</h1>".getBytes());
output.flush();
output.close();
}
client.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(8080);
while (true) {
Socket client = server.accept();
Thread thread = new Thread(new StaticServer(client));
thread.start();
}
}
}
这个示例实现了静态资源请求的处理,根据请求路径的后缀名返回相应的 MIME 类型,并读取相应的文件进行返回, 如果请求的路径不存在, 返回 404 Not Found 响应。
以上就是 Java 实现一个 http 服务器的完整攻略,以上示例只是一个非常简单的例子,实际上,一个完整的 http 服务器还需要实现很多功能,如动态资源处理、多线程处理、请求过滤、安全性等。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java 如何实现一个http服务器 - Python技术站