涉及Web服务器相关技术
IO流、Socket网络编程、HTTP协议、文件、多线程(同时处理多个浏览器的请求)List集合
1 web应用服务器运行原理:
-
连接过程:Web服务器与浏览器之间的连接,确定两者之间的连接是否成功;如果用户能找到并打开虚拟文件套接字,说明Web成功地连接了服务器及其浏览器。
-
请求过程:Web浏览器利用socket文件向其服务器发出各种请求。
-
获取请求资源的地址
-
根据静态资源或动态资源进行相应的处理
-
响应过程:使用请求过程中发出的请求HTTP协议传输到Web服务器,然后执行任务处理。
-
关闭连接:响应过程完成后,Web服务器与浏览器断开连接的过程。
2 代码展示
(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("<li>");
printWriter.write("<a style='text-decoration:blink;' href='" +
"./" + filename.getName() + "'>"
+ filename.getName() + "</a>");
printWriter.write("</li>");
}
}
}
// 若该文件不存在,则输出信息 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("<h1>File Not Found</h1>");
}
printWriter.flush();//不返回任何值,只用于刷新流
} catch (Exception e) {
e.printStackTrace();
}finally{
if(printWriter!=null){
printWriter.close();
}
if(output!=null){
output.close();
}
if(fis!=null){
fis.close();
}
}
}
}