自定义简单的(tomcat)web服务器

自从JSP发布之后,推出了各式各样的JSP引擎。Apache Group在完成GNUJSP1.0的开发以后,开始考虑在SUN的JSWDK基础上开发一个可以直接提供Web服务的JSP服务器,当然同时也支持Servlet, 这样Tomcat就诞生了。Tomcat是jakarta项目中的一个重要的子项目,其被JavaWorld杂志的编辑选为2001年度最具创新的java产品,同时它又是sun公司官方推荐的servlet和jsp容器,因此其越来越多的受到软件公司和开发人员的喜爱。servlet和jsp的最新规范都可以在tomcat的新版本中得到实现。其次,Tomcat是完全免费的软件,任何人都可以从互联网上自由地下载。Tomcat与Apache的组合相当完美。

当然这次我自定义的tomcat是很简单的,只解析出普通的html页面进行响应然后回送的是字符串到浏览器,其他的css什么的自然是不不支持的,一个基于Java的web服务器用到的两个重要类:java.net.Socket和java.net.ServerSock,当然通信用的是http协议。

好的,首先我们先新建一个tomcatServer入口类,这个类自然就是用serverSocket进行对socket的连接进行监听,然后再在线程中操作与浏览器的请求和响应:

<span style="font-size:18px;">import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class TomcatServer {
	/**
	 * @param args
	 *
	 * tomcatserver一有客户端上来就监听
	 * @throws IOException
	 */
	public static void main(String[] args)  {
		int port=Integer.parseInt((String)WebProperties.getInstance().get("port"));
		ServerSocket ss=null;
		try {
			ss = new ServerSocket(port);
		} catch (IOException e) {

			Utils.printException(e);
		}
		System.out.println(Utils.formatDate()+"\t服务器启动,监听"+ss.getLocalPort()+"端口");
		while(true){
			Socket s=null;
			try {
				s=ss.accept();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				Utils.printException(e);
			}
			System.out.println("客户端"+s.getRemoteSocketAddress()+"登陆上了服务器");
			//这是一个连接会话任务类,实现Runnable接口,网络操作需要启用线程
			//在会话任务类中
			HttpSessionTask hst=new HttpSessionTask(s);
			new Thread(hst).start();
		}

	}
}</span>

浏览器此时是客户端,我们监听了一个端口,然后只要有客户端连接上来我们就要在HttpSession中对浏览器的请求做处理了,在这里我们要建一个配置文件用来定义资源文件的位置和端口号,这样就可以容易修改这些配置项了:

path:c:\defaultpage=index.html
port=10000

此时配置项我们只需要加载一次,解析这个文件并要做成单例的:

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

//要求单例
public class WebProperties extends Properties {
private static WebProperties myProperties;

	private WebProperties() {
		//在这里完成读取db.properties文件
			InputStream iis=WebProperties.class.getClassLoader().getResourceAsStream( "web.properties");
			try {
				this.load(   iis );
			} catch (IOException e) {

				e.printStackTrace();
			}
	}
	//多个客户端上来时,防止多线程
	public synchronized static WebProperties getInstance() {
		if( myProperties==null){
			 myProperties=new WebProperties();
		}
		return myProperties;
	}
}

在HttpSession这个会话类中,需要完成接收请求和回送响应两个操作,在我们的java的web服务器中,HttpServletRequest是用来发送请求的,HttpServletResponse是用来回送响应的,我们也模仿java的这个机制,用这两个类对请求和响应做处理

HttpServletRequest类要做的是解析浏览器发来的http协议拿到请求头里的资源地址,然后HttpServletResponse得到资源地址后解析资源进行拼接协议响应头回送给客户端,这样一次请求到响应浏览器就可以显示出资源地址的内容了。

自定义的HttpServletRequest类:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
/**
 * 这个请求类对浏览器发送的协议进行解析,得到资源地址(这里只考虑get方法,参数拚在请求头中,这里解析出来后不做处理)
 * @author Administrator
 *
 */
