热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

浅谈web服务器项目中静态请求和动态请求处理

这篇文章主要介绍了浅谈web服务器项目中静态请求和动态请求处理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着

注:完整项目下载

在处理了核心任务之后,我们会发现有些请求并不是都是静态的,那么我们就需要进行实现处理动态请求的要求,如下面代码是我们请求的解决方式,我们只需在HttpRequestImpl实现类中,将如下代码实现具体的判断过程

  //判断当前请求的否是静态资源
  public boolean isStaticResource(){
    return true;
  }
  //判断当前请求的否是动态资源
  public boolean isDynamicResource(){
    return true;
  }

1、实现isStaticResource()方法:

// 判断当前请求的否是静态资源
  public boolean isStaticResource() {
    // 存在??文件??静态??
    System.out.println("进入isStaticResource()方法");   
    if (requestPath != null) {
      String parent = ConfigUtils.getConfigValue("rootPath");
      File file = new File(parent, requestPath);
      return file.exists() && file.isFile();
    }
    return false;
  }

2、实现isDynamicResource():

  // 判断当前请求的否是动态资源
  public boolean isDynamicResource() {
    // 存在??文件??动态??
    System.out.println("进入isDynamicResource()方法");
    String path = ServletMappingUtils.getMappingValue(requestPath);
    /*
     * //使用路径判断,当时我不知道还有一个叫做isContains(key)的方法,如果知道的话 就可以使用了,请参见测试类
     * if(isContainers(requestPath())) { return *; }
     */
    System.out.println("ServletMapping中根据requestPath获取的映射:" + path);
    if (path != null) {
      return true;
    }
    return false;
  }

在动态方法中,我们String path = ServletMappingUtils.getMappingValue(requestPath);来获取请求的资源的路径,如果存在值的话就返回结果,其实现如下所示,对于servlet_mapping.properties文件,还是复制到项目下即可:

package com.sample.utils;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class ServletMappingUtils {
	private static Properties p;
	static 
	{
		InputStream in=null;
		p=new Properties();
		try {
			//读了xx.properties文件
			in=ServletMappingUtils.class.getResourceAsStream("servlet_mapping.properties");
			//放置到p中,即放properties文件中的key,value
			p.load(in);
		} catch (IOException e) {
			e.printStackTrace();
		}
		finally
		{
			if(in!=null)
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
		}
	}
	public static String getMappingValue(String mapping)
	{ 
		return p.getProperty(mapping);
	}
	public static boolean isContainsKey(String key) {
     return p.containsKey(key);
	}
	public static void main(String[] args) {//输出测试
	//	Properties p=new Properties();
	//	p.setProperty("rootPath","ddd");
	//	System.out.println(p.get("rootPath"));
		System.out.println(getMappingValue("/HelloWorld"));
		System.out.println(isContainsKey("/Login"));
	}
}

3、实现对静态请求和动态请求的封装

  在处理完基本的功能性要求之后,我们实现对核心任务取得封装,在封装时,我们仍然采用类实现接口的方式,首先我们需要明确该确定一个怎么样的接口,其代码如下:

package com.sample.http;
//Http资源处理器
//负责处理http协议的资源请求
public interface HttpAccessProcessor {	
	//处理静态资源 页面/文件/图片等等
	public void processStaticResource(HttpRequest request,HttpResponse response);	
	//处理动态资源 java代码 浏览器通过路径发送请求可以访问调用java代码
	public void processDynamicResource(HttpRequest request,HttpResponse response);	
	//向浏览器返回错误信息及其页面
	public void sendError(int statusCode,HttpRequest request,HttpResponse response);	
}

其实现类如下所示:

