├── static
├── idea.jpeg
├── banner.swf
├── estate.gif
├── 404.html
└── news.css
├── out
└── production
│ └── MyTomCat
│ ├── User.class
│ ├── Login.class
│ ├── servlet
│ ├── Cookie.class
│ ├── Servlet.class
│ ├── HttpServlet.class
│ ├── HttpSession.class
│ ├── ServletContext.class
│ ├── HttpServletRequest.class
│ └── HttpServletResponse.class
│ └── server
│ ├── MyTomcat.class
│ ├── Processor.class
│ ├── ServerService.class
│ ├── DynamicProcessor.class
│ └── StaticProcessor.class
├── .idea
├── description.html
├── encodings.xml
├── vcs.xml
├── modules.xml
├── misc.xml
├── compiler.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── junitgenerator-prj-settings.xml
├── uiDesigner.xml
└── workspace.xml
├── README.md
├── src
├── servlet
│ ├── Servlet.java
│ ├── ServletContext.java
│ ├── HttpSession.java
│ ├── HttpServlet.java
│ ├── Cookie.java
│ ├── HttpServletResponse.java
│ └── HttpServletRequest.java
├── server
│ ├── Processor.java
│ ├── StaticProcessor.java
│ ├── MyTomcat.java
│ ├── DynamicProcessor.java
│ └── ServerService.java
├── User.java
└── Login.java
└── MyTomCat.iml
/static/idea.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itudo/MyTomcat/HEAD/static/idea.jpeg
--------------------------------------------------------------------------------
/static/banner.swf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itudo/MyTomcat/HEAD/static/banner.swf
--------------------------------------------------------------------------------
/static/estate.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itudo/MyTomcat/HEAD/static/estate.gif
--------------------------------------------------------------------------------
/out/production/MyTomCat/User.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itudo/MyTomcat/HEAD/out/production/MyTomCat/User.class
--------------------------------------------------------------------------------
/.idea/description.html:
--------------------------------------------------------------------------------
1 | Simple Java application that includes a class with main() method
--------------------------------------------------------------------------------
/out/production/MyTomCat/Login.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itudo/MyTomcat/HEAD/out/production/MyTomCat/Login.class
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # MyTomcat
2 | 实现一个简单的Tomcat
3 | 实现功能:
4 |
5 | 1:静态资源请求
6 |
7 | 2:动态请求处理
8 |
9 | 3:session及cookie信息存储
10 |
--------------------------------------------------------------------------------
/out/production/MyTomCat/servlet/Cookie.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itudo/MyTomcat/HEAD/out/production/MyTomCat/servlet/Cookie.class
--------------------------------------------------------------------------------
/out/production/MyTomCat/server/MyTomcat.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itudo/MyTomcat/HEAD/out/production/MyTomCat/server/MyTomcat.class
--------------------------------------------------------------------------------
/out/production/MyTomCat/server/Processor.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itudo/MyTomcat/HEAD/out/production/MyTomCat/server/Processor.class
--------------------------------------------------------------------------------
/out/production/MyTomCat/servlet/Servlet.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itudo/MyTomcat/HEAD/out/production/MyTomCat/servlet/Servlet.class
--------------------------------------------------------------------------------
/out/production/MyTomCat/servlet/HttpServlet.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itudo/MyTomcat/HEAD/out/production/MyTomCat/servlet/HttpServlet.class
--------------------------------------------------------------------------------
/out/production/MyTomCat/servlet/HttpSession.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itudo/MyTomcat/HEAD/out/production/MyTomCat/servlet/HttpSession.class
--------------------------------------------------------------------------------
/out/production/MyTomCat/server/ServerService.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itudo/MyTomcat/HEAD/out/production/MyTomCat/server/ServerService.class
--------------------------------------------------------------------------------
/out/production/MyTomCat/server/DynamicProcessor.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itudo/MyTomcat/HEAD/out/production/MyTomCat/server/DynamicProcessor.class
--------------------------------------------------------------------------------
/out/production/MyTomCat/server/StaticProcessor.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itudo/MyTomcat/HEAD/out/production/MyTomCat/server/StaticProcessor.class
--------------------------------------------------------------------------------
/out/production/MyTomCat/servlet/ServletContext.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itudo/MyTomcat/HEAD/out/production/MyTomCat/servlet/ServletContext.class
--------------------------------------------------------------------------------
/out/production/MyTomCat/servlet/HttpServletRequest.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itudo/MyTomcat/HEAD/out/production/MyTomCat/servlet/HttpServletRequest.class
--------------------------------------------------------------------------------
/out/production/MyTomCat/servlet/HttpServletResponse.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/itudo/MyTomcat/HEAD/out/production/MyTomCat/servlet/HttpServletResponse.class
--------------------------------------------------------------------------------
/static/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Insert title here
6 |
7 |
8 | 404
9 |
10 |
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/servlet/Servlet.java:
--------------------------------------------------------------------------------
1 | package servlet;
2 |
3 | /**
4 | * @description: Servlet
5 | * @author: WangZhiJun
6 | * @create: 2019-07-26 09:44
7 | **/
8 | public interface Servlet {
9 |
10 | /**
11 | * servlet初始化
12 | */
13 | void init();
14 | /**
15 | * servlet业务处理
16 | */
17 | void service(HttpServletRequest request, HttpServletResponse response);
18 | }
19 |
--------------------------------------------------------------------------------
/src/server/Processor.java:
--------------------------------------------------------------------------------
1 | package server;
2 |
3 | import servlet.HttpServletRequest;
4 | import servlet.HttpServletResponse;
5 |
6 | /**
7 | * @description: 处理接口
8 | * @author: WangZhiJun
9 | * @create: 2019-07-26 09:44
10 | **/
11 | public interface Processor {
12 | /** 处理请求,给出响应
13 | * @param request 请求
14 | * @param response 响应
15 | */
16 | void process(HttpServletRequest request, HttpServletResponse response);
17 | }
18 |
--------------------------------------------------------------------------------
/src/server/StaticProcessor.java:
--------------------------------------------------------------------------------
1 | package server;
2 |
3 | import servlet.HttpServletRequest;
4 | import servlet.HttpServletResponse;
5 |
6 | /**
7 | * @description: 静态处理类
8 | * @author: WangZhiJun
9 | * @create: 2019-07-26 09:44
10 | **/
11 | public class StaticProcessor implements Processor {
12 |
13 | @Override
14 | public void process(HttpServletRequest request, HttpServletResponse response) {
15 | response.sendRedirect();
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/MyTomCat.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/servlet/ServletContext.java:
--------------------------------------------------------------------------------
1 | package servlet;
2 |
3 | import java.util.Hashtable;
4 | import java.util.Map;
5 |
6 | /**
7 | * @description: Servlet上下文
8 | * @author: WangZhiJun
9 | * @create: 2019-07-26 09:44
10 | **/
11 | public class ServletContext {
12 | /**
13 | * servlet容器:存储servlet实例
14 | */
15 | public static Map servlets = new Hashtable();
16 | /**
17 | * 存储session信息
18 | */
19 | static Map sessions = new Hashtable<>();
20 | }
21 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/servlet/HttpSession.java:
--------------------------------------------------------------------------------
1 | package servlet;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | /**
7 | * @description: HttpSession
8 | * @author: WangZhiJun
9 | * @create: 2019-07-26 09:44
10 | **/
11 | public class HttpSession {
12 | private Map map = new HashMap();
13 | private String id;
14 |
15 | HttpSession(String id) {
16 | super();
17 | this.id = id;
18 | }
19 |
20 |
21 | public String getId() {
22 | return id;
23 | }
24 |
25 | public void setAttribute(String name,Object value) {
26 | this.map.put(name, value);
27 | }
28 |
29 | public Object getAttribute(String key) {
30 | return map.get(key);
31 | }
32 |
33 | public void removeAttribute(String name) {
34 | this.map.remove(name);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/servlet/HttpServlet.java:
--------------------------------------------------------------------------------
1 | package servlet;
2 |
3 | /** httpServlet针对http协议
4 | * GET /HTTP/1.1
5 | * @description: 简单Cookie类
6 | * @author: WangZhiJun
7 | * @create: 2019-07-26 09:44
8 | **/
9 | public abstract class HttpServlet implements Servlet {
10 | @Override
11 | public void init(){}
12 |
13 | protected void doPost(HttpServletRequest request, HttpServletResponse response) {}
14 |
15 | protected void doGet(HttpServletRequest request, HttpServletResponse response) {}
16 |
17 | /** 从request中取出method,判断是get还是post,调用doGet,doPost
18 | * @param request 请求
19 | * @param response 响应
20 | */
21 | @Override
22 | public void service(HttpServletRequest request, HttpServletResponse response) {
23 | String method = request.getMethod();
24 | if("GET".equals(method)){
25 | doGet(request,response);
26 | }else if("POST".equals(method)){
27 | doPost(request,response);
28 | }
29 | //还有 HEAD TRACE DELETE PUT等方法
30 | }
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/static/news.css:
--------------------------------------------------------------------------------
1 | #sidebar {
2 | width:266px;
3 | height:850px;
4 | background:#fff;
5 | float:left;
6 | border-right:1px solid #ccc;
7 | }
8 | #sidebar embed {
9 | display:block;
10 | width:220px;
11 | height:200px;
12 | margin:0 auto;
13 | margin-top:20px;
14 | }
15 | #content {
16 | width:600px;
17 | height:850px;
18 | background:#fff;
19 | float:right;
20 | }
21 | #content h1 {
22 | background:url(../images/newsc.gif) no-repeat;
23 | width:123px;
24 | height:27px;
25 | font-size:100%;
26 | text-indent:-9999px;
27 | margin-top:20px;
28 | margin-left:20px;
29 | }
30 | #content ul {
31 | margin-left:20px;
32 | margin-top:10px;
33 | line-height:180%;
34 | }
35 | #content ul li {
36 | padding-left:15px;
37 | background:url(../images/ico.gif) no-repeat left center;
38 | }
39 | #content ul li a {
40 | text-decoration:none;
41 | color:#06f;
42 | }
43 | #content ul li a:hover {
44 | color:#f60;
45 | text-decoration:underline;
46 | }
47 | #content p {
48 | margin-top:30px;
49 | text-align:center;
50 | }
--------------------------------------------------------------------------------
/src/servlet/Cookie.java:
--------------------------------------------------------------------------------
1 | package servlet;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * @description: 简单Cookie类
7 | * @author: WangZhiJun
8 | * @create: 2019-07-26 09:44
9 | **/
10 | public class Cookie implements Serializable{
11 | private static final long serialVersionUID = -3977915365961941126L;
12 | /**
13 | * cookie的名称
14 | */
15 | private String name;
16 | /**
17 | * cookie的值
18 | */
19 | private String value;
20 | //cookie还有path domin maxAge等属性,在此简化使用
21 |
22 | @Override
23 | public String toString() {
24 | return "Cookie [name=" + name + ", value=" + value;
25 | }
26 | public String getName() {
27 | return name;
28 | }
29 | public void setName(String name) {
30 | this.name = name;
31 | }
32 | public String getValue() {
33 | return value;
34 | }
35 | public void setValue(String value) {
36 | this.value = value;
37 | }
38 |
39 | public Cookie(String name, String value) {
40 | super();
41 | this.name = name;
42 | this.value = value;
43 | }
44 |
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/src/User.java:
--------------------------------------------------------------------------------
1 | import servlet.HttpServlet;
2 | import servlet.HttpServletRequest;
3 | import servlet.HttpServletResponse;
4 | import servlet.HttpSession;
5 |
6 | import java.io.PrintWriter;
7 |
8 |
9 | /**
10 | * @author WangZhiJun
11 | */
12 | public class User extends HttpServlet {
13 |
14 | @Override
15 | protected void doPost(HttpServletRequest request,
16 | HttpServletResponse response) {
17 | HttpSession session = request.getSession();
18 | String username = (String) session.getAttribute("username");
19 |
20 | PrintWriter out = response.getWriter();
21 | String jsession = request.getJsessionid();
22 | if(jsession!=null) {
23 | out.print("HTTP/1.1 200 OK\r\nSet-Cookie: JSESSIONID="+jsession+"\r\n\r\n");
24 | } else {
25 | out.print("HTTP/1.1 200 OK\r\n\r\n");
26 | }
27 | out.print("");
28 | out.print("");
29 | out.print("welcome! "+ username + "\r\n\r\n");
30 | out.print("sessionId:" + jsession);
31 | out.print("");
32 | out.print("");
33 | out.flush();
34 | out.close();
35 | }
36 |
37 | @Override
38 | protected void doGet(HttpServletRequest request,
39 | HttpServletResponse response) {
40 | doPost(request,response);
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/src/server/MyTomcat.java:
--------------------------------------------------------------------------------
1 | package server;
2 |
3 | import java.io.IOException;
4 | import java.net.ServerSocket;
5 | import java.net.Socket;
6 |
7 | /**
8 | * @description: Tomcat服务器启动类
9 | * @author: WangZhiJun
10 | * @create: 2019-07-26 09:44
11 | **/
12 | public class MyTomcat {
13 |
14 | public static void main(String[] args) {
15 | MyTomcat kc = new MyTomcat();
16 | kc.startServer();
17 | }
18 | private void startServer() {
19 | System.out.println("服务器准备启动");
20 | //TODO:在这里加入一个xml解析模块,读取server.xml,读取port信息
21 | int port = getServerPort();
22 | ServerSocket ss = null;
23 | try {
24 | ss = new ServerSocket(port);
25 | System.out.println("服务器启动成功,监听:"+ss.getLocalPort()+"端口");
26 | } catch (Exception e) {
27 | e.printStackTrace();
28 | System.out.println(port+"被占用,服务器启动失败");
29 | //TODO:自动选定另一个tcp的空闲端口
30 | System.exit(0);
31 | }
32 |
33 | while(true){
34 | Socket s=null;
35 | try {
36 | s = ss.accept();
37 | System.out.println("客户端"+s.getRemoteSocketAddress()+"联结上来了");
38 | //启动线程来处理这个客户端的请求与响应
39 | ServerService server = new ServerService(s);
40 | //TODO:不要显式创建线程,使用线程池
41 | Thread t = new Thread(server);
42 | t.start();
43 | } catch (IOException e) {
44 | e.printStackTrace();
45 | System.out.println("客户端"+s.getRemoteSocketAddress()+"掉线了");
46 | }
47 | }
48 | }
49 | private int getServerPort() {
50 | return 8888;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/Login.java:
--------------------------------------------------------------------------------
1 | import servlet.HttpServlet;
2 | import servlet.HttpServletRequest;
3 | import servlet.HttpServletResponse;
4 | import servlet.HttpSession;
5 | import java.io.PrintWriter;
6 |
7 |
8 | /**
9 | * @author WangZhiJun
10 | */
11 | public class Login extends HttpServlet {
12 |
13 | @Override
14 | protected void doPost(HttpServletRequest request,
15 | HttpServletResponse response) {
16 | String username = request.getParameter("username");
17 | String password = request.getParameter("password");
18 | System.out.println(username+"\t"+password);
19 |
20 | System.out.println(request.getCookies());
21 |
22 | HttpSession session = request.getSession();
23 | session.setAttribute("username", username);
24 | session.setAttribute("password", password);
25 |
26 | PrintWriter out = response.getWriter();
27 | String jsession = request.getJsessionid();
28 | if(jsession!=null) {
29 | out.print("HTTP/1.1 200 OK\r\nSet-Cookie: JSESSIONID="+jsession+"\r\n\r\n");
30 | } else {
31 | out.print("HTTP/1.1 200 OK\r\n\r\n");
32 | }
33 | out.print("");
34 | out.print("");
35 | out.print("login success! \r\n");
36 | out.print("sessionId:" + jsession);
37 | out.print("");
38 | out.print("");
39 | out.flush();
40 | out.close();
41 | }
42 |
43 | @Override
44 | protected void doGet(HttpServletRequest request,
45 | HttpServletResponse response) {
46 | doPost(request,response);
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/src/server/DynamicProcessor.java:
--------------------------------------------------------------------------------
1 | package server;
2 |
3 | import servlet.HttpServlet;
4 | import servlet.HttpServletRequest;
5 | import servlet.HttpServletResponse;
6 | import servlet.ServletContext;
7 |
8 | /**
9 | * @description: 动态请求处理类
10 | * @author: WangZhiJun
11 | * @create: 2019-07-26 09:44
12 | **/
13 | public class DynamicProcessor implements Processor {
14 |
15 | @Override
16 | public void process(HttpServletRequest request, HttpServletResponse response){
17 |
18 | //1、假设请求的地址为 /hello.action ->对应的是hello 这个servlet 类
19 | //从request中取出getRequestURI
20 | String uri = request.getRequestURI();
21 | //2、去掉 / 及action 两个部分 ,得到hello ,就是servlet类名
22 | String servletName = uri.substring(1,uri.indexOf("."));
23 | //单实例实现 ->到Map中判断是否已经存在了这个servlet实例,如果有,则取出这个实例
24 | //利用反射来加载这个类的字节码 URLClassLoader 来加载class
25 | HttpServlet servlet = null;
26 | //没有servlet实例
27 | if(!ServletContext.servlets.containsKey(servletName)){
28 | try {
29 | Class c = Class.forName(servletName);
30 | //2、利用class实例化newInstance()-> servlet初始化
31 | Object obj = c.newInstance();
32 | //将servlet放入ServletContext中
33 | ServletContext.servlets.put(servletName, obj);
34 | if(obj instanceof HttpServlet){
35 | servlet = (HttpServlet)obj;
36 | servlet.init();
37 | }
38 | } catch (Exception e) {
39 | e.printStackTrace();
40 | }
41 | }else{
42 | servlet = (HttpServlet) ServletContext.servlets.get(servletName);
43 | }
44 | servlet.service(request, response);
45 |
46 | }
47 |
48 | }
49 |
50 |
51 |
--------------------------------------------------------------------------------
/src/server/ServerService.java:
--------------------------------------------------------------------------------
1 | package server;
2 |
3 | import servlet.HttpServletRequest;
4 | import servlet.HttpServletResponse;
5 |
6 | import java.io.IOException;
7 | import java.io.InputStream;
8 | import java.io.OutputStream;
9 | import java.net.Socket;
10 |
11 | /**
12 | * @description: 处理接口
13 | * @author: WangZhiJun
14 | * @create: 2019-07-26 09:44
15 | **/
16 | public class ServerService implements Runnable{
17 | private Socket s;
18 |
19 | ServerService(Socket s) {
20 | super();
21 | this.s = s;
22 | }
23 |
24 | @Override
25 | public void run() {
26 | InputStream iis;
27 | OutputStream oos;
28 | try {
29 | iis = s.getInputStream();
30 | oos = s.getOutputStream();
31 | } catch (IOException e) {
32 | e.printStackTrace();
33 | System.out.println("客户端"+this.s.getRemoteSocketAddress()+"掉线");
34 | return;
35 | }
36 | //http是一个基于请求与响应的协议
37 | //1、创建一个请求对象
38 | HttpServletRequest request = new HttpServletRequest(iis);
39 | //2、创建一个响应对象
40 | HttpServletResponse response = new HttpServletResponse(request, oos);
41 | String uri = request.getRequestURI();
42 | //判断是动态的还是静态的请求
43 | Processor processor;
44 | //如果是动态的请求,则创建DynamicProcessor
45 | //未简化时间,此处认为请求信息里有.action为动态请求
46 | if(uri.indexOf(".action")>0){
47 | processor = new DynamicProcessor();
48 | }else{
49 | //如果是静态的请求,则创建StaticProcessor
50 | processor = new StaticProcessor();
51 | }
52 | processor.process(request, response);
53 | try {
54 | //http是无状态的短连接
55 | s.close();
56 | } catch (IOException e) {
57 | e.printStackTrace();
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/servlet/HttpServletResponse.java:
--------------------------------------------------------------------------------
1 | package servlet;
2 |
3 | import java.io.ByteArrayOutputStream;
4 | import java.io.File;
5 | import java.io.FileInputStream;
6 | import java.io.IOException;
7 | import java.io.OutputStream;
8 | import java.io.PrintWriter;
9 | import java.util.Date;
10 |
11 | /**
12 | * @description: HttpServletResponse
13 | * @author: WangZhiJun
14 | * @create: 2019-07-26 09:44
15 | **/
16 | public class HttpServletResponse {
17 | private HttpServletRequest request;
18 | private OutputStream oos;
19 |
20 | private String webRoot = System.getProperty("user.dir")+File.separator+"static";
21 | public HttpServletResponse(HttpServletRequest request, OutputStream oos) {
22 | this.request=request;
23 | this.oos = oos;
24 | }
25 | public PrintWriter getWriter(){
26 | return new PrintWriter(this.oos);
27 | }
28 |
29 | /**
30 | * 响应文件输出HTML,JPEG,gif
31 | * 响应码404,500,200
32 | */
33 | public void sendRedirect() {
34 | int code = 200;
35 | //1.取出request中的uri
36 | String uri = this.request.getRequestURI();
37 | File file;
38 | String fileName;
39 | if(uri.endsWith("/")){
40 | fileName = uri+"index.html";
41 | }else{
42 | fileName = uri;
43 | }
44 | file = new File(webRoot,fileName);
45 | //2.拼装file 查看是否存在
46 | //不存在则404
47 | if(!file.exists()){
48 | file = new File(webRoot,"404.html");
49 | code = 404;
50 | }
51 | //3、存在,找到这个文件,读出来
52 | //4、发送文件响应,不同的文件返回不同类型
53 | if(file.getName().endsWith(".jpg")){
54 | send(file,"application/x-jpg",code);
55 | }else if(file.getName().endsWith(".jpe")||file.getName().endsWith(".jpeg")){
56 | send(file,"image/jpeg",code);
57 | }else if(file.getName().endsWith(".gif")){
58 | send(file,"image/gif",code);
59 | }else if(file.getName().endsWith(".css")){
60 | send(file,"text/css",code);
61 | }else if(file.getName().endsWith(".js")){
62 | send(file,"application/x-javascript",code);
63 | }else if(file.getName().endsWith(".swf")){
64 | send(file,"application/x-shockwave-flash",code);
65 | }else{
66 | send(file,"text/html",code);
67 | }
68 | }
69 |
70 | /**
71 | * 返回响应流
72 | */
73 | private void send(File file, String contentType, int code) {
74 | try {
75 | String responseHeader = genProtocol(file.length(),contentType,code);
76 | byte[] bs = readFile(file);
77 |
78 | this.oos.write(responseHeader.getBytes());
79 | this.oos.flush();
80 | this.oos.write(bs);
81 | this.oos.flush();
82 | } catch (IOException e) {
83 | e.printStackTrace();
84 | }finally{
85 | try {
86 | this.oos.close();
87 | } catch (IOException e) {
88 | e.printStackTrace();
89 | }
90 | }
91 | }
92 |
93 | /**
94 | * 读取文件
95 | */
96 | private byte[] readFile(File file) {
97 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
98 | FileInputStream fis = null;
99 |
100 | try {
101 | fis = new FileInputStream(file);
102 | byte[] bs = new byte[1024];
103 | int length;
104 | while((length = fis.read(bs,0,bs.length))!=-1){
105 | baos.write(bs, 0, length);
106 | baos.flush();
107 | }
108 | } catch (Exception e) {
109 | e.printStackTrace();
110 | }finally{
111 | try {
112 | fis.close();
113 | } catch (IOException e) {
114 | e.printStackTrace();
115 | }
116 | }
117 | return baos.toByteArray();
118 | }
119 |
120 | /**
121 | * 拼接响应协议
122 | */
123 | private String genProtocol(long length, String contentType, int code) {
124 | String result = "HTTP/1.1 "+code+" OK\r\n";
125 | result+="Server: myTomcat\r\n";
126 | result+="Content-Type: "+contentType+";charset=utf-8\r\n";
127 | result+="Content-Length: "+length+"\r\n";
128 | result+="Date: "+new Date()+"\r\n";
129 | result+="\r\n";
130 | return result;
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/src/servlet/HttpServletRequest.java:
--------------------------------------------------------------------------------
1 | package servlet;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.util.ArrayList;
6 | import java.util.Hashtable;
7 | import java.util.List;
8 | import java.util.Map;
9 | import java.util.UUID;
10 |
11 | /**
12 | * @description: HttpServletRequest
13 | * @author: WangZhiJun
14 | * @create: 2019-07-26 09:44
15 | **/
16 | public class HttpServletRequest {
17 |
18 | /**
19 | * 请求方法
20 | */
21 | private String method;
22 | /**
23 | * 请求地址
24 | */
25 | private String requestURI;
26 |
27 | private String jsessionid = null;
28 |
29 | /**
30 | * 请求体
31 | */
32 | private String content;
33 | /**
34 | * 请求头
35 | */
36 | private Map headers = new Hashtable<>();
37 | /**
38 | * 请求参数
39 | */
40 | private Map parameter = new Hashtable<>();
41 | /**
42 | * 请求cookie信息
43 | */
44 | private List cookies = new ArrayList<>();
45 |
46 |
47 | public String getJsessionid() {
48 | return jsessionid;
49 | }
50 | public List getCookies() {
51 | return cookies;
52 | }
53 | public String getParameter(String key) {
54 | return parameter.get(key);
55 | }
56 |
57 | public HttpServletRequest(InputStream iis) {
58 | //一次性读完所有请求信息
59 | StringBuilder sb = new StringBuilder();
60 | int length = -1;
61 | byte[] bs = new byte[100*1024];
62 | try {
63 | length = iis.read(bs);
64 | } catch (IOException e) {
65 | e.printStackTrace();
66 | System.out.println("读取客户请求异常");
67 | }
68 | //将bs中的字节数据转为char
69 | for(int i = 0;i0) {
113 | for(Cookie c:cookies) {
114 | if("JSESSIONID".equals(c.getName())) {
115 | return c.getValue();
116 | }
117 | }
118 | }
119 | return null;
120 | }
121 |
122 | /**
123 | * headers中取出cookie,然后在解析出cookie对象存在cookies中
124 | */
125 | private void parseCookie() {
126 | if(headers==null&&headers.size()<=0){
127 | return;
128 | }
129 | //从headers中取出键为cookie的
130 | String cookieValue = headers.get("Cookie");
131 | if(cookieValue == null || cookieValue.length()<=0) {
132 | return;
133 | }
134 | String[] cvs = cookieValue.split(": ");
135 | if(cvs.length > 0) {
136 | for(String cv:cvs) {
137 | String[] str = cv.split("=");
138 | if(str.length > 0) {
139 | String key = str[0];
140 | String value = str[1];
141 | Cookie c = new Cookie(key,value);
142 | cookies.add(c);
143 | }
144 | }
145 | }
146 | }
147 | private void parseHeader() {
148 | //请求头
149 | String[] parts = this.content.split("\r\n\r\n");
150 | //GET /请求地址 HTTP/1.1
151 | String[] headerss = parts[0].split("\r\n");
152 | for(int i = 1;i=1){
170 | String[] pairs = this.requestURI.substring(index+1).split("&");
171 | for(String p:pairs){
172 | String[] po = p.split("=");
173 | parameter.put(po[0], po[1]);
174 | }
175 | }
176 | if(this.method.equals("POST")){
177 | String[] parts = this.content.split("\r\n\r\n");
178 | String entity = parts[1];
179 | String[] pairs = entity.split("&");
180 | for(String p:pairs){
181 | String[] po = p.split("=");
182 | parameter.put(po[0], po[1]);
183 | }
184 | }
185 | }
186 | public String getMethod() {
187 | return method;
188 | }
189 | public String getRequestURI() {
190 | return requestURI;
191 | }
192 | public Map getHeaders() {
193 | return headers;
194 | }
195 |
196 |
197 |
198 | }
199 |
--------------------------------------------------------------------------------
/.idea/junitgenerator-prj-settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/uiDesigner.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | -
6 |
7 |
8 | -
9 |
10 |
11 | -
12 |
13 |
14 | -
15 |
16 |
17 | -
18 |
19 |
20 |
21 |
22 |
23 | -
24 |
25 |
26 |
27 |
28 |
29 | -
30 |
31 |
32 |
33 |
34 |
35 | -
36 |
37 |
38 |
39 |
40 |
41 | -
42 |
43 |
44 |
45 |
46 | -
47 |
48 |
49 |
50 |
51 | -
52 |
53 |
54 |
55 |
56 | -
57 |
58 |
59 |
60 |
61 | -
62 |
63 |
64 |
65 |
66 | -
67 |
68 |
69 |
70 |
71 | -
72 |
73 |
74 | -
75 |
76 |
77 |
78 |
79 | -
80 |
81 |
82 |
83 |
84 | -
85 |
86 |
87 |
88 |
89 | -
90 |
91 |
92 |
93 |
94 | -
95 |
96 |
97 |
98 |
99 | -
100 |
101 |
102 | -
103 |
104 |
105 | -
106 |
107 |
108 | -
109 |
110 |
111 | -
112 |
113 |
114 |
115 |
116 | -
117 |
118 |
119 | -
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | server.*
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 | kittyCat
166 | webapps
167 | pro
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 | true
201 | DEFINITION_ORDER
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 | 1564105284307
318 |
319 |
320 | 1564105284307
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
--------------------------------------------------------------------------------