JAVA小白进阶day21

本文详细介绍了如何构建JAVA中的HttpResponse类,包括定义输出流、实体文件,实现发送状态行、响应头和正文的方法。同时讲解了HttpContext类的设计,用于设置媒体类型,并重构了WebServer的run方法以处理响应头。还涵盖了HttpRequest中消息头的解析工作,以及如何完成注册功能的相关逻辑。最后,讨论了解析配置文件web.xml以初始化介质类型映射的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第五个任务:
1.定义HttpResponse类:
1)定义HTTPResponse类在com.tedu.http包中
2)定义变量:
OutputStream out;
File entity;
定义setEntity()和getEntity()方法。
3)定义构造方法:HttpResponse(OutputStream out)
功能:初始化out成员变量
4)定义方法: println(String line) :void
功能:
向客户端发送一行字符串,该字符串会通过ISO8859-1转换为一组字节并写出.写出后会自动连续写出CRLF
out.write(line.getBytes(“ISO8859-1”));
out.write(13);
out.write(10);
5)定义方法sendStatusLine():void
功能:发送状态行信息
String line = “HTTP/1.1 200 OK”;
6)在sendStatusLine()放中调用println(String line)方法。
7)定义方法:getMimeTypeByEntity():String
功能:根据实体文件的名字获取对应的介质类型,Content-Type使用的值(常用的几种):根据文件扩展名返回文件的介质类型
if(“html”.equals(name)){
return “text/html”;
}else if(“jpg”.equals(name)){
return “image/jpg”;
}else if(“png”.equals(name)){
return “image/png”;
}
else if(“gif”.equals(name)){
return “image/gif”;
}
return “”;
测试:
8)定义方法:sendHeaders();
功能:响应头信息
println(“Content-Type:”+getMimeTypeByEntity());
println(“Content-Length:”+entity.length());
println("");//单独发送CRLF表示头发送完毕
9)定义方法: sendContent()
功能:发送响应正文信息
10)定义方法:flush():void
功能:调用sendStatusLine();sendHeaders();sendContent()

