涉及Web服务器的相关技术
IO流、Socket网络编程、HTTP协议、文件、多线程(同时处理多个浏览器的请求)、List集合
连接过程:Web服务器与其浏览器之间建立的连接,判定两者之间是否连接成功;若用户可以找到并打开虚拟文件套接字,说明Web服务器与其浏览器之间成功建立了连接。
请求过程:Web浏览器利用socket文件向其服务器发出各种请求。
获取请求资源的地址
根据是静态资源还是动态资源做出相应的处理
响应过程:在请求过程中发出的请求通过使用HTTP协议传输到Web服务器,然后执行任务处理。
关闭连接:响应过程完成后,Web服务器与其浏览器断开连接的过程。
(1)Main类
package com.weh;
import com.weh.httpserver.MyHttpServer;
public class Main {
// 开启多线程
public static void main(String[] args) {
new Thread(new MyHttpServer()).start();
}
}
(2)MyHttpServer类
package com.weh.httpserver;
import com.weh.response.MyResponse;
import com.weh.request.MyRequest;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
/*
* 1.通过Runnable接口的实现类,来开启线程
* 2.创建并开启服务器
* 3.实现服务端与客户端进行连接通信
* */
public class MyHttpServer implements Runnable{
public static final int port = 8080; //服务器端口号
public static final String WEB_ROOT=System.getProperty("user.dir")+
File.separator+ "webapps"; //服务器的当前文件目录路径
@Override
public void run() {
ServerSocket serverSocket=null;
Socket socket;
InputStream input=null;
OutputStream output=null;
try {
System.out.println("Web服务器已开启");
serverSocket = new ServerSocket(port); //传入端口号并创建服务器
} catch (Exception e) {
System.exit(0);
}
//服务端与客户端浏览器进行通信
while(true){
try {
socket=serverSocket.accept();//请求
input=socket.getInputStream();//获取客户端发过来信息
output=socket.getOutputStream();
MyRequest request=new MyRequest(input); //数据处理
request.parse();
MyResponse response=new MyResponse(output);
response.setMyRequest(request);
response.sendStaticResource();//发送
} catch (Exception e) {
e.printStackTrace();
continue;
}finally {
// 释放资源
release(input,output);
}
}
}
// 释放资源
public void release(InputStream inputStream,OutputStream outputStream){
try {
if(inputStream != null) {
inputStream.close();
}
if(outputStream != null){
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
(3)MyRequest类
package com.weh.request;
import java.io.InputStream;
/*
* 自定义MyRequest类
* 1.主要处理客户端发过来的信息进行处理并输出
* 2.获取客户端切换到哪个文件的名称
* */
public class MyRequest {
private InputStream input;
private String uri;
public MyRequest(InputStream input){
this.input=input;
}
// 输出客户端发过来的信息
public void parse(){
StringBuffer request=new StringBuffer(2048);
int len;
byte[] buffer=new byte[2048];
try {
len=input.read(buffer);
} catch (Exception e) {
len=-1;
}
for(int j=0;j<len;j++){
request.append((char)buffer[j]);
}
System.out.print(request.toString());
parseUri(request.toString());
}
// 获取切换后的文件名
public void parseUri(String srt){
int index1,index2;
index1=srt.indexOf(" ");
if(index1!=-1){
index2=srt.indexOf(" ",index1+1);
if(index2>index1){
setUri(srt.substring(index1+1,index2));
}
}
}
public void setUri(String uri) {
this.uri = uri;
}
public String getUri(){
return this.uri;
}
}
(4)MyResponse类
package com.weh.response;
import com.weh.httpserver.MyHttpServer;
import com.weh.request.MyRequest;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.List;
/*
* 自定义MyResponse类
* 1.向Socket的输出流中写请求给浏览器作出响应的结果
* 2.获取当前目录下的所有文件并创建文件类型的数组
* 3.数据的读取及转发
* */
public class MyResponse {
private static final int BUFFER_SIZE=1024;
MyRequest request;
OutputStream output;
FileInputStream fis=null;
PrintWriter printWriter =null;
public MyResponse(OutputStream output){
this.output=output;
}
public void setMyRequest(MyRequest request){
this.request=request;
}
public void sendStaticResource()throws IOException{
byte[] bytes=new byte[BUFFER_SIZE];
try {
printWriter = new PrintWriter(output); //创建缓冲字符输出流
File file=new File(MyHttpServer.WEB_ROOT+request.getUri());
if(file.exists()){ //判断文件目录是否存在
//向Socket的输出流中写请求给浏览器作出响应的结果
printWriter.println("HTTP/1.1 200 OK");
printWriter.println("Content-Type:text/html;charset=UTF-8");
printWriter.println();
// 判断文件是否为普通文件
if(file.isFile()){
fis=new FileInputStream(file.getPath()); //创建文件字节输入流
fis.read(bytes); //读取直接流
printWriter.write(new String(bytes));
// 判断文件是否为文件目录
}else if(file.isDirectory()){
List<File> list= Arrays.asList(new File(file.getPath()).listFiles());//获取当前目录下的所有文件并创建文件类型的数组
for(File filename : list){//数组遍历
if(filename.getName().indexOf(".htm")>0) {//判断是否含有.htm的字符的文件
printWriter.write("" );
printWriter.write(""
+ filename.getName() + "");
printWriter.write("");
}
}
}
// 若该文件不存在,则输出信息 File Not Found
}else{
printWriter.println("HTTP/1.1 404 File Not Found");
printWriter.println("Content-Type:text/html;charset=UTF-8");
printWriter.println("Content-Length:23");
printWriter.println();
printWriter.write("File Not Found
");
}
printWriter.flush();//不返回任何值,只用于刷新流
} catch (Exception e) {
e.printStackTrace();
}finally{
if(printWriter!=null){
printWriter.close();
}
if(output!=null){
output.close();
}
if(fis!=null){
fis.close();
}
}
}
}