Java修炼——手写服务器项目

项目工程总览: 

 1.Dispatcher类(一个请求与响应就是一个Dispatcher)

package com.bjsxt.server;

import java.io.IOException;
import java.net.Socket;

import com.bjsxt.servlet.Servlet;
import com.bjsxt.util.IOCloseUtil;

/**
 * 一个请求与响应就是一个Dispatcher
 * @author Administrator
 *
 */
public class Dispatcher implements Runnable {
	private Request req;
	private Response rep;
	private Socket client;
	private int code=200;//状态码
	//构造方法初始化属性
	public Dispatcher(Socket client) {
		//将局部变量的值赋给成员变量
		this.client=client;
		try {
			req=new Request(this.client.getInputStream());
			rep=new Response(this.client.getOutputStream());
		} catch (IOException e) {
			code=500;
			return ;
		}
	}
	@Override
	public void run() {
		//根据不同的url创建指定的Servlet对象
		//System.out.println(req.getUrl());
		Servlet servlet=WebApp.getServlet(req.getUrl());
		if (servlet==null) {
			this.code=404;
		}else{
			//调用相应的Servlet中的service方法
			try {
				servlet.service(req,rep);
			} catch (Exception e) {
				this.code=500;
			}
		}
		//将响应结果推送到客户机的浏览器
		rep.pushToClient(code);
		IOCloseUtil.closeAll(client);
	}

}

2.Entity(实体类)

package com.bjsxt.server;
/**
 * <servlet>
		<servlet-name>login</servlet-name>
		<serlvet-class>com.bjsxt.servlet.LoginServlet</serlvet-class>
	</servlet>
 * @author Administrator
 *
 */
public class Entity { /**servlet-name和一个servlet-name所对应的一个实体类*/
	private String name;//servlet-name
	private String clazz;//servlet-class
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getClazz() {
		return clazz;
	}
	public void setClazz(String clazz) {
		this.clazz = clazz;
	}
	public Entity(String name, String clazz) {
		super();
		this.name = name;
		this.clazz = clazz;
	}
	public Entity() {
		super();
	}
	
}

3.Mapping类(映射关系,多个路径访问共享资源)

package com.bjsxt.server;

import java.util.ArrayList;
import java.util.List;

/**
 * <servlet-mapping>
		<serlvet-name>login</serlvet-name>
		<url-pattern>/login</url-pattern>
		<url-pattern>/log</url-pattern>
	</servlet-mapping>
 * @author Administrator
 *
 */
public class Mapping {//映射关系,多个路径访问共享资源
	private String name;//servlet-name
	private List<String> urlPattern;//url-pattern
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public List<String> getUrlPattern() {
		return urlPattern;
	}
	public void setUrlPattern(List<String> urlPattern) {
		this.urlPattern = urlPattern;
	}
	public Mapping(){
		urlPattern=new ArrayList<String>();
	}
	public Mapping(String name, List<String> urlPattern) {
		super();
		this.name = name;
		this.urlPattern = urlPattern;
	}
	
}

4.Request类

package com.bjsxt.server;

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