package com.sample.http;
import com.sample.utils.ServletMappingUtils;
//Http资源处理器
//负责处理http协议的资源请求
public class HttpAccessProcessorImpl implements HttpAccessProcessor {
	//处理静态资源 页面/文件/图片等等
	public void processStaticResource(HttpRequest request,HttpResponse response)
	{
		System.out.println("进入方法processStaticResource(HttpRequest request,HttpResponse response)");
		//获取请求中资源,并处理
        String path=request.getRequestPath();
        String[] str=path.split("[.]");
        String cOntentType=str[str.length-1];
        System.out.println("路径的后缀:"+contentType);
		response.setStatusLine(200);
		response.setContentType(MIMEUtils.getMimeValue(contentType));
		response.setCRLF();
		response.printResponseHeader();
		response.printResponseContent(request.getRequestPath());
	}
	//处理动态资源 java代码 浏览器通过路径发送请求可以访问调用java代码
	public void processDynamicResource(HttpRequest request,HttpResponse response)
	{
		System.out.println("进入processDynamicResource");
		response.setStatusLine(200);
		response.setContentType("text/HTML");
		response.setCRLF();
		response.printResponseHeader();
        Class className=null;
		try {
			String path=ServletMappingUtils.getMappingValue(request.getRequestPath());
			System.out.println("使用反射获取的servlet路径:"+path);
			className = (Class.forName(path));
			//ServletImpl servlet= (ServletImpl) className.newInstance();
			Servlet servlet = (Servlet) className.newInstance();
			System.out.println(servlet);
			servlet.service(request, response);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}	
	//向浏览器返回错误信息及其页面
	public void sendError(int statusCode,HttpRequest request,HttpResponse response)
	{
		 System.out.println("进入sendError()");
			//获取请求中资源,并处理
			//response.setStatusLine("OK");
			response.setStatusLine(statusCode);
			//response.setStatusLine("OK");
			response.setContentType("text/html");
			response.setCRLF();
			response.printResponseHeader();
			//response.printResponseContent("/error/404.html");
			response.printResponseContent(ErrorPageUtils.getErrorPage(statusCode+""));
		 
	}
	
}

          同样的,在写完代码之后,在response.setContentType(MIMEUtils.getMimeValue(contentType));String path=ServletMappingUtils.getMappingValue(request.getRequestPath());response.printResponseContent(ErrorPageUtils.getErrorPage(statusCode+""));出现问题,按照以前编写的代码进行处理即可,在设置ServletMappingUtils.getMappingValue(request.getRequestPath())部分时,我们要将文件的配置路径设置为自己的类所在的包下面,比如我们的Servlet实现类在com.sample.servlet.HelloWorldServlet,则应该写为/HelloWorld=com.sample.servlet.HelloWorldServlet。            

