response用法 response

我们经常使用别人的服务器进行构建网站 , 现在我们就自己来写一个自己的服务来使用 。
准备工作:下载所需的题材及文档
注:完整项目下载
一、request请求获取
1、了解request请求
在写服务器之前 , 我们需要知道客户端发送给我们哪些信息?以及要求我们返回哪些信息?经过测试我们能够知道用户客户端发送的信息有以下几点:
客户端发送到服务器端的请求消息,我们称之为请求(request),其实就是一个按照http协议的规则拼接而成的字符串 , Request请求消息包含三部分: 请求行 消息报头 请求正文
第一部 请求行
格式:
Method Request-URI HTTP-Version CRLF
各部分分别为:
Method表示请求方法;一般为GET或者POST ;Request-URI是一个统一资源标识符; HTTP-Version表示请求的HTTP协议版本; CRLF表示回车和换行
例如:
GET /test.html HTTP/1.1
第二部 消息报头 http header
例如:
GET /test.html HTTP/1.1
Host: 127.0.0.1:9999
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,en;q=0.8,zh;q=0.5,en-US;q=0.3
Accept-Encoding: gzip, deflate
Connection: keep-alive
第三部 请求正文 http body
请求头和请求正文之间是一个空行 , 这个行非常重要 , 它表示请求头已经结束 , 接下来的是请求正文 。请求正文中可以包含客户提交的字符串信息
注意:在第二部分header和第三部分body之间有个空行,除非没有请求正文(如果你想要亲自看到效果 , 请参考:浏览器中GET和POST的区别) , 这是因为用户在浏览网页时提交给服务器的信息是不同的
2、实现
经过以上分析 , 我们就能够清楚的知道 , 客户端发送给服务器的请求 , 请求信息有使用的协议、请求的方法、请求的资源路径、请求的消息报头、判断请求的内容是否为静态资源、判断请求的内容是否为动态资源、判断是否为空请求 , 为了使用的方便 , 我们需要将其封装起来 , 总不能使用一次读取一次吧 , 这样做实在是太浪费系统资源与时间了 , 如下代码 , 就是一个接口类 , 用于获取客户端发送过来的属性
package com.sample.http;import java.util.Map; // http协议的请求public interface HttpRequest { //获得请求的协议 public String getProtocol(); //获得请求的方法 public String getRequestMethod(); //获得请求的路径 public String getRequestPath(); //获得请求的消息报头 public Map<String,String> getRequestHeader(); //根据参数的名字获得请求带过来的参数值 public String getParameter(String parameterName); //判断当前请求的否是静态资源 public boolean isStaticResource(); //判断当前请求的否是动态资源 public boolean isDynamicResource(); //判断当前请求的否是为空请求(有些浏览器会自动发送空请求) public boolean isNullRequest();}有了接口类之后 , 我们就可以创建类进行实现 , 下面就是实现类 , 用于对各个方法进行处理:
package com.sample.http;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.net.Socket;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Map.Entry;import java.util.Set;public class HttpRequestImpl implements HttpRequest{ //客户端的Socket private Socket s; private InputStream is=null;//输入流 private BufferedReader br=null; private HashMap<String,String> hmHeader=new HashMap<String,String>();//消息报头 private HashMap<String,String> hmparameters=new HashMap<String, String>();//参数集合 private boolean isNullRequest=false;//是否为空请求 , 默认false private String protocol=null;//请求协议 private String requestMethod=null;//请求方法 private String requestPath=null;//请求路径 public HttpRequestImpl(Socket s) {this.s=s;getInfos();//调用方法} private void getInfos()//定义一个方法 , 用于处理获取的客户端信息 {try {is=s.getInputStream();br=new BufferedReader(new InputStreamReader(is));//解析第一行String str;str=br.readLine();//readLine使用回车换行判断一行是否结束if(str==null){isNullRequest=true;return;}parseRequestMethodPathProtocol(str);//调用自己创建在本类里边的方法处理第一行信息 , 方法在后面//解析第二行---第八行String header=null;//判断是否结束 , 如果结束就退出 , 这里的判断按较为饶人 //首先应该明确br.readLine()的内容 , 当为true是对应的情况 //也就是说当“”(中间没有空格)与br.readLine()相等时 , 就进入到while中 while(!"".equals((header=br.readLine()))){parseRequestHeader(header);}//post和getif(br.ready())//post//POST提交方式判断 , 如果还有下一行就继续读取信息{char[] buf=new char[1024];int len=br.read(buf);//使用字节进行读取 , 因为这一行没有回车换行 , readLine无法判断是否结束String parameter=new String(buf,0,len);parseRequestParamByPost(parameter);//调用自己创建在本类里边的方法处理POST方式提交的正文信息}else{//get,get参数的位置在第一行连接处parseRequestParamByGet(requestPath);//调用自己创建在本类里边的方法处理GET方式提交的正文信息}} catch (Exception e) {e.printStackTrace();} } //GET方法处理 private void parseRequestParamByGet(String requestPath2) {String []str1=requestPath2.split("[?]");//使用“?”分割字符串if(str1.length==2){parseRequestParamByPost(str1[1]);}this.requestPath=str1[0]; } //POST方法处理 private void parseRequestParamByPost(String parameter) {String[] strs=parameter.split("&");if(strs.length>=1){for(String str:strs){String [] sp=str.split("="); hmparameters.put(sp[0],sp[1]);}} } //解析第二行到第八行 private void parseRequestHeader(String header) throws Exception{String[] headHost=header.split(": ");if(headHost.length!=2){throw new Exception("消息报头异常 , 请重新提交");}hmHeader.put(headHost[0],headHost[1]); } //解析第一行 private void parseRequestMethodPathProtocol(String str) throws Exception {String[] protocolMethodPath=new String[3];//由于第一行含有三个内容 , 分割后需要三个String存储protocolMethodPath=str.split(" ");//使用空格分割if(protocolMethodPath.length==3){requestMethod=protocolMethodPath[0];requestPath=protocolMethodPath[1];protocol=protocolMethodPath[2];}else{throw new Exception("首行参数不合适 , 请重新提交");} } //获得请求的协议 public String getProtocol() {return protocol; } //获得请求的方法 public String getRequestMethod(){return requestMethod; } //获得请求的路径 public String getRequestPath(){return requestPath; } //获得请求的消息报头 public Map<String,String> getRequestHeader(){return this.hmHeader; } //根据参数的名字获得请求带过来的参数值 public String getParameter(String parameterName){return hmparameters.get(parameterName); } //判断当前请求的否是静态资源 public boolean isStaticResource(){return true; } //判断当前请求的否是动态资源 public boolean isDynamicResource(){return true; } //判断当前请求的否是为空请求(有些浏览器会自动发送空请求) public boolean isNullRequest(){ return isNullRequest; }}

秒懂生活扩展阅读