public class Request {/*请求*/
	private InputStream is;//输入流
	private String requestInfo;//请求字符串,请求方式,请求的路径,参数,协议,协议版本,请求的正文。。。
	private String method;//请求的方式
	private String url;//请求的url
	public String getUrl() {
		return url;
	}
	//输入框的name为key,值为value
	/*
	 *  key: username    value  :bjsxt
	 *  key:pwd          value:123
	 *  key:hobby        value   :read,ball
	 * */
	private Map<String,List<String>> parametermapValues;//参数
	private static final String CRLF="\r\n";//换行
	private static final String BLANK=" ";//空格
	//构造方法,初始化属性
	public Request() {
		parametermapValues=new HashMap<String,List<String>>();
		method="";
		url="";
		requestInfo="";
	}
	public Request(InputStream is){
		this();//调用本类无参的构造方法
		this.is=is;
		try {
			byte [] buf=new byte[20480];
			int len=this.is.read(buf);
			requestInfo=new String(buf,0,len);
		} catch (IOException e) {
			return;
		}
		//调用本类中的分解请求信息的方法
		this.parseRequestInfo();
	}
	//分解请求信息的方法
	/**
	 * 请求方式
	 * 请求路径
	 * 请求的参数
	 * 
	 */
	private void parseRequestInfo(){
		String paraString="";//用于存储请求参数
		//获取请求参数的第一行
		String firstLine=requestInfo.substring(0, requestInfo.indexOf(CRLF)).trim();//从0开始,到第一个换行的位置
		//分解出请求方式
		int index=firstLine.indexOf("/");
		this.method=firstLine.substring(0, index).trim();
		//分解url  ,get可能包含参数,也可能不包含参数post
		String urlString= firstLine.substring(index,firstLine.indexOf("HTTP/")).trim();
		//判断请求方式是GET还 是POST
		if("get".equalsIgnoreCase(this.method)){  //包含请求参数
			if (urlString.contains("?")) {
				String [] urlArray=urlString.split("\\?");
				this.url=urlArray[0];
				paraString=urlArray[1];
			}else{
				this.url=urlString;
			}
		}else{//post不包含请求参数
			this.url=urlString;
			paraString=requestInfo.substring(requestInfo.lastIndexOf(CRLF)).trim();
		}
		if (paraString.equals("")) {
			return;
		}
		//请求参数
		//System.out.println(paraString);
		
		//调用本类的中的分析请求参数的方法
		this.parseParam(paraString);
		
	}
	//用于测试
	/*public void show(){
		System.out.println(this.url);
		System.out.println(this.method);
	}*/
	
