之前有小伙伴向我请教一道笔试题:要求写出一个WEB应用服务,不得使用Servlet接口,用Socket实现,可以响应get请求,打印请求信息,并判断请求资源,若不存在,返回404信息,若资源存在,返回该资源,并且可以返回默认的静态页面。
我简单写了一个小Demo,实现了上述功能,在这里分享给大家。
思路
主线程启动Socket服务,循环接收客户端请求,接收到请求后,将流中的数据取出拼接成字符串,在控制台打印。响应时判断请求资源是否存在,若存在,将资源通过输出流响应给客户端,若资源不存在,将404错误信息通过输出流响应给客户端,同时指定一个静态页面作为默认返回。
创建4个类
MyHttpServer:定义Socket服务,循环接收请求。
MyHttpRequest:自定义请求对象,解析请求。
MyHttpResponse:自定义响应对象,根据请求做出响应。
Test:测试类,主线程中启动Socket服务。
代码
package com.southwind.server;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
public class MyHttpServer {
public static String WebContent = System.getProperty("user.dir") + File.separator + "WebContent";
private int port = 8080;
private boolean isShutdown = false;
public void receiving() {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
} catch (IOException ex) {
ex.printStackTrace();
System.exit(1);
}
// 接收请求
while (!isShutdown) {
Socket socket = null;
InputStream is = null;
OutputStream os = null;
try {
//获取连接
socket = serverSocket.accept();
is = socket.getInputStream();
os = socket.getOutputStream();
//解析请求
MyHttpRequest request = new MyHttpRequest(is);
request.parse();
//响应
MyHttpResponse response = new MyHttpResponse(os);
response.sendStaticResource(request);
} catch (Exception ex) {
ex.printStackTrace();
}finally {
// 关闭
try {
socket.close();
is.close();
os.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
package com.southwind.server;
import java.io.IOException;
import java.io.InputStream;
public class MyHttpRequest {
private InputStream input;
private String uri;
public MyHttpRequest(InputStream input) {
this.input = input;
}
public void parse() {
StringBuffer requestStr = new StringBuffer(2048);
int i;
byte[] buffer = new byte[2048];
try {
i = input.read(buffer);
} catch (IOException ex) {
ex.printStackTrace();
i = -1;
}
for (int j = 0; j < i; j++) {
requestStr.append((char) buffer[j]);
}
System.out.println(requestStr.toString());
uri = parseUri(requestStr.toString());
}
private String parseUri(String requestStr) {
int index1, index2;
index1 = requestStr.indexOf(' ');
if (index1 != -1) {
index2 = requestStr.indexOf(' ', index1 + 1);
if (index2 > index1) {
return requestStr.substring(index1 + 1, index2);
}
}
return null;
}
public String getUri() {
return uri;
}
}
package com.southwind.server;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
public class MyHttpResponse {
private OutputStream output;
public MyHttpResponse(OutputStream output) {
this.output = output;
}
public void sendStaticResource(MyHttpRequest request) throws IOException {
byte[] bytes = new byte[1024];
FileInputStream fis = null;
String filePath = request.getUri() == null ? "" : request.getUri().trim();
if (filePath.equals("/")) {
filePath = "/index.html";
}
try {
String result = null;
File file = new File(MyHttpServer.WebContent, filePath);
byte[] fileByte = new byte[(int) file.length()];
if (file.exists()) {
fis = new FileInputStream(file);
fis.read(fileByte);
fis.close();
result = new String(fileByte);
result = warpMessage("200", result);
output.write(result.getBytes());
} else {
String errorMessage = warpMessage("404", "404 File Not Found! The requested URL /404/ was not found on this server. ");
output.write(errorMessage.getBytes());
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private String warpMessage(String statusCode, String message) {
return "HTTP/1.1 " + statusCode + "\r\n" + "Content-Type: text/html\r\n" + "Content-Length: " + message.length()
+ "\r\n" + "\r\n" + message;
}
}
package com.southwind.server;
public class Test {
public static void main(String[] args) {
System.out.println("Server startup successfully");
MyHttpServer server = new MyHttpServer();
server.receiving();
}
}
源码:
github
https://github.com/southwind9801/MyWebServer.git