public class HttpServletRequest {
	private String uri;
	private String method;
	private String protocolVersion;
	private Map<String,String> parameter=new HashMap<String,String>();
	private InputStream iis;
	//这个构造函数的iis是从socket中得到的输入流
	public HttpServletRequest( InputStream iis) throws IOException{
		this.iis=iis;
		parse();
	}
	//解析协议的方法   GET /company/index.html HTTP/1.1
	private void parse() throws IOException {
		BufferedReader br=new BufferedReader(new InputStreamReader(iis));
		String line=null;
		int i=0;
		if((line=br.readLine())!=null){
			if(i==0){
				parseCommandLine(line);
			}
			i++;
		}
	}
	private void parseCommandLine(String line) {
		if(line!=null&&!"".equals(line)){
			String [] strs=line.split(" ");
			method=strs[0];
			protocolVersion=strs[2];
			if("GET".equals(method)){
				doGet(strs[1]);
			}
		}
	}
	private void doGet(String str) {
		//解析是否有参数
		if(str.contains("?")){
			String[] strs=str.split("?");
			uri=strs[0];
			String[] ps=strs[1].split("&");
			for(String s:ps){
				String[] pp=s.split("=");
				parameter.put(pp[0], pp[1]);
			}
		}else{
			uri=str;
		}

	}
	//get方法参数的类
	public String getParameter(String key) {
		String value=parameter.get(key);
		if(!value.equals("")||!(value==null)){
			return value;
		}else{
			return null;
		}

	}
	public String getUri() {
		return uri;
	}
	public String getMethod() {
		return method;
	}
	public String getProtocolVersion() {
		return protocolVersion;
	}

}

自定义的HttpServletResponse类:

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

/**
 * 服务器响应类,这个类得到资源地址后对文件进行解析(这里只当字符全部输出),
 * 然后拼接响应头给浏览器浏览器接收后显示信息
 * @author Administrator
 *
 */
public class HttpServletResponse {
	private OutputStream oos;
	public HttpServletResponse(OutputStream oos){
		this.oos=oos;
	}
	public void redirect(String pageUrl){
		//输出流到客户端
		byte[] bs=new byte[1024];
		FileInputStream fis=null;
		File f=new File(pageUrl);
		if(!f.exists()){
			out404();
			return;
		}
		try {
			fis=new FileInputStream(f);
			StringBuffer sb=new StringBuffer();
			int length=-1;
			while((length=fis.read(bs,0,bs.length))!=-1){
				sb.append(new String(bs,0,length,"gbk"));
			}
			//正常的时候响应的协议
			String responseHead="HTTP/1.1 200 OK\r\nContent-Type: text/html;charset=gbk\r\nContent-Length: "+sb.toString().getBytes().length+"\r\n\r\n";
			out(responseHead,sb.toString());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			Utils.printException(e);
		}
	}
	private void out404() {
		String responseBody="<h1>没有页面</h1>";
		//TODO:
		String responseHead="HTTP/1.1 404 Not Found\r\nContent-Type: text/html;charset=utf-8\r\nContent=Length: "
			+responseBody.getBytes().length+"\r\n\r\n";
		try{
			out(responseBody,responseHead);

		}catch(Exception e){
			Utils.printException(e);
		}

	}
	private void out(String responseHead,String responseBody) throws IOException{
		oos.write(responseHead.getBytes());
		oos.write(responseBody.getBytes());
		oos.flush();
	}
}

最后一个就是我们的会话类了,这个类进行集中处理整个流程的操作:

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

/**
 *
 * @author Administrator
 *获取输入流,得到客户端传来的协议
 *将协议解析一个HttpServerletRequest对象(http://localhost/compay/index.html)
 *协议 GET /company/index.html HTTP/1.1
 */
public class HttpSessionTask implements Runnable {
	private Socket s;
	private InputStream iis;
	private OutputStream oos;
	private boolean flag=true;
	public HttpSessionTask(Socket s){
		this.s=s;
		try {
			iis=s.getInputStream();
			oos=s.getOutputStream();
		} catch (IOException e) {
			Utils.printException(e);
			flag=false;
		}

	}
	//因为http协议是一个无状态的,请求完后回应一次断开
	public void run() {
		if(flag==false){
			return;
		}

		try {
			//创建requset对象解析http协议的请求部分   GET /company/index.html HTTP/1.1
			//得到资源地址 /kaw/index.html
			//通过配置文件找到path c:\kaw\index.html
			//再创建response对象,调用redirect(path);
			HttpServletRequest request=new HttpServletRequest(iis);
			String uri=request.getUri();
			String filepath=WebProperties.getInstance().getProperty("path")+uri;
			HttpServletResponse response=new HttpServletResponse(oos);
			response.redirect(filepath);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			Utils.printException(e);
			out500(e);
		}finally{
			if(this.s!=null){
				try {
					s.close();
				} catch (IOException e) {

					e.printStackTrace();
				}
			}
		}
	}
	private void out500(Exception e) {
		//拼接协议输出错误信息
		//略

	}

}

好的,我们只需要在c盘放一个普通的html文件,启动tomcatserver类。

用浏览器访问地址:

网页就被读取出来了,当然这是个很简单的服务器,也只能操作普通文本,后续的学习希望可以深入服务器的学习,多多交流!

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-08 06:10:57

自定义简单的(tomcat)web服务器的相关文章

一个简单的Java web服务器实现

