第五个任务:
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();
}
}
}