`
cwqcwq
  • 浏览: 75697 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

打造自己的web容器(3)

    博客分类:
  • j2ee
阅读更多
---- 一个简单的servlet容器

上一篇讲到,我们的web容器已经可以读取静态资源,在这一篇中,我将建立一个简单的servlet容器,之所以简单,是因为有它的局限性,在后面我会总结,余下的问题我将在下一篇中一一解决。

本篇的第一个servlet容器主要完成如下功能:
    * 等待HTTP请求。
    * 构造一个ServletRequest对象和一个ServletResponse对象。
    * 假如该请求需要一个静态资源的话,调用StaticResourceProcessor实例的process方法,同时传递ServletRequest和ServletResponse对象。
    * 假如该请求需要一个servlet的话,加载servlet类并调用servlet的service方法,同时传递ServletRequest和ServletResponse对象。
    注意:在这个servlet容器中,每一次servlet被请求的时候,servlet类都会被加载。

第一个servlet容器由以下类组成:
    * HttpServer:容器的启动类,
    * Request:实现了ServletRequest
    * Response:实现了ServletResponse
    * IProcessor:处理器接口,后期会演变为连接器
      * StaticResourceProcessor:处理静态资源
      * ServletProcessor:处理servlet调用
    * MyClassLoader:继承自ClassLoader,用于加载class
    * Constants:常量

上一篇已经对部分代码作了解释,接下来,我会对新增的代码作解释。

HttpServer类:

// create Response object
Response response = new Response(output);
response.setRequest(request);
if (request.getUri().startsWith("/servlet/")) {		//暂时的实现,如果路径以 /servlet/ 开头则认为是调用servlet
	IProcessor processor = new ServletProcessor();
	processor.process(request, response);
}
else {
	IProcessor processor = new StaticResourceProcessor();
	processor.process(request, response);
}
// Close the socket
socket.close();


Response类:

public class Response implements ServletResponse {

	//...省略ServletResponse的方法实现

	public PrintWriter getWriter() throws IOException {

		// autoflush is true, println() will flush,
		// but print() will not.
		writer = new PrintWriter(output, true);
		return writer;
	}
}

Request类:

public class Request implements ServletRequest {

	//...省略ServletRequest的方法实现
	//其余方法与上一篇一致
}



ServletProcessor类:

public class ServletProcessor implements IProcessor {

	public void process(Request request, Response response) throws ServletException {

		String uri = request.getUri();
		String servletName = uri.substring(uri.lastIndexOf("/") + 1);
		ClassLoader loader = new MyClassLoader(this.getClass().getClassLoader());
		Class< ? > servletClass = null;
		try {
			servletClass = loader.loadClass(servletName);//加载class
		}
		catch (ClassNotFoundException e) {
			throw new ServletException(e);
		}
		Servlet servlet = null;
		if (null != servletClass) {
			try {
				servlet = (Servlet) servletClass.newInstance();
				servlet.service(request, response);
			}
			catch (Exception e) {
				throw new ServletException(e);
			}
		}
	}
}

StaticResourceProcessor类:

public class StaticResourceProcessor implements IProcessor {

	public void process(Request request, Response response) throws ServletException, IOException {

		response.sendStaticResource();//直接读取资源
	}
}

Constants类:

public class Constants {

	/* WEB容器的根目录 */
	public static final String WEB_ROOT = System.getProperty("user.dir") + File.separator + "WebContent";

	/* class的根路径 */
	public static final String CLASS_PATH = WEB_ROOT + File.separator + "WEB-INF" + File.separator + "classes";

}

MyClassLoader类:

public class MyClassLoader extends ClassLoader {

	private String classPath = null;

	protected MyClassLoader(ClassLoader parent) {

		super(parent);
		init();
	}

	private void init() {

		classPath = Constants.CLASS_PATH;

	}

	/* 
	 * 此方法应该被类加载器的实现重写,该实现按照委托模型来加载类
	 * @see java.lang.ClassLoader#findClass(java.lang.String)
	 */
	protected Class< ? > findClass(String className) throws ClassNotFoundException {

		String classFileName = className.replace('.', '/') + ".class";
		URL url = findResource(classFileName);
		byte[] bytes = null;
		if (null == url) {
			throw new ClassNotFoundException("Can't find [" + className + "]");
		}
		else {
			InputStream input = null;
			try {
				input = url.openStream();
				if (input == null) {
					throw new ClassNotFoundException("Can't load [" + className + "]");
				}
				else {
					ByteArrayOutputStream baos = new ByteArrayOutputStream(10240);
					byte[] buf = new byte[1024];
					int bytesRead = 0;
					while (bytesRead >= 0) {
						baos.write(buf, 0, bytesRead);
						bytesRead = input.read(buf);
					}
					bytes = baos.toByteArray();
				}
			}
			catch (IOException e) {
				throw new ClassNotFoundException(className, e);
			}
			finally {
				try {
					input.close();
				}
				catch (IOException ingore) {
				}
			}
		}
		Class< ? > theClass = defineClass(className, bytes, 0, bytes.length);
		if (theClass == null)
			throw new ClassFormatError();
		return theClass;
	}

	/* 
	 * 查找具有给定名称的资源。类加载器实现应该重写此方法,以指定从何处查找资源
	 * @see java.lang.ClassLoader#findResource(java.lang.String)
	 */
	protected URL findResource(String name) {

		try {
			URL url = super.findResource(name);
			if (null != url) {
				return url;
			}
			File path = new File(classPath);
			if (path.isDirectory()) {
				String pathRoot = path.getCanonicalPath();
				StringBuffer sb = new StringBuffer(pathRoot);
				sb.append(File.separator).append(name);
				File resourceFile = new File(sb.toString());
				if (resourceFile.exists()) {
					System.out.println("Resource [" + name + "] was found, in [" + pathRoot + "]");
					url = new URL("file:///" + resourceFile.getCanonicalPath());
				}
			}
			if (null == url) {
				return null;
			}
			else {
				return url;
			}
		}
		catch (IOException ex) {
			return null;
		}
	}
}


测试servlet:MyPrimitiveServlet

public class MyPrimitiveServlet implements Servlet {

	public void destroy() {}

	public ServletConfig getServletConfig() {}

	public String getServletInfo() {}

	public void init(ServletConfig arg0) throws ServletException {}

	public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
		System.out.println("from service");
		PrintWriter out = response.getWriter();
		out.println("Hello. MyServletContainer!");
		out.print("Violets are blue.");
	}
}


运行HttpServer,启动容器测试:
在浏览器中键入:http://localhost:8080/servlet/MyPrimitiveServlet
出现如下界面,则表明servlet调用成功:



第一个servlet容器的主要问题:
1、未实现servlet的生命周期
2、Response的getWriter()输出有问题
3、向上转换Request实例为javax.servlet.ServletRequest存在一定的安全性

在下一篇中,我将一一解决上述问题,且从下一篇开始,整体架构将以模块化组成。
  • 大小: 41.1 KB
分享到:
评论

相关推荐

    QT-HTML.rar_QT_Qt webkit html_Qt5.4 Web容器_qt html

    5. **实例分析**:可能包含一些实际案例,如淘宝客户端如何利用QtWebKit实现特定的Web功能,展示如何在Qt应用中构建一个功能丰富的Web容器。 6. **最佳实践**:分享在开发过程中需要注意的问题,以及如何遵循最佳...

    改造Kuberntetes打造SAE容器云

    【标题】:“改造Kubernetes打造SAE容器云” 在现代云计算环境中,Kubernetes(K8s)已经成为容器编排的主流平台,它提供了一种高效、可扩展的方式来管理和部署容器化应用。SAE(Serverless Application Engine)是...

    java web workspace 02

    JSP页面会被Web容器转换为Servlet执行,生成动态内容。 3. **MVC框架(如Spring MVC)**:MVC(Model-View-Controller)是一种软件设计模式,广泛应用于Web开发中。Spring MVC是Spring框架的一部分,提供了一种组织...

    后端开发入门与实战教程:从0到1打造高效Web应用.zip

    这份"后端开发入门与实战教程:从0到1打造高效Web应用"的资源包,将引领初学者步入这一领域的殿堂,通过系统的学习和实践,使你能够构建出高效且稳定的Web应用。 首先,后端开发的基础知识主要包括编程语言、框架和...

    Web聊天室系统源码

    3. **JavaEE容器**:如Tomcat或Jetty,它们提供了一个运行JavaWeb应用程序的环境,管理Servlet的生命周期,并处理HTTP请求。 4. **MVC模式**:模型-视图-控制器架构模式在JavaWeb开发中广泛应用,它将业务逻辑、...

    基于C++开发的WEB服务器,支持C++、Python、Java等多语言混合开发WEB应用.rar

    cppweb同时也是一个跨平台的微服务开发框架,通过两个核心组件webrouter与webserver提供微服务系统中的接口路由网关、服务注册中心、业务服务容器、定时任务调度中心以及接口...,我们的目标不是实现一个最好cgi容器...

    webcalendar.js控件及其使用说明

    3. **初始化控件**:在JavaScript中创建WebCalendar实例,并指定对应的容器元素。 4. **设置属性**:根据需求调整日历的显示属性,如初始显示的日期、是否显示星期等。 5. **绑定事件**:如果需要,可以为日历的特定...

    阿里云 专有云企业版 V3.8.1 容器服务 产品简介 20200727

    该服务简化集群的搭建和扩容等运维工作,整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳的Kubernetes容器化应用运行环境。 容器服务的优势包括: 1. 使用便捷:通过 Web 界面一键创建 Kubernetes 集群,...

    Go-Cyclone是一个打造容器工作流的云原生持续集成持续发布平台

    3. **工作流编排**:Cyclone允许用户定义复杂的工作流,这些工作流可以包含多个阶段和步骤,例如构建、测试、部署等。每个阶段都可以配置不同的容器镜像和执行命令,确保了整个流程的灵活性。 4. **持续测试**:在...

    小图片,用于web小图片,用于web

    在互联网世界中,小图片,特别是那些优化过的用于Web的小图片,扮演着至关重要的角色。它们不仅能够快速加载,提高用户体验,还能...在实际工作中,应根据具体需求和目标,灵活运用这些技巧,打造高效、美观的Web页面。

    《Java Web应用开发技术实用教程》-王红-电子教案

    《Java Web应用开发技术实用教程》是一本专为学习Java Web开发的初学者和进阶者编写的教材,由王红老师倾力打造。这本书涵盖了Java Web开发的基础知识到高级技术,旨在帮助读者掌握构建动态网页和Web应用程序的技能...

    深入体验Java Web开发内幕

    6. **Web容器与Tomcat**: 了解如何部署和管理Java Web应用在Web容器(如Apache Tomcat)中的运行,包括WAR文件的打包和发布。 7. **Web安全**: 书中可能会讨论关于身份验证、授权、防止SQL注入和XSS攻击等Web安全...

    Echarts + Web实现大屏展示效果(一)图片资源

    2. **准备DOM元素**:创建用于显示图表的div容器,并设置合适的宽高。 3. **初始化Echarts实例**:使用`echarts.init()`方法创建Echarts实例,关联到指定的DOM元素。 4. **配置图表**:定义图表的类型、数据、样式等...

    PHPWEB分享式智能网站管理系统 v1.2.0.rar

    我们将逐步为不同行业用户量身打造行业模板,让您以最快捷的方式,最低的成本创建功能强大的企业网站。PHPWEB是您高效便捷的网站管理工具。PHPWEB可免费用于非商业用途,无需购买授权,直接安装使用。商业用户可以...

    Web经典图表控件 Highcharts控件

    3. 创建图表容器:在HTML中设置一个div元素作为图表的容器,为其设置ID以便于JavaScript操作。 4. 初始化图表:在JavaScript中,通过`new Highcharts.Chart()`方法初始化图表,指定图表容器ID、配置对象和数据。 ...

    tomcat6.0 适用与java web 程序的开发服务器

    《深入理解Tomcat 6.0:打造高效Java Web服务器》 Tomcat 6.0是一款广泛应用的开源Java Web服务器,由Apache软件基金会维护,它实现了Java Servlet和JavaServer Pages(JSP)规范,为Java Web应用程序提供了一个轻...

    [HeyJava][天一时代][WEB开发]05_Tomcat搭建项目

    Tomcat是一个开源的Java Servlet容器,它能够解析并执行基于Java Servlet和JavaServer Pages (JSP) 的Web应用程序。此描述暗示了课程将涉及安装、配置Tomcat以及部署Web项目的基本步骤。 【标签】:“java web 开发...

    阿里云 专有云企业版 V3.12.0 容器服务Kubernetes版 产品简介 20200727

    容器服务简化集群的搭建和扩容等运维工作,整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳的Kubernetes 容器化应用运行环境。 什么是容器服务 容器服务是高性能可伸缩的容器管理服务,支持企业级...

    Java_Web整合开发王者归来_10

    标签“java web 王者归来”暗示了该教程可能涵盖了一些高级主题,旨在将读者打造成Java Web开发的高手。 在Java Web开发中,整合开发通常涉及到多个技术和框架的协同工作,以构建高效、可维护的Web应用程序。以下是...

    java高手真经_系统架构卷:java.web系统设计与架构

    《Java高手真经_系统架构卷:Java.Web系统设计与架构》是一本专注于Java Web开发领域的专业书籍,由刘中兵及其Java研究室倾力打造。这本书深入探讨了Java技术在构建复杂Web系统中的应用,涵盖了从基础概念到高级设计...

Global site tag (gtag.js) - Google Analytics