servlet接口

  使用servlet编程需要实现或者继承实现了javax.servlet.Servlet接口的类,其中定义了5个签名方法:

 public void init(ServletConfig config) throws ServletException
public void service(ServletRequest req,ServletResponse res) throws ServletException,java.io.IOException
public void destroy()
public ServletConfig getServletConfig()
public java.lang.String getServletInfo()

init(),service(),destroy对应着servlet的生命周期,init只在加载该servlet时执行且只此一次,容器根据用户请求调用对应servlet的service执行方法,当实例销毁移除前容器调用destroy处理后续操作。

模拟容器主要工作流程:

  • 等待http请求
  • 根据请求创建对应Request与Response对象
  • 如果请求的是静态资源,则调用StaticResourceProcessor发送对应资源
  • 如果请求是servlet,则加载该类并执行其service方法
简单servlet容器

主要类信息如下:

  1. HttpServer  与web服务器类似,不同的是加入了servlet请求判断,并调用ServletProcessor处理对应servlet
  2. Request   与上一篇web服务器类似,但是实现了ServletRequest接口
  3. Response   与上一篇web服务器类似,但是实现了ServletResponse接口
  4. StaticResourceProcessor  用于处理请求静态资源时调用
  5. ServletProcessor 用于当请求是servlet时调用
  6. Constant 定义一些常量
  7. MyLogger 自己定义在控制台打印日志信息,可以忽略
  8. PrimitiveServlet 实现servlet接口,自定义servlet程序用于请求调用

说明:部分接口只是实现了需要用到的方法,并没有完全实现所有方法,使用默认即可,代码里面没有贴出来

