项目结构如下
由于是简易实现,原理比较简单,
1.新建ServerSocket连接,监听服务端口
2.浏览器输入请求后获取inputStream,outputStream封装成简易的HttpRequest,HttpResponse
3.至于servlet mapping映射直接在ServletMappingConfig使用map集合存储
4.访问servlet类通过java反射机制访问
封装httprequest
package com.wying.tomcat;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
/**
* description: 输入流解析url和method封装成简易httprequest
* date: 2020/7/14
* author: gaom
* version: 1.0
*/
public class HttpRequest {
private String url;
private String method;
private String paramStr;
private Map<String,String> paramMap=new HashMap<>();
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public HttpRequest(InputStream inputStream) throws IOException {
String httpRequestStr ="";
byte[] bytes=new byte[1024];
int length =0;
if((length=inputStream.read(bytes)) >0){
httpRequestStr=new String(bytes,0,length);
}
System.out.println("HttpRequest inputStream:"+httpRequestStr);
String httpHead = httpRequestStr.split("\n")[0];
//解析出http请求的url 和method
//GET /testServlet?name=123 HTTP/1.1
method=httpHead.split("\\s")[0];
String httpUrl=httpHead.split("\\s")[1];
//解析get传参数据
if(httpUrl.indexOf("?")>=0){
String[] httpUrls= httpUrl.split("\\?");
url=httpUrls[0];
paramStr=httpUrls[1];
setParams();
}else{
url=httpUrl;
}
System.out.println("HttpRequest url:"+url+" method:"+method);
}
//解析参数存入map
private void setParams(){
System.out.println("解析参数存入map this.paramStr:"+this.paramStr);
String[] params = this.paramStr.split("&");
for (String param : params) {
String[] keyValue = param.split("=");
paramMap.put(keyValue[0], keyValue[1]);
}
}
//获取参数
public String getParamter(String paramName){
return paramMap.get(paramName);
}
}
封装httpresponse
package com.wying.tomcat;
import java.io.IOException;
import java.io.OutputStream;
/**
* description:简单httpresponse 直接出出文本
* date: 2020/7/14
* author: gaom
* version: 1.0
*/
public class HttpResponse {
private OutputStream outputStream;
public HttpResponse(OutputStream outputStream){
this.outputStream = outputStream;
}
public void write(String content)throws IOException {
StringBuffer httpResponse = new StringBuffer();
httpResponse.append("HTTP/1.1 200 OK\n")
.append("Content-Type: text/html\n")
.append("\r\n");
httpResponse.append(content);
outputStream.write(httpResponse.toString().getBytes());
outputStream.close();
}
}
写入url和对应的servlet类映射关系
package com.wying.tomcat;
/**
* description:
* date: 2020/7/14
* author: gaom
* version: 1.0
*/
public class ServletMapping {
private String servletName;
private String url;
private String clazz;
public ServletMapping(String servletName, String url, String clazz){
this.servletName=servletName;
this.url=url;
this.clazz=clazz;
}
public String getServletName() {
return servletName;
}
public void setServletName(String servletName) {
this.servletName = servletName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getClazz() {
return clazz;
}
public void setClazz(String clazz) {
this.clazz = clazz;
}
}
package com.wying.tomcat;
import java.util.ArrayList;
import java.util.List;
/**
* description:
* date: 2020/7/14
* author: gaom
* version: 1.0
*/
public class ServletMappingConfig {
public static List<ServletMapping> servletMappingList =new ArrayList<>();
//简单处理 tomcat是从web.xml读取
static{
servletMappingList.add(new ServletMapping("testServlet","/testServlet","com.wying.test.TestServlet"));
}
}
HttpServlet基类
package com.wying.tomcat;
import java.io.IOException;
/**
* description:
* date: 2020/7/14
* author: gaom
* version: 1.0
*/
public abstract class HttpServlet {
public abstract void doGet(HttpRequest httpRequest,HttpResponse httpResponse) throws IOException;
public abstract void doPost(HttpRequest httpRequest,HttpResponse httpResponse) throws IOException;
public void service(HttpRequest httpRequest,HttpResponse httpResponse) throws IOException{
if(httpRequest.getMethod().equalsIgnoreCase("POST")){
doPost(httpRequest,httpResponse);
}else if(httpRequest.getMethod().equalsIgnoreCase("GET")){
doGet(httpRequest,httpResponse);
}
}
}
启动类
package com.wying.tomcat;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
/**
* description:tomcat启动类
* date: 2020/7/14
* author: gaom
* version: 1.0
*/
public class Catalina {
private int port=8088;
private Map<String,String> urlServletMap =new HashMap<String,String>();
public Catalina(int port){
this.port=port;
}
public void start() {
// 初始化URL与对应处理的servlet的关系
initServletMapping();
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(port);
System.out.println("tomcat start port:"+port);
while (true) {
System.out.println("开始监听请求....");
//监听请求
Socket socket = serverSocket.accept();
System.out.println("收到请求.....");
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
//封装httpRequest
HttpRequest httpRequest = new HttpRequest(inputStream);
//封装httpResponse
HttpResponse httpResponse = new HttpResponse(outputStream);
System.out.println("request httpRequestUrl :"+httpRequest .getUrl());
//分发器
dispatch(httpRequest, httpResponse);
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != serverSocket) {
try {
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//将url和对应的servlet类存入map
private void initServletMapping(){
for (ServletMapping servletMapping : ServletMappingConfig.servletMappingList) {
urlServletMap.put(servletMapping.getUrl(), servletMapping.getClazz());
}
}
public void dispatch(HttpRequest httpRequest,HttpResponse httpResponse) throws IOException {
//根据url找到servlet类
if("/favicon.ico".equals(httpRequest.getUrl())){
System.out.println("浏览器获取图标请求 暂时忽略");
return;
}
String clazz =urlServletMap.get( httpRequest.getUrl());
if(clazz==null){
httpResponse.write(" error url:"+httpRequest.getUrl()+" not match Servlet");
return;
}
try{
//通过反射机制创建对应的servlet对象
Class<HttpServlet> httpServletClass =(Class<HttpServlet>) Class.forName(clazz);
HttpServlet httpServlet= httpServletClass.newInstance();
httpServlet.service(httpRequest,httpResponse);
}catch (ClassNotFoundException e){
e.printStackTrace();
}catch (InstantiationException e){
e.printStackTrace();
}catch (IllegalAccessException e){
e.printStackTrace();
}
}
public static void main(String[] args){
Catalina catalina= new Catalina(8088);
catalina.start();
}
}
TestServlet
package com.wying.test;
import com.wying.tomcat.HttpRequest;
import com.wying.tomcat.HttpResponse;
import com.wying.tomcat.HttpServlet;
import java.io.IOException;
/**
* description:
* date: 2020/7/14
* author: gaom
* version: 1.0
*/
public class TestServlet extends HttpServlet {
@Override
public void doGet(HttpRequest httpRequest, HttpResponse httpResponse) throws IOException {
System.out.println("TestServlet doGet............;..");
String name= httpRequest.getParamter("name");
httpResponse.write(" <html><body><h1>TestServlet success!!!! name:"+name+"</h1></body></html>");
}
@Override
public void doPost(HttpRequest httpRequest, HttpResponse httpResponse) {
System.out.println("TestServlet doPost..............");
}
}
浏览器访问效果