Java_203_手写webserver_引入Servlet

package pk2;

public class LoginServlet implements Servlet{
	@Override
	public void service(Request request,Response response) {
		response.print("<html>");
		response.print("<haed>");
		response.print("<title>");
		response.print("服务器响应成功");
		response.print("</title>");
		response.print("</haed>");
		response.print("<body>");
		response.print("登录成功,欢迎回来2020 "+request.getParameter("name")+request.getParameter("pwd"));
		response.print("<form method=\"get\" action=\"http://localhost:8889\">用户名:<input type=\"text\" name=\"name\" id=\"uname\"/>密码:<input type=\"password\" name=\"pwd\" id=\"pwd\"/><input type=\"submit\" value=\"GET\"/></form>");
		response.print("<br>");
		response.print("<form method=\"post\" action=\"http://localhost:8889?aaabbb=ccc\">用户名:<input type=\"text\" name=\"name\" id=\"uname\"/>密码:<input type=\"password\" name=\"pwd\" id=\"pwd\"/><input type=\"submit\" value=\"POST\"/></form>");
		response.print("</body>");
		response.print("</html>");
	}

}
package pk2;

public class RegisterServlet implements Servlet{

	@Override
	public void service(Request request,Response response) {
		response.print("<html>");
		response.print("<haed>");
		response.print("<title>");
		response.print("服务器响应成功");
		response.print("</title>");
		response.print("</haed>");
		response.print("<body>");
		response.print("注册成功,欢迎回来2020 "+request.getParameter("name")+request.getParameter("pwd"));
		response.print("<form method=\"get\" action=\"http://localhost:8889\">用户名:<input type=\"text\" name=\"name\" id=\"uname\"/>密码:<input type=\"password\" name=\"pwd\" id=\"pwd\"/><input type=\"submit\" value=\"GET\"/></form>");
		response.print("<br>");
		response.print("<form method=\"post\" action=\"http://localhost:8889?aaabbb=ccc\">用户名:<input type=\"text\" name=\"name\" id=\"uname\"/>密码:<input type=\"password\" name=\"pwd\" id=\"pwd\"/><input type=\"submit\" value=\"POST\"/></form>");
		response.print("</body>");
		response.print("</html>");
	}

}
package pk2;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 封装请求协议:封装请求参数为Map
 * 
 * @author pmc
 *
 */
public class Request {
	//协议信息
	private String requestinfo;
	//请求方式
	private String method;
	//请求URL
	private String url;
	//请求参数
	private String queryStr;
	//存储参数
	private Map<String,List<String>> parameterMap; 
	//换行符
	private String CRLF="\r\n";
	public Request(Socket client) throws IOException {
		this(client.getInputStream());
	}
	public Request(InputStream in) {
		parameterMap=new HashMap<String,List<String>>();
		byte[] datas = new byte[1024 * 1024];
		int len;
		try {
			len = in.read(datas);
			requestinfo = new String(datas, 0, len);
		} catch (IOException e) {
			e.printStackTrace();
			return;
		}
		//分解字符串
		parseRequestinfo();
	}
	private void parseRequestinfo(){
		System.out.println("分解开始");
		System.out.println(requestinfo);
		System.out.println("1.获取请求方式:开头到第一个/");
		//GET、POST
		this.method=this.requestinfo.substring(0,this.requestinfo.indexOf("/")).toLowerCase();
		this.method=this.method.trim();
		System.out.println("2.获取请求url:第一个/到HTTP/,可能包含请求参数?前面的url");
		//1.获取/的位置
		int startidx=this.requestinfo.indexOf("/")+1;//不要/+1
		//2.获取HTTP/的位置
		int endidx=this.requestinfo.indexOf("HTTP/");//不要/+1
		//3.分割字符串
		//URL
		this.url=this.requestinfo.substring(startidx, endidx);
		//4.获取?的位置
		//queryStr请求参数
		int queryidx=this.url.indexOf("?");
		if(queryidx>=0){
			String[] str=this.url.split("\\?");//需要转义\\
			this.url=str[0];
			this.queryStr=decode(str[1], "GBK");
		}
		System.out.println("3.获取请求参数:如果GET已经获取,如果是POST可能在请求体中");
		if(method.equals("post")){
//			System.out.println(queryStr);
			String qStr = this.requestinfo.substring(this.requestinfo.lastIndexOf(CRLF)).trim();
			if(queryStr==null){
				queryStr=qStr;
			}else{
				queryStr+="&"+qStr;//地址栏有参数+表单参数
			}
		}
		queryStr=null==queryStr?"":queryStr;
		System.out.println("method:"+method+"-->"+"url:"+url+"-->"+"queryStr:"+queryStr);
		//转成Map name=1&pwd=2
		convertMap();
	}
	//处理请求参数为Map
	private void convertMap(){
		//1.'&'分割字符串
		String[] keyValues=this.queryStr.split("&");
		for(String temp:keyValues){
			//2.'='分割字符串
			String[] kv=temp.split("=");
			kv=Arrays.copyOf(kv, 2);
			//获取key和value
			String key=kv[0];
			String value=kv[1]==null?null:decode(kv[1],"GBK");
			//存储到map中
			if(!parameterMap.containsKey(key)){
				parameterMap.put(key, new ArrayList<String>());
			}
			parameterMap.get(key).add(value);
		}
	}
	//处理中文
	private String decode(String value,String Unicode){
		try {
			return java.net.URLDecoder.decode(value,Unicode);//Unicode 指定字符集
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} 
		return null;
	}
	//通过name获取对应的多个值
	public String[] getParameterValues(String key){
		List<String> list=this.parameterMap.get(key);
		if(list==null||list.size()<1){
			return null;
		}
		return list.toArray(new String[0]);
	}
	//通过name获取对应的一个值
	public String getParameter(String key){
		String [] values=getParameterValues(key);
		return values==null?null:values[0];
	}
	public String getMethod() {
		return method;
	}
	public String getUrl() {
		return url;
	}
	public String getQueryStr() {
		return queryStr;
	}
	
}
package pk2;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Date;