(一)HttpServer 
 public class HttpServer {
MyLogger logger = new MyLogger<>(HttpServer.class);
private static final String SHUTDOWN_COMMAND = "/SHUTDOWN";
private boolean shutdown = false; public void await() {
ServerSocket serverSocket = null;
int port = 8080;
try {
serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
logger.log("server started......." + "at " + serverSocket.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.exit(1);
}
while (!shutdown){
Socket socket = null;
InputStream inputStream = null;
OutputStream outputStream = null;
try {
socket = serverSocket.accept();
logger.log("accepted new request...");
inputStream = socket.getInputStream();
outputStream = socket.getOutputStream();
Request request = new Request(inputStream);
request.Parse();
Response response = new Response(outputStream);
response.setRequest(request);
logger.log("inition done,begin process.......");
if(request.getUri() == null){
logger.log("request uri is null...close socket");
socket.close();
continue;
}
else if(request.getUri().startsWith("/servlet/")){
logger.log("execute servlet...");
ServletProcessor servletProcessor = new ServletProcessor();
servletProcessor.process(request, response);
}
else {
logger.log("send staticResource...");
StaticResourceProcessor staticResourceProcessor = new StaticResourceProcessor();
staticResourceProcessor.process(request, response);
}
socket.close();
shutdown = request.getUri().equals(SHUTDOWN_COMMAND);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
(二)Request 
 public class Request implements ServletRequest{

     MyLogger logger = new MyLogger(ServletRequest.class);
private String uri;
private InputStream in; public Request(InputStream in){
this.in = in;
} public String parseUri(String request){
int index1,index2;
index1 = request.indexOf(" ");
if (index1 != -1){
index2 = request.indexOf(" ", index1+ 1);
if (index1 < index2)
return request.substring(index1 + 1, index2);
}
return null;
} public void Parse(){
StringBuffer request = new StringBuffer(2048);
byte[] bs = new byte[2048];
int i;
try {
i = in.read(bs);
} catch (IOException e) {
e.printStackTrace();
i = -1;
} for(int j=0; j<i; j++){
request.append((char)bs[j]);
} logger.log(request.toString());
uri = parseUri(request.toString());
if(uri != null)
logger.log("uri is " + uri);
} public String getUri() {
return uri;
}
}
(三)Response 
 public class Response implements ServletResponse{

     MyLogger logger = new MyLogger(Response.class);
private static final int BUFFER_SIZE = 1024;
private Request request;
private OutputStream out;
private PrintWriter writer; public Response(OutputStream out) {
this.out = out;
} public void setRequest(Request request) {
this.request = request;
}
//假设请求的是图片资源
public void sendStaticResource() throws IOException{
byte[] buffer = new byte[BUFFER_SIZE];
FileInputStream fis = null;
File file = new File(Constant.WEB_ROOT, request.getUri());
try {
logger.log("Begin read file + " + file.toString());
fis = new FileInputStream(file);
String headerMsg = "HTTP/1.1 200 OK\r\n" +
"Content-Type: image/jpg\r\n" +
"Content-Length: " + file.length() + "\r\n" +
"\r\n" ;
logger.log("headerMsg->\r\n" + headerMsg);
out.write(headerMsg.getBytes());
int ch = fis.read(buffer, 0, BUFFER_SIZE);
while (ch != -1){
out.write(buffer, 0, BUFFER_SIZE);
ch = fis.read(buffer, 0, BUFFER_SIZE);
}
} catch (FileNotFoundException e) {
String html = "<h1>file not found</h1>";
logger.log("FileNotFoundException");
String errorMsg = "HTTP/1.1 404 file not found\r\n" +
"Content-Type: text/html\r\n" +
"Content-Length: " + html.getBytes().length + "\r\n" +
"\r\n" +
html;
out.write(errorMsg.getBytes());
logger.log("errorMsg->" + errorMsg);
}
finally {
if(fis != null){
fis.close();
}
}
}
}
(四)StaticResourceProcessor 
 public class StaticResourceProcessor {
public void process(Request request,Response response) {
try {
response.sendStaticResource();
} catch (IOException e) {
e.printStackTrace();
}
}
}
(五)ServletProcessor 
 public class ServletProcessor {
public void process(Request request,Response response){
String uri = request.getUri();
String servletName = uri.substring(uri.lastIndexOf("/") + 1);
URLClassLoader loader = null; URL[] urls = new URL[1];
URLStreamHandler urlStreamHandler = null;
File classPath = new File(Constant.WEB_ROOT);
try {
String repository = (new URL("file",null,classPath.getCanonicalPath() +
File.separator)).toString();
urls[0] = new URL(null,repository,urlStreamHandler);
loader = new URLClassLoader(urls);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Class myClass = null;
try {
myClass = loader.loadClass(servletName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} Servlet servlet = null;
try {
servlet = (Servlet) myClass.newInstance();
servlet.service((ServletRequest)request, (ServletResponse) response); } catch (InstantiationException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ServletException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}
(六)MyLogger 
 public  class MyLogger<T> {
private String classStr = ""; public void log(T msg){
System.out.println(classStr + "(" +
(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date()) + ")" + ": " + msg);
}
public MyLogger(Class classz){
classStr = classz.getName();
}
}
(七)PrimitiveServlet 
 public class PrimitiveServlet implements Servlet{
MyLogger Logger = new MyLogger<>(PrimitiveServlet.class);
@Override
public void destroy() {
// TODO Auto-generated method stub } @Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return null;
} @Override
public String getServletInfo() {
// TODO Auto-generated method stub
return null;
} @Override
public void init(ServletConfig arg0) throws ServletException {
// TODO Auto-generated method stub } @Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
Logger.log("service execute.....");
PrintWriter writer = response.getWriter();
writer.println("Hey,welcome on board!");
writer.println("lets rock!");
} }
(八)Constant 
public class Constant {
public static final String WEB_ROOT =
System.getProperty("user.dir") + File.separator + "bin";
}

理解与模拟一个简单servlet容器的更多相关文章

  1. 一个简单servlet容器

    一个简单servlet容器 2.1 javax.servlet.Servlet接口 Servlet编程需要使用javax.servlet和javax.servlet.http两个包下的接口和类 在所有 ...

  2. 理解与模拟一个简单web服务器

    先简单说下几个概念,根据自己的理解,不正确请见谅. web服务器 首先要知道什么是web服务器,简单说web服务器就是可以使用HTTP传输协议与客户端进行通信的服务器.最初的web服务器只能用来处理静 ...

  3. 模拟一个简单的tomcat

    目录 简单处理 每个请求一个线程 模拟tomcat 参考 简单处理 // 客户端和服务器的通信,说到底就是两个数据的传输, // 客户端发送inputStream给服务器,服务器回复 // outpu ...

  4. 自定义模拟一个Spring IOC容器

    一.模拟一个IOC容器: 介绍:现在,我们准备使用一个java project来模拟一个spring的IOC容器创建对象的方法,也就是不使用spring的jar自动帮助我们创建对象,而是通过自己手动书 ...

  5. 【模块化编程】理解requireJS-实现一个简单的模块加载器

    在前文中我们不止一次强调过模块化编程的重要性,以及其可以解决的问题: ① 解决单文件变量命名冲突问题 ② 解决前端多人协作问题 ③ 解决文件依赖问题 ④ 按需加载(这个说法其实很假了) ⑤ ..... ...

  6. 使用Socket模拟一个简单的Webservice调用

    webservice是对socket的一个封装,让远程调用调用变得更加简单,那么使用socket究竟有多么麻烦呢?来看看. 做一个简单的天气查询: 服务端: public class SocketSe ...

  7. 模拟一个简单的基于tcp的远程关机程序(转)

    最近在学习unix网络编程,现在正在学习tcp的通信.其实,只要建立起了tcp通信,操作远端的计算机就不是什么问题了.正向telnet一样,也是基于tcp/IP协议的.所以这个实验,也算是对telne ...

  8. java模拟一个简单的QQ

    v 项目源码 https://github.com/hjzgg/java_QQ v 标题效果       package testFour; import java.awt.Color; import ...

  9. spring 理解Spring AOP 一个简单的约定游戏

    应该说AOP原理是Spring技术中最难理解的一个部分,而这个约定游戏也许会给你很多的帮助,通过这个约定游戏,就可以理解Spring AOP的含义和实现方法,也能帮助读者更好地运用Spring AOP ...

随机推荐

  1. 新手接触java

    第二个程序,求同时被3,5,7整除

  2. 线程学习笔记(EventWaitHandler)AutoResetEvent的使用

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  3. 主DNS配置

    一,安装BIND [root@localhost ~]# yum install bind bind-chroot bind-utils Loaded plugins: product-id, sub ...

  4. Makefile技术和应用总结

    如何学习和运用Makefile 怎么写Makefile?不想讲太多如何如何做.Makefile这东西,公司让一两个人来负责就好了,否则一定是一锅粥.每次看到招聘广告里说,要求懂Makefile,懂Li ...

  5. jsp中利用response.senddirect(str)重定向,传递参数新思路

    用Servlet进行请求重定向,参数传递好办,直接用request.setAttribute(str1,str2); 但是如果不用Servlet 而是直接用jsp进行转发呢? 我们首先要知道   请求 ...

  6. How to Read a Book

    主题: 讲述阅读的四种层次,以及每种层次所需要的.截然不同的阅读方法. 主要声明与论点: 带着问题阅读,时刻不忘在书中寻找问题的答案: 高速阅读,以最短的时间了解一本书的全貌,然后决定是否值得再次阅读 ...

  7. NoSQL精粹(NoSQL Distilled)——序言

    之前说到博客长草的问题,想了想除了很忙特别忙非常忙各种瞎忙忙你妹啊外,主要还是不知道写什么好--到这家公司的两年中从JS到领域驱动到缓存服务器从前端到后端各种折腾,有些东西虽然有所心得,不过既然前人已 ...

  8. elixir 高可用系列(四) Task

    概述 之前学习的 Agent,GenSever以及GenEvent,都是用来管理状态或者处理消息的. 但是在很多时候,我们需要的是执行某个任务,这时如果使用 GenSever 或者 GenEvent, ...

  9. 【原创】Windows Server 文件夹权限小问题

    服务器:Windows Server 2008 R2 Standard 做文件服务器 问题:在资源管理器里给账号设置了R/W权限,但是一直有问题,写失败. 解决:需要在server manager-r ...

  10. Asp.Net Web API 2第十三课——ASP.NET Web API中的JSON和XML序列化

    前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文描述ASP.NET W ...