一个简单的Java web服务器实现,比较简单,基于java.net.Socket和java.net.ServerSocket实现: 程序执行步骤 创建一个ServerSocket对象: 调用ServerSocket对象的accept方法,等待连接,连接成功会返回一个Socket对象,否则一直阻塞等待: 从Socket对象中获取InputStream和OutputStream字节流,这两个流分别对应request请求和response响应: 处理请求:读取InputStream字节流信息,转成字

简单的Java Web服务器

1 import java.io.FileInputStream; 2 import java.io.OutputStream; 3 import java.net.ServerSocket; 4 import java.net.Socket; 5 6 public class Server { 7 8 /** 9 * @param args 10 */ 11 public static void main(String[] args) throws Exception{ 12 // TODO

tomcat web服务器优化

tomcat主要作为中间件在架构中出现,目前我们使用LNMJ的架构,tomcat用来处理动态请求,处理速度快,但是占用资源大,这只懒猫,想要跑得快就要给条大鱼,否则会影响主机性能 下面简单介绍下这次优化的内容 按照CIS-Tomcat7最新基线标准进行中间件层面基线检测 注意:禁止root登陆项请谨慎操作,禁止登陆后root账号不能直接等 检查项1: tomcat进程运行权限检测 路径: /application/tomcat当前值: 0 `加固建议: 请创建低权限的账号运行tomcat` 检查

嵌入式Tomcat Web服务器的使用

在运行web工程时,常常要频繁启动tomcat,使用嵌入式tomcat可以减少部分重复操作. 1.下载tomcat5.0.28embed.zip 解压文件夹复制到工程下. http://archive.apache.org/dist/tomcat/tomcat-5/v5.0.28/bin/jakarta-tomcat-5.0.28-embed.zip 2.源码实现 import java.io.File; import javax.servlet.ServletException; import

简单的面向对象-web服务器

import socket import re import multiprocessing class WSGIServer(object): def __init__(self): # 创建套接字 self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,

Java web基础总结三之—— java web 服务器

Java web基础总结三之-- java web 服务器 一.什么是java web服务器 首先来看一下什么是web服务器,它一般指网站服务器,是指一个再互联网一个主机上的一个程序.它可以解析客户端发送来的遵循http协议的请求,并且经过逻辑业务处理后,以http协议向浏览器等Web客户端提供文档. 互联网上供外界访问的Web资源可以分为两种:一个是静态web资源(如html 页面),指web页面中供人们浏览的数据始终是不变.另一个动态web资源,指web页面中供人们浏览的数据是由程序动态产生

从零开始搭建论坛(一):Web服务器与Web框架

之前用 Django 做过一个小的站点,感觉Django太过笨重,于是就准备换一个比较轻量级的 Web 框架来玩玩.Web.py 作者已经挂掉,项目好久没有更新,所以不准备用它.而 Flask 也是一个成熟的轻量级 Web 框架,在 github 上有众多的 Star 和 Fork,文档和扩展也很丰富,值得学习. 学习一个框架最好的方式就是用框架做一个项目,在实战中理解掌握框架.这里我用 Flask 框架,使用 Mysql 数据库做了一个论坛系统.麻雀虽小,五脏俱全,论坛效果图如下: 下面是论坛

深入浅出web服务器与python应用程序之间的联系

简单来说,Web服务器是在运行在物理服务器上的一个程序,它永久地等待客户端(主要是浏览器,比如Chrome,Firefox等)发送请求.Web 服务器接受 Http Request,返回 Response,很多时候 Response 并不是静态文件,因此需要有一个应用程序根据 Request 生成相应的 Response.这里的应用程序主要用来处理相关业务逻辑,读取或者更新数据库,根据不同 Request 返回相应的 Response.两者之间的桥梁就是WSGI. 一直喜欢研究比较底层的技术,

基于C# Socket的Web服务器---静态资源处理

Web服务器是Web资源的宿主,它需要处理用户端浏览器的请求,并指定对应的Web资源返回给用户,这些资源不仅包括HTML文件,JS脚本,JPG图片等,还包括由软件生成的动态内容.为了满足上述需求,一个完整的Web服务器工作流程: 1)   服务器获得浏览器通过TCP/IP连接向服务器发送的http请求数据包. 2)   HTTP请求经过Web服务器的HTTP解析引擎分析得出请求方法.资源地址等信息,然后开始处理. 3)   对于静态请求,则在服务器上查询请求url路径下文件,并返回(如果未找到则

Node.js 的Web 服务器--Fenix

Fenix 是提供给开发人员使用的简单的一个 Web 服务器, 是基于 Node.js 开发.可以同时在上面运行很多的项目, 最适合前端开发人员使用. 可以通过免费的 Node.js 控制台创建,停止,启动和共享 Fexix 服务器. 您可以通过把你的桌面变成一个公共的 Web 服务器,让大家能看到你的web服务. Fenix官方 Node.js 的Web 服务器--Fenix