public class Response {
	private BufferedWriter bw;
	// 正文
	private StringBuilder content;
	// 协议头信息(状态行与请求头,回车)
	private StringBuilder headinfo;
	private int len;
	private final String BLANK = " ";
	private final String CRLF = "\r\n";

	private Response() {
		content = new StringBuilder();
		headinfo = new StringBuilder();
		len = 0;
	}

	public Response(Socket client) {
		this();
		try {
			bw = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
		} catch (IOException e) {
			e.printStackTrace();
			headinfo = null;
		}
	}

	public Response(OutputStream out) {
		bw = new BufferedWriter(new OutputStreamWriter(out));
	}

	// 动态添加内容
	public Response print(String info) {
		// 3.正文
		content.append(info);
		len += info.getBytes().length;
		return this;
	}

	public Response println(String info) {
		content.append(info).append(CRLF);
		len += (info + CRLF).getBytes().length;
		return this;
	}

	// 构建头信息
	private void createHeadInfo(int code) {
		// 1.响应行
		headinfo.append("HTTP/1.1").append(BLANK);
		headinfo.append(code).append(BLANK);
		switch (code) {
		case 200:
			headinfo.append("OK").append(CRLF);
			break;
		case 404:
			headinfo.append("NOT FOUND").append(CRLF);
			break;
		case 505:
			headinfo.append("SERVER ERROR").append(CRLF);
			break;
		}
		// 2.响应头
		headinfo.append("Date:").append(new Date()).append(CRLF);
		headinfo.append("Server:").append("pmcse Server/0.0.1;charset=GBK").append(CRLF);
		headinfo.append("Content-type:text/html").append(CRLF);
		headinfo.append("Content-length:").append(len).append(CRLF);
		headinfo.append(CRLF);
	}

	// 推送响应信息
	public void pushToBrowser(int code) throws IOException {
		if (headinfo == null) {
			code=505;
		}
		createHeadInfo(code);
		bw.append(headinfo);//头信息
		bw.append(content);//正文
		bw.flush();
	}
}
package pk2;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

/**
 * 加入了Servlet解耦了业务代码
 *
 */
public class Server6 {
	private ServerSocket serversocket;
	public static void main(String[] args){
//		System.out.println("启动服务");
		Server6 server=new Server6();
		server.start();
	}
	//启动
	public void start(){
		try {
			serversocket=new ServerSocket(8889);
			this.receive();
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("服务器启动失败。");
		}
	}
	//停止服务
	public void stop(){
		
	}
	//接收连接
	public void receive(){
		try {
		Socket client=	serversocket.accept();
		System.out.println("一个客户端建立连接。");
		//获取请求协议
		Request request=new Request(client);
		//返回数据
		Response response=new Response(client);

		Servlet servlet=null;
		if(request.getUrl().equals("login")){
			servlet= new LoginServlet();
		}else if(request.getUrl().equals("reg")){
			servlet=new RegisterServlet();
		}else{
			//首页
		}
		servlet.service(request, response);
		//写到客户端
		response.pushToBrowser(200);//状态写出开关
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("连接失败。");
		}
	}
}
package pk2;
/**
 * 服务器小脚本接口
 * @author pmc
 *
 */
public interface Servlet {
	void service(Request request,Response response);
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr_Pmc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值