HttpRequest 的解析(1)
从上文中(https://blog.csdn.net/qq_34861102/article/details/80098513)中已经提到对于每一个HttpRequest
要使用一个HttpProcessor
用来进行解析,而对于HttpProcessor
首先要完成对于传入参数的解析
这里实现一个简易的解析
- 首先自己写一个打印流的函数,观察输入流中的内容:
public static void print (InputStream is) throws UnsupportedEncodingException{InputStreamReader isr =new InputStreamReader(is,"utf-8");BufferedReader br = new BufferedReader(isr);try {int index = 0;while (index < 100) {System.out.println(br.readLine());index ++;}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
- 得到内容如下:
GET /index.html?user=outlier HTTP/1.1
Host: localhost:8080
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: Idea-c03939ae=62b06f69-204a-4fa1-8f13-0c23db6987dd; UM_distinctid=162ec462706246-04cad68b914a44-336e7b05-fa000-162ec46270921b; CNZZDATA1264021086=2075159346-1524378005-%7C1524583190
开始对内容进行解析
- 新建一个
parseRequest
方法 (这里暂定使用类似于解释器中的Map
进行存储得到解析的值)
//常规参数Map
private Map<String,String> paramMap = new HashMap<String, String>();
//在URI中使用的参数列表
private Map<String,String> uriParamMap = new HashMap<String, String>();
进行分析:这里使用递归子程序的方法进行解析
- 仿照之前的方法,先转化成
char
类型的数组
public char[] convertStreamToCharArray(InputStream is) {BufferedReader reader = new BufferedReader(new InputStreamReader(is));StringBuilder sb = new StringBuilder();String line = null;try {while ((line = reader.readLine()) != null) {sb.append(line + " ");}} catch (IOException e) {e.printStackTrace();} finally {try {is.close();} catch (IOException e) {e.printStackTrace();}}return sb.toString().toCharArray(); }
- 然后进行递归子程序的方法 ,这里先实现的第一行的解析:
package Connector;import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Map;public class HttpRequest {//the paramprivate Map<String,String> paramMap = new HashMap<String, String>();//the param in the URIprivate Map<String,String> uriParamMap = new HashMap<String, String>();//the tokens of the inputStreamchar[] tokens;//the offset of the tokensint currentToken = -1;//the value of the tokenchar current;/** get the tokens*/public HttpRequest(InputStream inputStream) {tokens = convertStreamToCharArray(inputStream);}/** get the URI*/public String getRequestURI() {System.out.println("paramMap.size() " + paramMap.size());return paramMap.get("requestURI");}/** the next token*/private void nextToken(){if (currentToken < tokens.length){currentToken ++;current = tokens[currentToken];} else {// TODO: error message needSystem.out.println("the end of the tokens");}}/** parse*/public void parseRequest(){if (tokens == null || tokens.length == 0){// TODO: error message needSystem.out.println("the input is null");return;}// startnextToken();if (current == 'G'){parseGetMethod();} else if (current == 'P'){} else {// TODO: error message needSystem.out.println("the input is wrong");return;}}/** parse Get*/private void parseGetMethod(){nextToken();if (current == 'E'){nextToken();if (current == 'T'){paramMap.put("METHOD","GET");// TODO: current message needSystem.out.println("the method : get");parseURI();} else {// TODO: error message needSystem.out.println("the method is wrong");}} else {// TODO: error message needSystem.out.println("the method is wrong");}}/** parse URI*/private void parseURI(){nextToken();while (current == ' ' || current == '\t'){nextToken();}if (current != '/'){// TODO: error message needSystem.out.println("there need a '/' , The URI is wrong");} else {StringBuilder sb = new StringBuilder();nextToken();while (current != '?' && current != ' '){sb.append(current);nextToken();}paramMap.put("requestURI", String.valueOf(sb));// TODO: current message needSystem.out.println("the requestURI :" + String.valueOf(sb));if (current == ' '){// There is no param in the request Param// TODO: current message needSystem.out.println("There is no param in the request Param");parseHttpVersion();} else {// TODO: current message needSystem.out.println("There is some params in the request Param");parseParamUriRequest();System.out.println("params have been recorded");parseHttpVersion();}}}/** parse the param of the uriRequest*/private void parseParamUriRequest(){StringBuilder sb_key = new StringBuilder();StringBuilder sb_value = new StringBuilder();nextToken();while (current != '='){sb_key.append(current);nextToken();}nextToken();while (current != '&' && current != ' '){sb_value.append(current);nextToken();}uriParamMap.put(String.valueOf(sb_key),String.valueOf(sb_value));// TODO: current message needSystem.out.println(" params in the URI : " +String.valueOf(sb_key)+ " : " +String.valueOf(sb_value));if (current == '&'){parseParamUriRequest();}}/** parse the version of the Http*/private void parseHttpVersion(){nextToken();while (current == ' ' || current == '\t'){nextToken();}if (current == 'H'){StringBuilder sb_key = new StringBuilder();StringBuilder sb_value = new StringBuilder();while (current != '/'){sb_key.append(current);nextToken();}nextToken();while (current != '\n' && current != '\t' && current != ' '){sb_value.append(current);nextToken();}paramMap.put(String.valueOf(sb_key),String.valueOf(sb_value));// TODO: current message needSystem.out.println(" HTTP Version : " +String.valueOf(sb_key)+ " : " +String.valueOf(sb_value));nextToken();// TODO: 下一次分析开始 H // System.out.println(current);}}/** change the inputStream to the CharArray*/private char[] convertStreamToCharArray(InputStream is) {BufferedReader reader = new BufferedReader(new InputStreamReader(is));StringBuilder sb = new StringBuilder();String line = null;try {while ((line = reader.readLine()) != null) {sb.append(line + ' ');}} catch (IOException e) {e.printStackTrace();} finally {try {is.close();} catch (IOException e) {e.printStackTrace();}}return sb.toString().toCharArray();}}
- 仿照之前的方法,先转化成
运行结果:
git
地址:https://github.com/Outliwer/SimpledWebContainer