	//username=fdsaf&pwd=fdasf&hobby=ball&hobby=read
	/**
	 * username=bjsxt
	 * pwd=123
	 * hobby=ball
	 * hobby=paint
	 * 
	 * username=
	 * @param prarString
	 */
	private void parseParam(String paramString){
		String [] token=paramString.split("&");
		for(int i=0;i<token.length;i++){
			String keyValues=token[i];  //username=fasaf
			//继续分割
			String[] keyValue=keyValues.split("=");  //username=
			if (keyValue.length==1) {
				keyValue=Arrays.copyOf(keyValue, 2);
				keyValue[1]=null;
			}
			//转成Map集合
			String key=keyValue[0].trim();
			String value=keyValue[1]==null?null:decode(keyValue[1].trim(), "utf-8");
			//放到参数的集合中存储
			if (!parametermapValues.containsKey(key)) {
				parametermapValues.put(key, new ArrayList<String>());
			}
			List<String> values=parametermapValues.get(key);
			values.add(value);
		}
	}
	/**
	 * 编写根据表单元素的name获取多个对应的值
	 * 
	 */
	public String [] getParamterValues(String name){
		List<String> values=parametermapValues.get(name);
		if (values==null) {
			return null;
		}else{
			return values.toArray(new String [0]);
		}
		
	}
	/**
	 * 根据表单元素的name获取单个值
	 * 
	 */
	public String  getParameter(String name){
		//调用根据名称获取多个值的方法
		String [] values=getParamterValues(name);
		if (values==null) {
			return null;
		}else{
			return values[0];
		}
	}
	//用于测试
	public static void main(String[] args) {
		Request req=new Request();
		//调用分解参数的方法
		req.parseParam("username=%E5%8C%97%E4%BA%AC%E5%B0%9A%E5%AD%A6%E5%A0%82&pwd=123&hobby=ball&hobby=paint");
		System.out.println(req.parametermapValues);
		
		//调用获取多个值的方法
		String [] str=req.getParamterValues("hobby");
		for (String string : str) {
			System.out.println(string);
		}
		//调用获取单个值的方法
		System.out.println(req.getParameter("pwd"));
	}
	//处理中文,因为浏览器对中文进行了编码,进行解码
	private String decode(String value, String code){
		try {
			return URLDecoder.decode(value,code);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
}

5.Response类

package com.bjsxt.server;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;

import com.bjsxt.util.IOCloseUtil;

public class Response {//响应
	private StringBuilder headInfo;//响应头
	private StringBuilder content;//响应内容
	private int length;//响应内容的长度
	//流
	private BufferedWriter bw;
	
	//两个常量,换行和空格
	private static final String CRLF="\r\n";//换行
	private static final String BLANK=" ";//空格
	
	//构造方法
	public Response() {
		headInfo=new StringBuilder();
		content=new StringBuilder();
		
	}
	//带参构造方法
	public Response(OutputStream os){
		this();//调用本类的无参构造方法
		try {
			bw=new BufferedWriter(new OutputStreamWriter(os, "utf-8"));
		} catch (UnsupportedEncodingException e) {
			headInfo=null;
		}
		
	}
	//构造正文部分
	public Response print(String info){
		content.append(info);
		try {
			length+=info.getBytes("utf-8").length;
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return this;
	}
	public Response println(String info){
		content.append(info).append(CRLF);
		try {
			length+=(info+CRLF).getBytes("utf-8").length;
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return this;
	}
	
	//构造响应头
	
	private void createHeadInfo(int code){
		headInfo.append("HTTP/1.1").append(BLANK).append(code).append(BLANK);
		switch (code) {
		case 200:
			headInfo.append("OK");
			break;
		case 500:
			headInfo.append("SERVER ERROR");
			break;
		default:
			headInfo.append("NOT FOUND");
			break;
		}
		headInfo.append(CRLF);
		headInfo.append("Content-Type:text/html;charset=utf-8").append(CRLF);
		headInfo.append("Content-Length:"+length).append(CRLF);
		headInfo.append(CRLF);
	}
	/**
	 * 推送到客户机的浏览器
	 * @param code
	 */
	public void pushToClient(int code){
		if (headInfo==null) {
			code=500;
		}
		try {
			//调用本类中的构造响应头
			this.createHeadInfo(code);
			bw.write(headInfo.toString());
			bw.write(content.toString());
			bw.flush();
			this.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void close(){
		IOCloseUtil.closeAll(bw);
	}
}

6.Server类(服务器,用于启动和停止服务)

package com.bjsxt.server;

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 com.bjsxt.servlet.Servlet;
import com.bjsxt.util.IOCloseUtil;

public class Server {//服务器,用于启动和停止服务
	private ServerSocket server;
	private boolean isShutDown=false;//默认没有出错
	public static void main(String[] args) {
		Server server=new Server();//创建服务器对象
		server.start();
	}
	public void start(){
		this.start(8888);
	}
	public void start(int port){
		try {
			server=new ServerSocket(port);
			this.receive(); //调用接收请求信息的方法
		} catch (IOException e) {
			isShutDown=true;
		}
	}
	private void receive() {
		try {
			while(!isShutDown){
				//(1)监听
				Socket client=server.accept();
				//创建线程类的对象
				Dispatcher dis=new Dispatcher(client);
				//创建线程的代理类,并启动线程
				new Thread(dis).start();
			}	
			
		} catch (IOException e) {
			this.stop();//关闭服务器
		}
		
	}
	public void stop(){
		isShutDown=true;
		IOCloseUtil.closeAll(server);
	}
}

7.ServletContext类(Entity与Mapping的映射关系)

package com.bjsxt.server;

import java.util.HashMap;
import java.util.Map;

/**
 * Servlet上下用,就是一个容器,
 * @author Administrator
 *
 */
public class ServletContext { //Entity与Mapping的映射关系
	private Map<String,String> servlet;//key是servlet-name  (Entity中的name),值serlvet-class Entity中的clazz
	private Map<String,String> mapping;//key是url-pattern (Mapping中的List集合中的每一个元素),value是serlvet-name,是Mapping中的name
	public Map<String, String> getServlet() {
		return servlet;
	}
	public void setServlet(Map<String, String> servlet) {
		this.servlet = servlet;
	}
	public Map<String, String> getMapping() {
		return mapping;
	}
	public void setMapping(Map<String, String> mapping) {
		this.mapping = mapping;
	}
	public ServletContext() {
		servlet=new HashMap<String,String>();
		mapping=new HashMap<String,String>();
	}
}

8.WebApp类

package com.bjsxt.server;

import java.util.List;
import java.util.Map;

import com.bjsxt.servlet.Servlet;

public class WebApp {//App的意思是应用程序
	private static ServletContext contxt;
	static{
		contxt=new ServletContext();
		//分别获取对应关系的Map集合
		Map<String,String> servlet=contxt.getServlet();
		Map<String,String> mapping=contxt.getMapping();
		//创建解析XML文件对象
		WebDom4j web=new WebDom4j();
		web.parse(web.getDocument());//解析xml
		//获取解析XML之后的List集合
		List<Entity> entityList=web.getEntityList();
		List<Mapping> mappingList=web.getMappingList();
		
		//将List集合中的数据存储到Map集合
		for (Entity entity : entityList) {
			servlet.put(entity.getName(), entity.getClazz());
		}
		//	System.out.println(servlet);
		for( Mapping map:mappingList){
			//遍历url-pattern的集合
			List<String> urlPattern=map.getUrlPattern();
			for(String s:urlPattern){
				mapping.put(s, map.getName());
			}
		}
		//System.out.println(mapping);
	}
	/**
	 * 根据url创建不同的Servlet对象
	 * @param url
	 * @return
	 */
	public static Servlet getServlet(String url){
		if (url==null||url.trim().equals("")) {
			return null;
		}
		//调用无参构造方法创建Servlet对象
		
		try {
			//如果url正确
			//根据url的key获取servlet-name的值 /log=login, /reg=register
			String servletName=contxt.getMapping().get(url);
			//根据servletName得到对应的servlet-class
			String servletClass=contxt.getServlet().get(servletName);  //得到的是一个完整个的包名+类的字符串
			//使用反射创建 Servlet对象
			Class<?> clazz=Class.forName(servletClass);
			Servlet servlet = (Servlet) clazz.newInstance();
			return servlet;
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	//测试
	public static void main(String[] args) {
		System.out.println(getServlet("/log"));
		System.out.println(getServlet("/login"));
	}
}

9.WebDom4j 类(用于解析xml)

package com.bjsxt.server;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

public class WebDom4j {//用于解析XML
	private List<Entity> entityList;//用于存储是N多Entity,而每一个Entity都是servlet-name与servlet-class
	private List<Mapping> mappingList;//用于存储N多Mapping,而每一个Mapping都是一个servlet-name与N多个url-pattern
	public List<Entity> getEntityList() {
		return entityList;
	}
	public void setEntityList(List<Entity> entityList) {
		this.entityList = entityList;
	}
	public List<Mapping> getMappingList() {
		return mappingList;
	}
	public void setMappingList(List<Mapping> mappingList) {
		this.mappingList = mappingList;
	}
	//构造方法
	public WebDom4j() {
		entityList=new ArrayList<Entity>();
		mappingList=new ArrayList<Mapping>();
	}
	//获取Document对象的方法
	public Document getDocument(){
		try {
			//(1)创建SAXReader对象
			SAXReader reader=new SAXReader();
			//(2)调用read方法
			return reader.read(new File("src/WEB_INFO/web.xml"));
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	public void parse(Document doc){
		//(1)获取根元素
		Element root=doc.getRootElement(); //web-app
		//(2)获取servlet子元素
		for(Iterator<Element> ite=root.elementIterator("servlet");ite.hasNext();){
			Element subElement=ite.next();//得到每一个servlet
			//创建一个实体类
			Entity ent=new Entity(); //用于存储servlet-name与servlet-class
			for(Iterator<Element> subIte=subElement.elementIterator();subIte.hasNext();){
				Element ele=subIte.next(); //可能是servlet-name,也可能是servlet-class
				if("servlet-name".equals(ele.getName())){
					ent.setName(ele.getText()); //给实体类中的name赋值
				}else if("serlvet-class".equals(ele.getName())){
					ent.setClazz(ele.getText());
				}
			}
			//将Entity添加到集合中
			entityList.add(ent);
		}
		//测试
		/**for (Entity entity : entityList) {
			System.out.println(entity.getName()+"\t"+entity.getClazz());
		}*/
		//解析servlet-mapping
		
		for(Iterator<Element> ite=root.elementIterator("servlet-mapping");ite.hasNext();){
			Element subEle=ite.next();//得到每一个servlet-mapping
			//创建一个Mapping类的对象
			Mapping map=new Mapping();
			//解析servlet-mapping下的子元素
			for(Iterator<Element> subIte=subEle.elementIterator();subIte.hasNext();){
				Element ele=subIte.next();  //servlet-name,也有可能是url-pattern
				if("serlvet-name".equals(ele.getName())){
					map.setName(ele.getText());
				}else if("url-pattern".equals(ele.getName())){
					//获取集合对象,调用集合对象的添加方法,添加元素素
					map.getUrlPattern().add(ele.getText());
				}
			}
			//Mapping添加到集合中
			mappingList.add(map);
		}
		//测试
		/*for (Mapping m : mappingList) {
			System.out.println(m.getName());
			for(String s:m.getUrlPattern()){
				System.out.println(s);
			}
		}*/
	}
	//用于测试
	public static void main(String[] args) {
		WebDom4j web=new WebDom4j();
		web.parse(web.getDocument());
	}
}

10.FaviconServlet类

package com.bjsxt.servlet;

import com.bjsxt.server.Request;
import com.bjsxt.server.Response;

public class FaviconServlet extends Servlet {

	@Override
	public void doGet(Request req, Response rep) throws Exception {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void doPost(Request req, Response rep) throws Exception {
		// TODO Auto-generated method stub
		
	}

}

 

11.LoginServlet类

package com.bjsxt.servlet;

import com.bjsxt.server.Request;
import com.bjsxt.server.Response;

public class LoginServlet extends Servlet {

	@Override
	public void doGet(Request req, Response rep) throws Exception {
			//获取请求参数
		String name=req.getParameter("username");
		String pwd=req.getParameter("pwd");
		
		if(this.login(name, pwd)){
			//调用响应中的构建内容的方
			rep.println(name+"登录成功");
		}else{
			rep.println(name+"登录失败,对不起,账号或密码不正确");
		}
		
	}
	private boolean login(String name,String pwd){
		if ("bjsxt".equals(name)&&"123".equals(pwd)) {
			return true;
		}
		return false;
	}

	@Override
	public void doPost(Request req, Response rep) throws Exception {
		// TODO Auto-generated method stub
		
	}

	

}

12.Servlet(是所有的请求的Servlet的父类)

package com.bjsxt.servlet;

import com.bjsxt.server.Request;
import com.bjsxt.server.Response;

public abstract class Servlet { //是所有的请求的Servlet的父类
	public void service(Request req,Response rep) throws Exception{
		this.doGet( req, rep);
		this.doPost( req, rep);
	}
	public abstract void doGet(Request req,Response rep) throws Exception;
	public abstract void doPost(Request req,Response rep) throws Exception;
}

 

13.IOCloseUtil类(用于关闭流的工具类)

package com.bjsxt.util;

import java.io.Closeable;
import java.io.IOException;

public class IOCloseUtil {//用于关闭流
	public static void closeAll(Closeable...close){
		for (Closeable closeable : close) {
			if (closeable!=null) {
				try {
					closeable.close();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
}

14.web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
	<servlet>
		<servlet-name>login</servlet-name>
		<serlvet-class>com.bjsxt.servlet.LoginServlet</serlvet-class>
	</servlet>
	<servlet-mapping>
		<serlvet-name>login</serlvet-name>
		<url-pattern>/login</url-pattern>
		<url-pattern>/log</url-pattern>
	</servlet-mapping>
	<servlet>
		<servlet-name>register</servlet-name>
		<serlvet-class>com.bjsxt.servlet.RegisterServlet</serlvet-class>
	</servlet>
	<servlet-mapping>
		<serlvet-name>register</serlvet-name>
		<url-pattern>/reg</url-pattern>
		<url-pattern>/register</url-pattern>
		<url-pattern>/regis</url-pattern>
	</servlet-mapping>
	<servlet>
		<servlet-name>favicon</servlet-name>
		<serlvet-class>com.bjsxt.servlet.FaviconServlet</serlvet-class>
	</servlet>
	<servlet-mapping>
		<serlvet-name>favicon</serlvet-name>
		<url-pattern>/favicon.ico</url-pattern>
		
	</servlet-mapping>
</web-app>

 

15.Request

package com.bjsxt.server;

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

public class Request {/*请求*/
	private InputStream is;//输入流
	private String requestInfo;//请求字符串,请求方式,请求的路径,参数,协议,协议版本,请求的正文。。。
	private String method;//请求的方式
	private String url;//请求的url
	public String getUrl() {
		return url;
	}
	//输入框的name为key,值为value
	/*
	 *  key: username    value  :bjsxt
	 *  key:pwd          value:123
	 *  key:hobby        value   :read,ball
	 * */
	private Map<String,List<String>> parametermapValues;//参数
	private static final String CRLF="\r\n";//换行
	private static final String BLANK=" ";//空格
	//构造方法,初始化属性
	public Request() {
		parametermapValues=new HashMap<String,List<String>>();
		method="";
		url="";
		requestInfo="";
	}
	public Request(InputStream is){
		this();//调用本类无参的构造方法
		this.is=is;
		try {
			byte [] buf=new byte[20480];
			int len=this.is.read(buf);
			requestInfo=new String(buf,0,len);
		} catch (IOException e) {
			return;
		}
		//调用本类中的分解请求信息的方法
		this.parseRequestInfo();
	}
	//分解请求信息的方法
	/**
	 * 请求方式
	 * 请求路径
	 * 请求的参数
	 * 
	 */
	private void parseRequestInfo(){
		String paraString="";//用于存储请求参数
		//获取请求参数的第一行
		String firstLine=requestInfo.substring(0, requestInfo.indexOf(CRLF)).trim();//从0开始,到第一个换行的位置
		//分解出请求方式
		int index=firstLine.indexOf("/");
		this.method=firstLine.substring(0, index).trim();
		//分解url  ,get可能包含参数,也可能不包含参数post
		String urlString= firstLine.substring(index,firstLine.indexOf("HTTP/")).trim();
		//判断请求方式是GET还 是POST
		if("get".equalsIgnoreCase(this.method)){  //包含请求参数
			if (urlString.contains("?")) {
				String [] urlArray=urlString.split("\\?");
				this.url=urlArray[0];
				paraString=urlArray[1];
			}else{
				this.url=urlString;
			}
		}else{//post不包含请求参数
			this.url=urlString;
			paraString=requestInfo.substring(requestInfo.lastIndexOf(CRLF)).trim();
		}
		if (paraString.equals("")) {
			return;
		}
		//请求参数
		//System.out.println(paraString);
		
		//调用本类的中的分析请求参数的方法
		this.parseParam(paraString);
		
	}
	//用于测试
	/*public void show(){
		System.out.println(this.url);
		System.out.println(this.method);
	}*/
	
	//username=fdsaf&pwd=fdasf&hobby=ball&hobby=read
	/**
	 * username=bjsxt
	 * pwd=123
	 * hobby=ball
	 * hobby=paint
	 * 
	 * username=
	 * @param prarString
	 */
	private void parseParam(String paramString){
		String [] token=paramString.split("&");
		for(int i=0;i<token.length;i++){
			String keyValues=token[i];  //username=fasaf
			//继续分割
			String[] keyValue=keyValues.split("=");  //username=
			if (keyValue.length==1) {
				keyValue=Arrays.copyOf(keyValue, 2);
				keyValue[1]=null;
			}
			//转成Map集合
			String key=keyValue[0].trim();
			String value=keyValue[1]==null?null:decode(keyValue[1].trim(), "utf-8");
			//放到参数的集合中存储
			if (!parametermapValues.containsKey(key)) {
				parametermapValues.put(key, new ArrayList<String>());
			}
			List<String> values=parametermapValues.get(key);
			values.add(value);
		}
	}
	/**
	 * 编写根据表单元素的name获取多个对应的值
	 * 
	 */
	public String [] getParamterValues(String name){
		List<String> values=parametermapValues.get(name);
		if (values==null) {
			return null;
		}else{
			return values.toArray(new String [0]);
		}
		
	}
	/**
	 * 根据表单元素的name获取单个值
	 * 
	 */
	public String  getParameter(String name){
		//调用根据名称获取多个值的方法
		String [] values=getParamterValues(name);
		if (values==null) {
			return null;
		}else{
			return values[0];
		}
	}
	//用于测试
	public static void main(String[] args) {
		Request req=new Request();
		//调用分解参数的方法
		req.parseParam("username=%E5%8C%97%E4%BA%AC%E5%B0%9A%E5%AD%A6%E5%A0%82&pwd=123&hobby=ball&hobby=paint");
		System.out.println(req.parametermapValues);
		
		//调用获取多个值的方法
		String [] str=req.getParamterValues("hobby");
		for (String string : str) {
			System.out.println(string);
		}
		//调用获取单个值的方法
		System.out.println(req.getParameter("pwd"));
	}
	//处理中文,因为浏览器对中文进行了编码,进行解码
	private String decode(String value, String code){
		try {
			return URLDecoder.decode(value,code);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
}

 

 

 

 

 

 

 

 

posted @ 2019-12-11 08:56  sakura-yxf  阅读(250)  评论(0)    收藏  举报