          值得注意的是Servlet servlet = (Servlet) className.newInstance();处的错误信息,在这里我们需要再创建一个类进行处理动态跳转,如下所示:

package com.sample.servlet;
import com.sample.http.HttpRequest;
import com.sample.http.HttpResponse;
//只有实现这个接口的类,才可以被浏览器发送请求访问到
public interface Servlet {
	//被浏览器发请求访问到的对象会调用这个指定方法service,进行处理这次浏览器的请求
	public void service(HttpRequest request,HttpResponse response);
}

下面是实现类HelloWorldServlet,其代码如下所示:

package com.sample.servlet;
import java.io.PrintWriter;
import com.sample.http.HttpRequest;
import com.sample.http.HttpResponse;
//只有实现这个接口的类,才可以被浏览器发送请求访问到
public class HelloWorldServlet implements Servlet{
	//被浏览器发请求访问到的对象会调用这个指定方法service,进行处理这次浏览器的请求
	public void service(HttpRequest request,HttpResponse response)
	{
		String name=request.getParameter("name");
		System.out.println(name);
		try {
			PrintWriter pw=response.getPrintWriter();
			pw.println("");
			pw.println("");
			pw.println("
"+name+":这是我的Servlet
"); pw.println(""); pw.println(""); pw.flush(); pw.close(); } catch (Exception e) { e.printStackTrace(); } } }

这样就完成了动态跳转页面,但是,我们在每次创建是都需要来new一个新对象,这样不仅浪费时间空间内存等等,最重要的用户体验都找不见了,那么我们就对其再次进行封装,其代码如下,实现request,response对象的封装:

package com.sample.http;
 
//负责创建http协议访问过程中使用到的对象
public interface HttpCreator {
	//返回创建好的request对象
	public HttpRequest getHttpRequest();
	
	//返回创建好的response对象
	public HttpResponse getHttpResponse();
	
	//返回创建好的HttpAccessProcessor对象
	public HttpAccessProcessor getHttpAccessProcessor();
}

下面就是实现类:

package com.sample.http;
import java.net.Socket;
//负责创建http协议访问过程中使用到的对象
public class HttpCreatorImpl implements HttpCreator{
	private Socket s;
	HttpRequestImpl request;
	HttpResponseImpl response;
	HttpAccessProcessorImpl hapi;
	public HttpCreatorImpl(Socket s) {
			this.s=s;
	}
	//返回创建好的request对象
	public HttpRequest getHttpRequest()
	{
     return request=new HttpRequestImpl(s);
	}	
	//返回创建好的response对象
	public HttpResponse getHttpResponse()
	{
		 return respOnse=new HttpResponseImpl(s);
	}	
	//返回创建好的HttpAccessProcessor对象
	public HttpAccessProcessor getHttpAccessProcessor()
	{
		 return hapi=new HttpAccessProcessorImpl();
	}
}

到此,我们完成了所有对象的封装,下面我们进行测试,写测试类如下所示:

package com.sample.http;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerTest {
	public static void main(String[] args) {
		//声明变量
        ServerSocket ss=null;
        Socket s=null;
        boolean flag=true;
        try {
        	int port=10002;
        	System.out.println("Server Port:"+port);
					ss=new ServerSocket(port);
					//while(flag)
					{
						//接受客户端发送过来的Socket
						s=ss.accept();
						HttpCreatorImpl hci=new HttpCreatorImpl(s);
						HttpRequest request=hci.getHttpRequest();
						HttpResponse respOnse=hci.getHttpResponse();
						HttpAccessProcessor hapi=hci.getHttpAccessProcessor();
						//	用于测试收到的信息
						if(request.isStaticResource())//处理静态信息
						{
							hapi.processStaticResource(request, response);
						}
						else if(request.isDynamicResource())//处理动态请求
						{
							hapi.processDynamicResource(request, response);
						}
						else//无法处理时
						{
							System.out.println("无法处理");
							hapi.sendError(404, request, response);
						}
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
	}
}

当我们在浏览器中输入http://127.0.0.1:10002/HelloWorld?id=1212&name=suguniang信息回车时能够看到如下所示界面,但是此时的状态是在项目文件夹webapps中根本不存在HelloWorld页面,但是我们能够正常访问到页面信息,而此时返回的信息正是我们的Servlet实现类中的内容:


而当我们在URL中输入不存在的请求资源时,则会弹出404界面

到此这篇关于浅谈web服务器项目中静态请求和动态请求处理的文章就介绍到这了,更多相关web服务器中静态请求和动态请求内容请搜索编程笔记以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程笔记!

原文链接:https://blog.csdn.net/suwu150/article/details/52494089


推荐阅读
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 在重复造轮子的情况下用ProxyServlet反向代理来减少工作量
    像不少公司内部不同团队都会自己研发自己工具产品,当各个产品逐渐成熟,到达了一定的发展瓶颈,同时每个产品都有着自己的入口,用户 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • Java自带的观察者模式及实现方法详解
    本文介绍了Java自带的观察者模式,包括Observer和Observable对象的定义和使用方法。通过添加观察者和设置内部标志位,当被观察者中的事件发生变化时,通知观察者对象并执行相应的操作。实现观察者模式非常简单,只需继承Observable类和实现Observer接口即可。详情请参考Java官方api文档。 ... [详细]
  • Spring学习(4):Spring管理对象之间的关联关系
    本文是关于Spring学习的第四篇文章,讲述了Spring框架中管理对象之间的关联关系。文章介绍了MessageService类和MessagePrinter类的实现,并解释了它们之间的关联关系。通过学习本文,读者可以了解Spring框架中对象之间的关联关系的概念和实现方式。 ... [详细]
  • 面向对象之3:封装的总结及实现方法
    本文总结了面向对象中封装的概念和好处,以及在Java中如何实现封装。封装是将过程和数据用一个外壳隐藏起来,只能通过提供的接口进行访问。适当的封装可以提高程序的理解性和维护性,增强程序的安全性。在Java中,封装可以通过将属性私有化并使用权限修饰符来实现,同时可以通过方法来访问属性并加入限制条件。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 如何使用计算机控制遥控车的步骤和电路制作方法
    本文介绍了使用计算机控制遥控车的步骤和电路制作方法。首先,需要检查发送器的连接器和跳线,以确定命令的传递方式。然后,通过连接跳线和地面,将发送器与电池的负极连接,以实现遥控车的前进。接下来,制作一个简单的电路,使用Arduino命令将连接到跳线的电线接地,从而实现将Arduino命令转化为发送器命令。最后,通过焊接晶体管和电阻,完成电路制作。详细的步骤和材料使用方法将在正文中介绍。 ... [详细]
author-avatar
Karson2012
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有