public class WebServer {
	ServerSocket server;
	public WebServer() {
		try {
			server = new ServerSocket(8888);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public void start() {
		while (true) {
			Socket socket;
			try {
				while (true) {
					System.out.println("等待客户端的请求");
					socket = server.accept();
					new Thread(new ClientHandler(socket)).start();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	class ClientHandler implements Runnable {
		Socket socket;
		public ClientHandler() {
		}
		public ClientHandler(Socket socket) {
			this.socket = socket;
		}
		@Override
		public void run() {
			//  \r\n ASCⅡ 13 10
			System.out.println("接收客户端请求");
			//获取请求状态行
			try {
				InputStream in =  socket.getInputStream();
				OutputStream out = socket.getOutputStream();
				HttpRequest request =new HttpRequest(in);
				HttpResponse response = new HttpResponse(out);
//				System.out.println(request.getMethod());
//				System.out.println(request.getUrl());
//				System.out.println(request.getProtocol());
				File file = new File("webapps"+request.getUrl());
				//响应页面
				response.setEntity(file);
				//响应的文档内容
				response.flush();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	public static void main(String[] args) {
		new WebServer().start();
	}
}

public class HttpRequest {
	public String method;
	public String url;
	public String protocol;
	public HttpRequest() {}
	public HttpRequest(InputStream in) {
		try {
			parseRequestLine(in);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public String getMethod() {
		return method;
	}
	public String getUrl() {
		return url;
	}
	public String getProtocol() {
		return protocol;
	}
	public void parseRequestLine(InputStream in) throws IOException {
		StringBuilder builder = new StringBuilder();
		char c1 = 0,c2 = 0;
		int d = -1;
		while((d=in.read())!=-1) {
			c2 = (char)d;
			//解析第一行,遇到 \r\n,break
			if(c1 == 13 && c2 == 10) {
				break;
			}
			builder.append(c2);
			c1 = c2;
		}
		String str = builder.toString().trim();
		String[] data = str.split(" ");
		this.method = data[0];//获取请求方式get
		this.url = data[1];//url请求
		this.protocol = data[2];//协议名称
	}
}

public class HttpResponse {
	OutputStream out;
	File entity;
	public HttpResponse(OutputStream out) {
		this.out = out;
	}
	public File getEntity() {
		return entity;
	}
	public void setEntity(File entity) {
		this.entity = entity;
	}
	public void println(String line) {
		try {
			out.write(line.getBytes());
			out.write(13);
			out.write(10);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void sendStatusLine() {
		String line = "HTTP/1.1 200 OK";
		this.println(line);
	}
	public void sendHeader() {
		String contentType = "Content -Type" + getMineTypeByEntity();
		this.println(contentType);
		long length = entity.length();
		String contentLength = "Content-Length:" + entity.length();
		this.println(contentLength);
		this.println("");
	}
	public void sendContent() throws IOException {
		try {
			FileInputStream fin = new FileInputStream(entity);
			byte[] buffer = new byte[(int) entity.length()];
			fin.read(buffer);
			out.write(buffer);
			fin.close();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	public void flush() {
		this.sendStatusLine();
		this.sendHeader();
		try {
			this.sendContent();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public String getMineTypeByEntity() {
		// 文件的扩展名
		int index = this.entity.getName().lastIndexOf(".");
		String name = this.entity.getName().substring(index + 1);
		if ("html".equals(name)) {
			return "text/html";
		} else if ("jpg".equals(name)) {
			return "image/jpg";
		} else if ("png".equals(name)) {
			return "image/png";
		} else if ("gif".equals(name)) {
			return "image/gif";
		}
		return "";
	}
}

第六个任务
设置媒体类型
1.在com.tedu.core中添加一个类HttpContext
该类用于定义相关Http协议的内容.
比如头信息中Content-Type的值与文件后缀的关系等.
1)在com.tedu.core包中定义HttpContext类
2)定义两个常量int CR = 13; int LF = 10;
3)定义介质的类型静态变量 Map<String,String> mimeTypeMapping;
4)定义方法private static void initMimeTypeMapping()
功能:初始化介质的类型
mimeTypeMapping = new HashMap<String,String>();
mimeTypeMapping.put(“html”, “text/html”);
mimeTypeMapping.put(“jpg”, “image/jpeg”);
mimeTypeMapping.put(“gif”, “image/gif”);
mimeTypeMapping.put(“png”, “image/png”);
5)定义public static String getContentTypeByMime(String mime)方法
功能:根据给定的介质类型获取对应的Content-Type的值
return mimeTypeMapping.get(mime);
6)定义初始化的方法public static void init()
功能:完成HTTPContext初始化的功能
//1 初始化介质类型映射
initMimeTypeMapping();
7)定义静态块
功能:HttpContext加载的时候开始初始化
static{
//HttpContext加载的时候开始初始化
init();
}
2.在HttpResponse中进行代码重构
1)添加一个Map属性,用于保存响应的所有响应头信息.
private Map<String,String> headers = new HashMap<String,String>();
2)添加常用头的设置方法,供外界设置响应头:
public void setContentType(String contentType){
//把内容类型添加到头信息中
//this.headers.put(“Content-Type”, contentType);
}
public void setContentLength(int length){
//把响应文件的长度添加到头信息中
this.headers.put(“Content-Length”, length+"");
}
3)重新实现sendHeaders方法
private void sendHeaders(){
Set set = headers.keySet();
for(String name:set){
String line = name+":"+headers.get(name);
print(line);//发送每一个头信息
}
print("");//单独发送CRLF表示头发送完毕
}
3.重构WebServer的run方法
String contentType = HttpContext.getContentTypeByMime(name);
//设置响应头:媒体类型和文件长度
//设置响应正文
//响应客户端
4.测试

public class WebServer {
	ServerSocket server;

	public WebServer() {
		try {
			server = new ServerSocket(8888);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public void start() {
		while (true) {
			Socket socket;
			try {
				while (true) {
					System.out.println("等待客户端的请求");
					socket = server.accept();
					new Thread(new ClientHandler(socket)).start();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	class ClientHandler implements Runnable {
		Socket socket;
		public ClientHandler() {
		}
		public ClientHandler(Socket socket) {
			this.socket = socket;
		}
		@Override
		public void run() {
			//  \r\n ASCⅡ 13 10
			System.out.println("接收客户端请求");
			//获取请求状态行
			try {
				InputStream in =  socket.getInputStream();
				OutputStream out = socket.getOutputStream();
				HttpRequest request =new HttpRequest(in);
				HttpResponse response = new HttpResponse(out);
//				System.out.println(request.getMethod());
//				System.out.println(request.getUrl());
//				System.out.println(request.getProtocol());
				File file = new File("webapps"+request.getUrl());
				//设置文档长度
				response.setContentLength((int)file.length());
				//设置文档类型
				int index  = file.getName().indexOf(".");
				String name = file.getName().substring(index+1);
				response.setContentType(HttpContext.getMimeType(name));
				//响应页面
				response.setEntity(file);
				//响应的文档内容
				response.flush();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) {
		new WebServer().start();
	}

}
public class HttpContext {
	public static final int CR = 13; 
	public static final int LF = 10;
	private static Map<String,String> map;
	
	static{
		//HttpContext加载的时候开始初始化
		init();
	}
	private static void initMimeType() {
		map = new HashMap<String,String>();
		map.put("html", "text/html");
		map.put("jpg", "image/jpeg");
		map.put("gif", "image/gif");
		map.put("png", "image/png");
	}
	public static String getMimeType(String key) {
		return map.get(key);
	}
	public static void init() {
		initMimeType();
	}
}
public class HttpRequest {
	public String method;
	public String url;
	public String protocol;
	public HttpRequest() {}
	public HttpRequest(InputStream in) {
		try {
			parseRequestLine(in);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public String getMethod() {
		return method;
	}
	public String getUrl() {
		return url;
	}
	public String getProtocol() {
		return protocol;
	}
	public void parseRequestLine(InputStream in) throws IOException {
		StringBuilder builder = new StringBuilder();
		char c1 = 0,c2 = 0;
		int d = -1;
		while((d=in.read())!=-1) {
			c2 = (char)d;
			//解析第一行,遇到 \r\n,break
			if(c1 == 13 && c2 == 10) {
				break;
			}
			builder.append(c2);
			c1 = c2;
		}
		String str = builder.toString().trim();
		String[] data = str.split(" ");
		this.method = data[0];//获取请求方式get
		this.url = data[1];//url请求
		this.protocol = data[2];//协议名称
	}
}
public class HttpResponse {
	OutputStream out;
	File entity;
	private Map<String,String> headers = new HashMap<>();
	
	public HttpResponse(OutputStream out) {
		this.out = out;
	}
	public void setContentType(String contentType){
		//把内容类型添加到头信息中
		//this.headers.put("Content-Type", contentType);
		headers.put("Content-Type",contentType);
		
	}
	
	public void setContentLength(int length){
		//把响应文件的长度添加到头信息中
		//this.headers.put("Content-Length", length+"");
		headers.put("Content-Length", length+"");
	}
	public File getEntity() {
		return entity;
	}

	public void setEntity(File entity) {
		this.entity = entity;
	}

	public void println(String line) {
		try {
			out.write(line.getBytes());
			out.write(13);
			out.write(10);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	//遍历响应头信息
	private void sendHeaders(){
		Set<String> keys = headers.keySet();
		for(String key:keys){
			String str = key+":"+headers.get(key);
			println(str);//发送每一个头信息
		}
		println("");//单独发送CRLF表示头发送完毕
	
	}
	public void sendStatusLine() {
		String line = "HTTP/1.1 200 OK";
		this.println(line);
	}

	public void sendHeader() {
		Set<String> keys = headers.keySet();
		for(String key:keys){
			String str =key+":"+headers.get(key);
			this.println(str);
		}
		this.println("");
	}

	public void sendContent() throws IOException {
		try {
			FileInputStream fin = new FileInputStream(entity);

			byte[] buffer = new byte[(int) entity.length()];
			fin.read(buffer);
			out.write(buffer);
			fin.close();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}

	}

	public void flush() {
		this.sendStatusLine();
		this.sendHeader();
		try {
			this.sendContent();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

第七个任务:
完成HttpRequest中对消息头的解析工作
1.HttpRequest中使用Map创建一个属性headers,用于保存所有客户端发送过来的消息头信息
private Map<String,String> headers = new HashMap<String,String>();
2.添加方法parseHeaders,用于解析所有的消息头.
String line = readLine(in);
//读到空行,表示消息头读完毕
if("".equals(line)){
break;
}
3.封装方法readLine()
private String readLine(InputStream in) throws IOException

public class WebServer {
	ServerSocket server;

	public WebServer() {
		try {
			server = new ServerSocket(8888);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void start() {
		while (true) {
			Socket socket;
			try {
				while (true) {
					System.out.println("等待客户端的请求");
					socket = server.accept();
					new Thread(new ClientHandler(socket)).start();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	class ClientHandler implements Runnable {
		Socket socket;
		public ClientHandler() {
		}
		public ClientHandler(Socket socket) {
			this.socket = socket;
		}
		@Override
		public void run() {
			//  \r\n ASCⅡ 13 10
			System.out.println("接收客户端请求");
			//获取请求状态行
			try {
				InputStream in =  socket.getInputStream();
				OutputStream out = socket.getOutputStream();
				HttpRequest request =new HttpRequest(in);
				HttpResponse response = new HttpResponse(out);

				//测试获取请求头信息
				System.out.println(request.getHeads());
				
				File file = new File("webapps"+request.getUrl());
				//设置文档长度
				response.setContentLength((int)file.length());
				//设置文档类型
				int index  = file.getName().indexOf(".");
				String name = file.getName().substring(index+1);
				response.setContentType(HttpContext.getMimeType(name));
				//响应页面
				response.setEntity(file);
				//响应的文档内容
				response.flush();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	public static void main(String[] args) {
		new WebServer().start();
	}
}

public class HttpContext {
	public static final int CR = 13; 
	public static final int LF = 10;
	private static Map<String,String> map;
	
	static{
		//HttpContext加载的时候开始初始化
		init();
	}
	private static void initMimeType() {
		map = new HashMap<String,String>();
		map.put("html", "text/html");
		map.put("jpg", "image/jpeg");
		map.put("gif", "image/gif");
		map.put("png", "image/png");
	}
	public static String getMimeType(String key) {
		return map.get(key);
	}
	public static void init() {
		initMimeType();
	}
}

public class HttpRequest {
	public String method;
	public String url;
	public String protocol;
	private Map<String ,String> header = new HashMap<>();
	public HttpRequest() {}
	public HttpRequest(InputStream in) {
		try {
			parseRequestLine(in);
			parseRequestHeaders(in);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public String getMethod() {
		return method;
	}
	public String getUrl() {
		return url;
	}
	public String getProtocol() {
		return protocol;
	}
	public void parseRequestHeaders(InputStream in)  throws IOException {
		while(true) {
			String str = this.readLine(in);
			if("".equals(str)) {
				break;
			}
			String[] data = str.split(": ");
			header.put(data[0],data[1]);
		}
	}
	
	public void parseRequestLine(InputStream in) throws IOException {
		String[] data = this.readLine(in).split(" ");
		if(data.length==3) {
			this.method = data[0];//获取请求方式get
			this.url = data[1];//url请求
			this.protocol = data[2];//协议名称
		}
	}
	public  String readLine(InputStream in) throws IOException{
		StringBuilder builder = new StringBuilder();
		char c1 = 0,c2 = 0;
		int d = -1;
		while((d=in.read())!=-1) {
			c2 = (char)d;
			//解析第一行,遇到 \r\n,break
			if(c1 == 13 && c2 == 10) {
				break;
			}
			builder.append(c2);
			c1 = c2;
		}
		String str = builder.toString().trim();
		return str;
	}
	public Map<String,String> getHeads(){
		return header;
	}
}

public class HttpResponse {
	OutputStream out;
	File entity;
	private Map<String,String> headers = new HashMap<>();
	
	public HttpResponse(OutputStream out) {
		this.out = out;
	}
	public void setContentType(String contentType){
		//把内容类型添加到头信息中
		//this.headers.put("Content-Type", contentType);
		headers.put("Content-Type",contentType);
		
	}	
	public void setContentLength(int length){
		//把响应文件的长度添加到头信息中
		//this.headers.put("Content-Length", length+"");
		headers.put("Content-Length", length+"");
	}
	public File getEntity() {
		return entity;
	}

	public void setEntity(File entity) {
		this.entity = entity;
	}

	public void println(String line) {
		try {
			out.write(line.getBytes());
			out.write(13);
			out.write(10);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	//遍历响应头信息
	private void sendHeaders(){
		Set<String> keys = headers.keySet();
		for(String key:keys){
			String str = key+":"+headers.get(key);
			println(str);//发送每一个头信息
		}
		println("");//单独发送CRLF表示头发送完毕
	
	}
	public void sendStatusLine() {
		String line = "HTTP/1.1 200 OK";
		this.println(line);
	}
	public void sendHeader() {
		Set<String> keys = headers.keySet();
		for(String key:keys){
			String str =key+":"+headers.get(key);
			this.println(str);
		}
		this.println("");
	}
	public void sendContent() throws IOException {
		try {
			FileInputStream fin = new FileInputStream(entity);

			byte[] buffer = new byte[(int) entity.length()];
			fin.read(buffer);
			out.write(buffer);
			fin.close();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	public void flush() {
		this.sendStatusLine();
		this.sendHeader();
		try {
			this.sendContent();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

第八个任务:完成注册的功能
1.重构HttpRequest类
1)添加成员变量
//请求信息
private String requestLine;
//请求所附带的所有参数
private Map<String,String> params = new HashMap<String,String>();
2)定义paresUri():
功能完成:判读是否有?,如果有解析出来方法map集合中
public void parseUil(){
//1.判断是否有?
int index = this.url.indexOf("?");
//2.如果没有,那么requestLine = url;
if(index==-1){
requestLine = url;
}else{
//3.如果有:
//requestLine = url?之前的值
requestLine = url.substring(0,index);
//把?后边的数据解析出来,设置到params集合中
}
}
3)在parseRquestLine方法中调用

//请求的url
url = data[1];
//调用paresUri方法
parseUil();

4)定义getParameter方法,和getRequestLine
2.重构run方法
如果myweb/reg
处理注册功能,响应页面到客户端
public void run() {
try {

if("/myweb/register".equals(request.getRequestLine())){
String username = request.getParameter(“name”);
String pw = request.getParameter(“pw”);
//把数据写到数据文件
//admin&123456 PrintWriter
//响应一个视图
/myweb/registerok.html
}else{

}
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
3.定义forward方法,响应视图
public void forward(String uri,HttpResonse response)
4.测试:http://localhost:8080/myweb/reg.html

public class WebServer {
	ServerSocket server;
	public WebServer() {
		try {
			server = new ServerSocket(8888);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public void start() {
		while (true) {
			Socket socket;
			try {
				while (true) {
					System.out.println("等待客户端的请求");
					socket = server.accept();
					new Thread(new ClientHandler(socket)).start();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	class ClientHandler implements Runnable {
		Socket socket;
		public ClientHandler() {
		}
		public ClientHandler(Socket socket) {
			this.socket = socket;
		}
		@Override
		public void run() {
			// \r\n ASCⅡ 13 10
			System.out.println("接收客户端请求");
			// 获取请求状态行
			try {
				InputStream in = socket.getInputStream();
				OutputStream out = socket.getOutputStream();
				HttpRequest request = new HttpRequest(in);
				HttpResponse response = new HttpResponse(out);
				// 测试获取请求头信息
//				System.out.println(request.getHeads());
				if ("/myweb/register".equals(request.getRequestUrl())) {
					String username = request.getParameter("name");
					String pw = request.getParameter("pw");
					System.out.println(username + "," + pw);
					// 保存数据,使用数据文件
					PrintWriter printwriter = new PrintWriter(new FileOutputStream("user.txt", true));
					printwriter.println(username + "&" + pw);
					printwriter.flush();
					printwriter.close();
					fileResponse("/myweb/registerOK.html", response);
				} else {
					fileResponse(request.getUrl(), response);
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	public void fileResponse(String uri, HttpResponse response) {
		File file = new File("webapps" + uri);
		// 设置文档长度
		response.setContentLength((int) file.length());
		// 设置文档类型
		int index = file.getName().indexOf(".");
		String name = file.getName().substring(index + 1);
		response.setContentType(HttpContext.getMimeType(name));
		// 响应页面
		response.setEntity(file);
		// 响应的文档内容
		response.flush();
	}
	public static void main(String[] args) {
		new WebServer().start();
	}
}

public class HttpContext {
	public static final int CR = 13; 
	public static final int LF = 10;
	private static Map<String,String> map;
	
	static{
		//HttpContext加载的时候开始初始化
		init();
	}
	private static void initMimeType() {
		map = new HashMap<String,String>();
		map.put("html", "text/html");
		map.put("jpg", "image/jpeg");
		map.put("gif", "image/gif");
		map.put("png", "image/png");
	}
	public static String getMimeType(String key) {
		return map.get(key);
	}
	public static void init() {
		initMimeType();
	}
}

public class HttpRequest {
	public String method;
	public String url;
	public String protocol;
	private Map<String ,String> header = new HashMap<>();
	private String requestUrl;
	private Map<String,String> params = new HashMap<String,String>();
	public HttpRequest() {}
	public HttpRequest(InputStream in) {
		try {
			parseRequestLine(in);
			parseRequestHeaders(in);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	//解析url,封装请求参数
	public void parseUrl() {
		//判断是否有?
		int index = this.url.indexOf("?");
		if(index == -1) {
			this.requestUrl = url;
		}else {
			//1、?前 this.request = url
			this.requestUrl = url.substring(0,index);
			//2、?后 map
			String parameters = url.substring(index+1);
			String[] values = parameters.split("&");
			for(String str : values) {
				//name = admin   pw=123456
				String[] data = str.split("=");
				if(data.length == 2) {
					params.put(data[0], data[1]);
				}else {
					params.put(data[0],"");
				}
			}
		}
	}
	public String getMethod() {
		return method;
	}
	public String getUrl() {
		return url;
	}
	public String getProtocol() {
		return protocol;
	}
	public void parseRequestHeaders(InputStream in)  throws IOException {
		while(true) {
			String str = this.readLine(in);
			if("".equals(str)) {
				break;
			}
			String[] data = str.split(": ");
			header.put(data[0],data[1]);
		}
	}
	public void parseRequestLine(InputStream in) throws IOException {
		String[] data = this.readLine(in).split(" ");
		if(data.length == 3) {
			this.method = data[0];//获取请求方式get
			this.url = data[1];//url请求
			this.parseUrl();
			this.protocol = data[2];//协议名称
		}
	}
	public  String readLine(InputStream in) throws IOException{
		StringBuilder builder = new StringBuilder();
		char c1 = 0,c2 = 0;
		int d = -1;
		while((d=in.read())!=-1) {
			c2 = (char)d;
			//解析第一行,遇到 \r\n,break
			if(c1 == 13 && c2 == 10) {
				break;
			}
			builder.append(c2);
			c1 = c2;
		}
		String str = builder.toString().trim();
		return str;
	}
	public Map<String,String> getHeads(){
		return header;
	}
	public String getParameter(String key) {
		return  params.get(key);
	}
	public String getRequestUrl() {
		return requestUrl;
	}
}

public class HttpResponse {
	OutputStream out;
	File entity;
	private Map<String,String> headers = new HashMap<>();
	public HttpResponse(OutputStream out) {
		this.out = out;
	}
	public void setContentType(String contentType){
		//把内容类型添加到头信息中
		//this.headers.put("Content-Type", contentType);
		headers.put("Content-Type",contentType);
	}
	public void setContentLength(int length){
		//把响应文件的长度添加到头信息中
		//this.headers.put("Content-Length", length+"");
		headers.put("Content-Length", length+"");
	}
	public File getEntity() {
		return entity;
	}
	public void setEntity(File entity) {
		this.entity = entity;
	}
	public void println(String line) {
		try {
			out.write(line.getBytes());
			out.write(13);
			out.write(10);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	//遍历响应头信息
	private void sendHeaders(){
		Set<String> keys = headers.keySet();
		for(String key:keys){
			String str = key+":"+headers.get(key);
			println(str);//发送每一个头信息
		}
		println("");//单独发送CRLF表示头发送完毕
	
	}
	public void sendStatusLine() {
		String line = "HTTP/1.1 200 OK";
		this.println(line);
	}

	public void sendHeader() {
		Set<String> keys = headers.keySet();
		for(String key:keys){
			String str =key+":"+headers.get(key);
			this.println(str);
		}
		this.println("");
	}
	public void sendContent() throws IOException {
		try {
			FileInputStream fin = new FileInputStream(entity);
			byte[] buffer = new byte[(int) entity.length()];
			fin.read(buffer);
			out.write(buffer);
			fin.close();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}

	}
	public void flush() {
		this.sendStatusLine();
		this.sendHeader();
		try {
			this.sendContent();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

第九个任务:
解析介质文件web.xml
重构:HTTPContext类的 initMimeTypeMapping方法
private static void initMimeTypeMapping()throws DocumentException{
/*
* 解析conf/web.xml文档
* 将根标签中所有的标签读取出来
* 将其中的子标签中的内容作为key
* 将其中的子标签中的内容作为value
* 存入到mimeTypeMapping中即可
*/
}
测试:
public static void main(String args[]){
System.out.println(getMimeType(“afp”));
}

public class WebServer {
	ServerSocket server;
	public WebServer() {
		try {
			server = new ServerSocket(8888);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	public void start() {
		while (true) {
			Socket socket;
			try {
				while (true) {
					System.out.println("等待客户端的请求");
					socket = server.accept();
					new Thread(new ClientHandler(socket)).start();
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	class ClientHandler implements Runnable {
		Socket socket;
		public ClientHandler() {
		}
		public ClientHandler(Socket socket) {
			this.socket = socket;
		}
		@Override
		public void run() {
			// \r\n ASCⅡ 13 10
			System.out.println("接收客户端请求");
			// 获取请求状态行
			try {
				InputStream in = socket.getInputStream();
				OutputStream out = socket.getOutputStream();
				HttpRequest request = new HttpRequest(in);
				HttpResponse response = new HttpResponse(out);
				// 测试获取请求头信息
//				System.out.println(request.getHeads());
				if ("/myweb/register".equals(request.getRequestUrl())) {
					String username = request.getParameter("name");
					String pw = request.getParameter("pw");
					System.out.println(username + "," + pw);
					// 保存数据,使用数据文件
					PrintWriter printwriter = new PrintWriter(new FileOutputStream("user.txt", true));
					printwriter.println(username + "&" + pw);
					printwriter.flush();
					printwriter.close();	
					fileResponse("/myweb/registerOK.html", response);
				} else {
					fileResponse(request.getUrl(), response);
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	public void fileResponse(String uri, HttpResponse response) {
		File file = new File("webapps" + uri);
		// 设置文档长度
		response.setContentLength((int) file.length());
		// 设置文档类型
		int index = file.getName().indexOf(".");
		String name = file.getName().substring(index + 1);
		response.setContentType(HttpContext.getMimeType(name));
		// 响应页面
		response.setEntity(file);
		// 响应的文档内容
		response.flush();
	}
	public static void main(String[] args) {
		new WebServer().start();
	}
}

public class HttpContext {
	public static final int CR = 13;
	public static final int LF = 10;
	private static Map<String, String> map;

	static {
		// HttpContext加载的时候开始初始化
		init();
	}
	private static void initMimeType() {
		map = new HashMap<String, String>();
		/*
		 * 解析conf/web.xml文档 将根标签中所有的<mime-mapping>标签读取出来 将其中的子标签<extension>中的内容作为key
		 * 将其中的子标签<mime-type>中的内容作为value 存入到mimeTypeMapping中即可
		 */
		SAXReader reader = new SAXReader();
		Document document;
		try {
			document = reader.read(new File("config/web.xml"));
			Element rootElement = document.getRootElement();
			Iterator<Element> it1 = rootElement.elementIterator();
			while (it1.hasNext()) {
				Element element = it1.next();
				if (element.getName().equals("mime-mapping")) {
					Iterator<Element> it2 = element.elementIterator();
					String key = "";
					String value = "";
					while (it2.hasNext()) {
						Element element2 = it2.next();
						if (element2.getName().equals("extension")) {
							key = element2.getText();
						}
						if (element2.getName().equals("mime-type")) {
							value = element2.getText();
						}
					}
					map.put(key, value);
				}
			}
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public static String getMimeType(String key) {
		return map.get(key);
	}
	public static void init() {
		initMimeType();
	}
}

public class HttpRequest {
	public String method;
	public String url;
	public String protocol;
	private Map<String ,String> header = new HashMap<>();
	private String requestUrl;
	private Map<String,String> params = new HashMap<String,String>();
	public HttpRequest() {}
	public HttpRequest(InputStream in) {
		try {
			parseRequestLine(in);
			parseRequestHeaders(in);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	//解析url,封装请求参数
	public void parseUrl() {
		//判断是否有?
		int index = this.url.indexOf("?");
		if(index == -1) {
			this.requestUrl = url;
		}else {
			//1、?前 this.request = url
			this.requestUrl = url.substring(0,index);
			//2、?后 map
			String parameters = url.substring(index+1);
			String[] values = parameters.split("&");
			for(String str : values) {
				//name = admin   pw=123456
				String[] data = str.split("=");
				if(data.length == 2) {
					params.put(data[0], data[1]);
				}else {
					params.put(data[0],"");
				}
			}
		}
	}
	public String getMethod() {
		return method;
	}
	public String getUrl() {
		return url;
	}
	public String getProtocol() {
		return protocol;
	}
	public void parseRequestHeaders(InputStream in)  throws IOException {
		while(true) {
			String str = this.readLine(in);
			if("".equals(str)) {
				break;
			}
			String[] data = str.split(": ");
			header.put(data[0],data[1]);
		}
	}
	public void parseRequestLine(InputStream in) throws IOException {
		String[] data = this.readLine(in).split(" ");
		if(data.length == 3) {
			this.method = data[0];//获取请求方式get
			this.url = data[1];//url请求
			this.parseUrl();
			this.protocol = data[2];//协议名称
		}
	}
	public  String readLine(InputStream in) throws IOException{
		StringBuilder builder = new StringBuilder();
		char c1 = 0,c2 = 0;
		int d = -1;
		while((d=in.read())!=-1) {
			c2 = (char)d;
			//解析第一行,遇到 \r\n,break
			if(c1 == 13 && c2 == 10) {
				break;
			}
			builder.append(c2);
			c1 = c2;
		}
		String str = builder.toString().trim();
		return str;
	}
	public Map<String,String> getHeads(){
		return header;
	}
	public String getParameter(String key) {
		return  params.get(key);
	}
	public String getRequestUrl() {
		return requestUrl;
	}
}

public class HttpResponse {
	OutputStream out;
	File entity;
	private Map<String,String> headers = new HashMap<>();
	public HttpResponse(OutputStream out) {
		this.out = out;
	}
	public void setContentType(String contentType){
		//把内容类型添加到头信息中
		//this.headers.put("Content-Type", contentType);
		headers.put("Content-Type",contentType);	
	}
	public void setContentLength(int length){
		//把响应文件的长度添加到头信息中
		//this.headers.put("Content-Length", length+"");
		headers.put("Content-Length", length+"");
	}
	public File getEntity() {
		return entity;
	}
	public void setEntity(File entity) {
		this.entity = entity;
	}
	public void println(String line) {
		try {
			out.write(line.getBytes());
			out.write(13);
			out.write(10);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	//遍历响应头信息
	private void sendHeaders(){
		Set<String> keys = headers.keySet();
		for(String key:keys){
			String str = key+":"+headers.get(key);
			println(str);//发送每一个头信息
		}
		println("");//单独发送CRLF表示头发送完毕
	}
	public void sendStatusLine() {
		String line = "HTTP/1.1 200 OK";
		this.println(line);
	}
	public void sendHeader() {
		Set<String> keys = headers.keySet();
		for(String key:keys){
			String str =key+":"+headers.get(key);
			this.println(str);
		}
		this.println("");
	}
	public void sendContent() throws IOException {
		try {
			FileInputStream fin = new FileInputStream(entity);

			byte[] buffer = new byte[(int) entity.length()];
			fin.read(buffer);
			out.write(buffer);
			fin.close();
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}
	public void flush() {
		this.sendStatusLine();
		this.sendHeader();
		try {
			this.sendContent();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值