浅谈web服务器项目中request请求和response的相关响应处理

我们经常使用别人的服务器进行构建网站,现在我们就自己来写一个自己的服务来使用。

准备工作:下载所需的题材及文档

注:完整项目下载

一、request请求获取

 1、了解request请求

在写服务器之前,我们需要知道客户端发送给我们哪些信息?以及要求我们返回哪些信息?经过测试我们能够知道用户客户端发送的信息有以下几点:

客户端发送到服务器端的请求消息,我们称之为请求(request),其实就是一个按照http协议的规则拼接而成的字符串,Request请求消息包含三部分: 请求行 消息报头 请求正文
        第一部 请求行
            格式:
            Method Request-URI HTTP-Version CRLF
             各部分分别为:
            Method表示请求方法;一般为GET或者POST ;Request-URI是一个统一资源标识符; HTTP-Version表示请求的HTTP协议版本; CRLF表示回车和换行
            例如:
            GET /test.html HTTP/1.1

第二部 消息报头 http header
            例如:
            GET /test.html HTTP/1.1
            Host: 127.0.0.1:9999
            User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0
            Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
            Accept-Language: zh-CN,en;q=0.8,zh;q=0.5,en-US;q=0.3
            Accept-Encoding: gzip, deflate
            Connection: keep-alive

第三部 请求正文 http body
            请求头和请求正文之间是一个空行,这个行非常重要,它表示请求头已经结束,接下来的是请求正文。请求正文中可以包含客户提交的字符串信息

注意:在第二部分header和第三部分body之间有个空行,除非没有请求正文(如果你想要亲自看到效果,请参考:浏览器中GET和POST的区别),这是因为用户在浏览网页时提交给服务器的信息是不同的

 2、实现

经过以上分析,我们就能够清楚的知道,客户端发送给服务器的请求,请求信息有使用的协议、请求的方法、请求的资源路径、请求的消息报头、判断请求的内容是否为静态资源、判断请求的内容是否为动态资源、判断是否为空请求,为了使用的方便,我们需要将其封装起来,总不能使用一次读取一次吧,这样做实在是太浪费系统资源与时间了,如下代码,就是一个接口类,用于获取客户端发送过来的属性

package com.sample.http;
import java.util.Map;
  // http协议的请求
public interface HttpRequest {
  //获得请求的协议
  public String getProtocol();
  //获得请求的方法
  public String getRequestMethod();
  //获得请求的路径
  public String getRequestPath();
  //获得请求的消息报头
  public Map<String,String> getRequestHeader();
  //根据参数的名字获得请求带过来的参数值
  public String getParameter(String parameterName);
  //判断当前请求的否是静态资源
  public boolean isStaticResource();
  //判断当前请求的否是动态资源
  public boolean isDynamicResource();
  //判断当前请求的否是为空请求(有些浏览器会自动发送空请求)
  public boolean isNullRequest();
}

有了接口类之后,我们就可以创建类进行实现,下面就是实现类,用于对各个方法进行处理:

package com.sample.http;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class HttpRequestImpl implements HttpRequest{
	//客户端的Socket
	private Socket s;
	private InputStream is=null;//输入流
	private BufferedReader br=null;
	private HashMap<String,String> hmHeader=new HashMap<String,String>();//消息报头
	private HashMap<String,String> hmparameters=new HashMap<String, String>();//参数集合
	private boolean isNullRequest=false;//是否为空请求,默认false
	private String protocol=null;//请求协议
	private String requestMethod=null;//请求方法
	private String requestPath=null;//请求路径
	public HttpRequestImpl(Socket s) {
		this.s=s;
		getInfos();//调用方法
	 }
	private void getInfos()//定义一个方法,用于处理获取的客户端信息
	{
		try {
			is=s.getInputStream();
			br=new BufferedReader(new InputStreamReader(is));
			//解析第一行
			String str;
			str=br.readLine();//readLine使用回车换行判断一行是否结束
			if(str==null)
			{
				isNullRequest=true;
				return;
			}
			parseRequestMethodPathProtocol(str);//调用自己创建在本类里边的方法处理第一行信息,方法在后面
		//解析第二行---第八行
			String header=null;
            //判断是否结束,如果结束就退出,这里的判断按较为饶人
           //首先应该明确br.readLine()的内容,当为true是对应的情况
           //也就是说当“”(中间没有空格)与br.readLine()相等时,就进入到while中
            while(!"".equals((header=br.readLine()))){
			parseRequestHeader(header);
			}
		//post和get
		if(br.ready())//post//POST提交方式判断,如果还有下一行就继续读取信息
		{
			char[] buf=new char[1024];
			int len=br.read(buf);//使用字节进行读取,因为这一行没有回车换行,readLine无法判断是否结束
			String parameter=new String(buf,0,len);
			parseRequestParamByPost(parameter);//调用自己创建在本类里边的方法处理POST方式提交的正文信息
		}
		else
		{//get,get参数的位置在第一行连接处
			parseRequestParamByGet(requestPath);//调用自己创建在本类里边的方法处理GET方式提交的正文信息
		}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
     //GET方法处理
    private void parseRequestParamByGet(String requestPath2) {
		String []str1=requestPath2.split("[?]");//使用“?”分割字符串
		if(str1.length==2)
		{
				parseRequestParamByPost(str1[1]);
		}
		this.requestPath=str1[0];
	}
    //POST方法处理
    private void parseRequestParamByPost(String parameter) {
		 String[] strs=parameter.split("&");
		 if(strs.length>=1)
		 {
			 for(String str:strs)
			 {
				 String [] sp=str.split("=");
         hmparameters.put(sp[0],sp[1]);
			 }
		 }
	}
	//解析第二行到第八行
	private void parseRequestHeader(String header) throws Exception{
		String[] headHost=header.split(": ");
		 if(headHost.length!=2)
	     {
			 throw new Exception("消息报头异常,请重新提交");
		 }
		 hmHeader.put(headHost[0],headHost[1]);
	}
	//解析第一行
	private void parseRequestMethodPathProtocol(String str) throws Exception {
		 String[] protocolMethodPath=new String[3];//由于第一行含有三个内容,分割后需要三个String存储
		 protocolMethodPath=str.split(" ");//使用空格分割
		 if(protocolMethodPath.length==3)
		 {
		 requestMethod=protocolMethodPath[0];
		 requestPath=protocolMethodPath[1];
		 protocol=protocolMethodPath[2];
		 }
		 else
		 {
			 throw new Exception("首行参数不合适,请重新提交");
		 }
	}
	//获得请求的协议
	public String getProtocol()
	{
		return protocol;
	}
	//获得请求的方法
	public String getRequestMethod(){
		return requestMethod;
	}
	//获得请求的路径
	public String getRequestPath(){
		return requestPath;
	}
	//获得请求的消息报头
	public Map<String,String> getRequestHeader(){
		return this.hmHeader;
	}
	//根据参数的名字获得请求带过来的参数值
	public String getParameter(String parameterName){
		return hmparameters.get(parameterName);
	}
	//判断当前请求的否是静态资源
	public boolean isStaticResource(){
		return true;
	}
	//判断当前请求的否是动态资源
	public boolean isDynamicResource(){
		return true;
	}
	//判断当前请求的否是为空请求(有些浏览器会自动发送空请求)
	public boolean isNullRequest(){
 return isNullRequest;
	}
}

以上内容是对客户端(浏览器)请求内容的处理,即如何进行包装客户端请求的信息,并且将其包装成一个统一的整体,既然能够获取浏览器的内容,那么,我们就必须采取一定的措施告诉浏览器我们找到了你想要的文件,并且将返回给客户端,下面我们就来实现如何返回给客户端想要的信息

二、response响应处理

 1、了解response响应 

服务器在接收和解释客户端的请求消息后,服务器会返回给客户端一个HTTP响应消息,我们称之为响应(response)。其实也是一个按照http协议的规则拼接而成的一个字符串
    HTTP响应也是由三个部分组成,分别是: 响应状态行、消息报头、响应正文

第一部分 响应状态行

格式如下:
        HTTP-Version Status-Code Reason-Phrase CRLF
例如:
        HTTP/1.1 200 OK
        各部分分别为:
        HTTP-Version表示服务器HTTP协议的版本;
        Status-Code表示服务器发回的响应状态代码; 
        Reason-Phrase表示状态代码的文本描述。
        CRLF表示回车和换行

    第二部分 消息报头

HTTP消息报头包括普通报头、请求报头、响应报头、实体报头这四大类。
  每一个 报头域 都是由 名字+冒号+空格+值 组成,消息报头域的名字不区分大小写。它们的作用是描述 客户端或者服务器 的属性
                 1.普通报头:即可用于请求,也可用于响应,是作为一个整体而不是特定资源与事务相关联。
                 2.请求报头:允许客户端传递关于自身信息和希望的响应形式。
                 3.响应报头:允许服务器传递关于自身信息的响应。
                 4.实体报头:定义被传送资源的信息。即可用于请求,也可用于响应。

什么是 MIME Type?

首先,我们要了解浏览器是如何处理内容的。在浏览器中显示的内容有 HTML、有 XML、有 GIF、还有 Flash ……那么,浏览器是如何区分它们,决定什么内容用什么形式来显示呢?答案是 MIME Type,也就是该资源的媒体类型。媒体类型通常是通过 HTTP 协议,由 Web 服务器告知浏览器的,更准确地说,是通过响应的消息报头里面的属性 Content-Type 来表示的,例如:Content-Type: text/HTML表示内容是 text/HTML 类型,也就是超文本文件。为什么是“text/HTML”而不是“HTML/text”或者别的什么?MIME Type 不是个人指定的,是经过 ietf 组织协商,以 RFC 的形式作为建议的标准发布在网上的,大多数的 Web 服务器和用户代理都会支持这个规范 (顺便说一句,Email 附件的类型也是通过 MIME Type 指定的)。

通常只有一些在互联网上获得广泛应用的格式才会获得一个 MIME Type,如果是某个客户端自己定义的格式,一般只能以 application/x- 开头。XHTML 正是一个获得广泛应用的格式,因此,在 RFC 3236 中,说明了 XHTML 格式文件的 MIME Type 应该是 application/xHTML+XML。当然,处理本地的文件,在没有人告诉浏览器某个文件的 MIME Type 的情况下,浏览器也会做一些默认的处理,这可能和你在操作系统中给文件配置的 MIME Type 有关。比如在 Windows 下,打开注册表的“HKEY_LOCAL_MACHINESOFTWAREClassesMIMEDatabaseContent Type”主键,你可以看到所有 MIME Type 的配置信息

每个MIME类型由两部分组成,前面是数据的大类别,例如声音audio、图象image等,后面定义具体的种类。

常见的MIME类型

超文本标记语言文本 .html,.html text/html
普通文本 .txt text/plain
RTF文本 .rtf application/rtf
GIF图形 .gif image/gif
JPEG图形 .ipeg,.jpg image/jpeg
au声音文件 .au audio/basic
MIDI音乐文件 mid,.midi audio/midi,audio/x-midi
RealAudio音乐文件 .ra, .ram audio/x-pn-realaudio
MPEG文件 .mpg,.mpeg video/mpeg
AVI文件 .avi video/x-msvideo
GZIP文件 .gz application/x-gzip
TAR文件 .tar application/x-tar

第三部分 响应正文

响应正文就是服务器返回的资源的内容

 2、实现

首先,我们需要进行抽象,即将浏览器想要的信息,即如下内容包装起来,如下所示,我们将其包装成一个接口,在抽象时我们必须认识到用户可能会犯的错误,所以尽量使用重载的方法进行避免,在下面的接口中,使用了重载进行处理部分方法:

package com.sample.http;
import java.io.OutputStream;
import java.io.PrintWriter;
//http协议的响应
public interface HttpResponse {
	//获得一个指向客户端的字节流
	public OutputStream getOutputStream()throws Exception;
	//获得一个指向客户端的字符流
	public PrintWriter getPrintWriter()throws Exception;
	//设置响应的状态行 参数为String类型
	public void setStatusLine(String statusCode);
	//设置响应的状态行 参数为int类型
	public void setStatusLine(int statusCode);
	//设置响应消息报头
	public void setResponseHeader(String hName,String hValue);
	//设置响应消息报头中Content-Type属性
	public void setContentType(String contentType);
	//设置响应消息报头中Content-Type属性 并且同时设置编码
	public void setContentType(String contentType,String charsetName);
	//设置CRLF 回车换行 \r\n
	public void setCRLF();
	//把设置好的响应状态行、响应消息报头、固定空行这三部分写给浏览器
	public void printResponseHeader();
	//把响应正文写给浏览器
	public void printResponseContent(String requestPath);
}

在接口中,我们能够看到详细的解释,下面我们就来实现接口中的方法:

package com.sample.http;
<pre name="code" class="java">import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.Socket;

import com.sample.utils.ConfigUtils;
import com.sample.utils.StatusCodeUtils;
//http协议的响应
public class HttpResponseImpl implements HttpResponse {
	 //声明初始变量
	Socket s;//客户端socket
	OutputStream os;//输出端字节流
	BufferedWriter bw;//输出端字符流
	PrintWriter pw;
	StringBuffer sbuffer;//放状态行,\r\n ,
	FileInputStream fis;
	File file;
	//构造器
	public HttpResponseImpl(Socket s) {
          this.s=s;
          System.out.println("HttpRequestImpl(Socket s)");
          os=null;
          bw=null;
          pw=null;
          sbuffer=new StringBuffer();//初始化,记得,否则以下的操作会遇见空指针异常
          fis=null;
          file=null;
          getInfos();
	}

	private void getInfos() {
			try {
				os=s.getOutputStream();
				bw=new BufferedWriter(new OutputStreamWriter(os,"GBK"));
				pw=new PrintWriter(bw);
			} catch (Exception e) {
				e.printStackTrace();
			}
	}
	//获得一个指向客户端的字节流
	public OutputStream getOutputStream()throws Exception
	{
		return os;
	}
	//获得一个指向客户端的字符流
	public PrintWriter getPrintWriter()throws Exception
	{
		return pw;
	}
	//设置响应的状态行 参数为String类型
	public void setStatusLine(String statusCode)
	{
		String str=StatusCodeUtils.getStatusCodeValue(statusCode);
		//System.out.println(str+"------"+str.length());
		sbuffer.append("HTTP/1.1 "+statusCode+" "+str);
		setCRLF();
	}
	//设置响应的状态行 参数为int类型
	public void setStatusLine(int statusCode)
	{
		setStatusLine(statusCode+"");//将int类型转化为String类型
	}
	//设置响应消息报头
	public void setResponseHeader(String hName,String hValue)
	{
		sbuffer.append(hName+": "+hValue);
		setCRLF();
	}
	//设置响应消息报头中Content-Type属性
	public void setContentType(String contentType)
	{
		setResponseHeader("Content-Type",contentType);
	}
	//设置响应消息报头中Content-Type属性 并且同时设置编码
	public void setContentType(String contentType,String charsetName)
	{//text/html;charset=utf-8
		setContentType(";charset= "+charsetName);
	}
	//设置CRLF 回车换行 \r\n
	public void setCRLF()
	{
		sbuffer.append("\r\n");
	}
	//把设置好的响应状态行、响应消息报头、固定空行这三部分写给浏览器
	public void printResponseHeader()
	{
		//设置setResponseLine,setResponseHeader,setResponseType
		String res=sbuffer.toString();
		pw.print(res);
		pw.flush();
	}
	//把响应正文写给浏览器
	public void printResponseContent(String requestPath)
	{
		//响应正文
		String getPath= requestPath;//客户请求的地址
		String webHome=(new ConfigUtils()).getConfigValue("rootPath");
		System.out.println("配置文件中目录:"+webHome);//输出从配置文件中获取的地址
		file=new File(webHome+getPath);
		if(file.exists())//如果文件存在就执行
		{
		try {
			fis=new FileInputStream(file);
			byte[] buf=new byte[1024];
			int len=-1;
			while((len=fis.read(buf))!=-1)
			{
				//String str=buf.toString();
				//bw.write(str);//字符流写过去是一个地址,因为写过去之后需要浏览器解析,如果是图片或者其他(图片或视频是字节流)的该怎么解析呢?
				//System.out.println(str);
				os.write(buf, 0, len);
			}
			bw.flush();
			os.flush();//os要不要关???
		} catch (IOException e) {
			e.printStackTrace();
		}finally
		{
			try {
				if(bw!=null)
				bw.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		}
	}
}

在Eclipse中写完以上代码我们会发现,其中有多处错误信息,其原因是我们没有进行创建以上代码所要求的类,现在我们进行创建,其使用方法请参见:java.util 类 Properties    ,使用参考中的方法,我们能够进行对所需要的信息进行配置,在以上代码中使用的地方有两处,分别是【注意:这样做的好处是增减了项目的灵活性,用户能够在不查看代码的情况下随时更改配置文件等一些文件的信息,】:

(1)设置状态行处

//设置响应的状态行 参数为String类型
	public void setStatusLine(String statusCode)
	{
		String str=StatusCodeUtils.getStatusCodeValue(statusCode);
		//System.out.println(str+"------"+str.length());
		sbuffer.append("HTTP/1.1 "+statusCode+" "+str);
		setCRLF();
	}

其中StatusCodeUtils类创建如下所示,而对于status_code.properties文件存放在下载的准备文件中的/webservlet/project/中,直接复制到项目中即可:

package com.sample.utils;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
public class StatusCodeUtils {
	private static Properties p;
	static
	{
		InputStream in=null;
		p=new Properties();
		try {
			//读了xx.properties文件
			in=StatusCodeUtils.class.getResourceAsStream("status_code.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 getStatusCodeValue(String status)
	{
		return p.getProperty(status);
	}
	public static String getStatusCodeValue(int status)
	{
		return getStatusCodeValue(status+"");//没有空格
	}
	/*public static void main(String[] args) {//输出测试
	//Properties p=new Properties();
	// p.setProperty("rootPath","ddd");
	//System.out.println(p.get("rootPath"));
		System.out.println(getStatusCodeValue("304"));
		System.out.println(getStatusCodeValue("200"));
	}*/
}

(2)响应正文处:

//响应正文
		String getPath= requestPath;//客户请求的地址
		String webHome=(new ConfigUtils()).getConfigValue("rootPath");
		System.out.println("配置文件中目录:"+webHome);//输出从配置文件中获取的地址
		file=new File(webHome+getPath);

在响应正文中使用了ConfigUtils类进行了项目路径的获取,代码如下所示,对于config.properties(注意:此文件中文件路径应该注意,我使用的是Linux系统,文件结构是/home/***,而对于windows系统,目录结构为:"C://webapps/*****,最好在地址栏复制地址,写到配置中")文件也在准备文件中,请自行下载,然后复制到项目中:就是下面这个东西,路径配置合适,然后你就可以将自己的项目放在webapps目录下,让自己的电脑作为服务器供其他人访问自己的网站了

ConfigUtils路径配置类,用于获取项目文件目录位置

package com.sample.utils;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
public class ConfigUtils {
	private static Properties p;
	static
	{
		InputStream in=null;
		OutputStream on=null;
		p=new Properties();
		try {
			//读了xx.properties文件
			in=ConfigUtils.class.getResourceAsStream("config.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 getConfigValue(String config)
	{
		return p.getProperty(config);
	}
	public static void main(String[] args) {//输出测试
	//	Properties p=new Properties();
	//	p.setProperty("rootPath","ddd");
	//	System.out.println(p.get("rootPath"));
		System.out.println(getConfigValue("rootPath"));
	}
}

到此为止,我们已经实现了服务器的主要任务,接受请求和处理请求,下面我们进行测试:

写一个测试类如下:

package com.sample.http;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
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();
						HttpRequestImpl request=new HttpRequestImpl(s);
						//	用于测试收到的信息
						System.out.println("获取的路径:"+request.getRequestPath());
						System.out.println("获取的:"+request.getProtocol());
						System.out.println("获取的:"+request.getRequestMethod());
						System.out.println(request.getParameter("name"));
						System.out.println(request.getParameter("id"));
						Map<String,String> m=request.getRequestHeader();
						Set<Entry<String,String>> set=m.entrySet();
						Iterator it=set.iterator();
						while(it.hasNext())
						{
							Entry entry=(Entry<String, String> )it.next();
							System.out.println(entry.getKey()+"----"+entry.getValue());
						}
					    //写响应给浏览器
						/*
						 * 封装:
						 * */
						//输出流
						HttpResponseImpl response=new HttpResponseImpl(s);
						response.setStatusLine(200);
						response.setContentType("text/html");
						response.printResponseHeader();
						response.setCRLF();
						response.printResponseHeader();
						response.printResponseContent(request.getRequestPath());
						//用于输出信息
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
	}
}

在浏览器中输入地址回车:http://127.0.0.1:10002/test.html?id=1212&name=suguniang ,能够看到浏览器解析后的界面,当其他电脑访问时(其他电脑指的是同一个域内的),只要将127.0.0.1修改为本地的ip地址即可

此时控制台上也输出相应的信息:

自己的web服务器项目-静态请求和动态请求处理(二)

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

(0)

相关推荐

  • golang设置http response响应头与填坑记录

    1. 设置WriteHeader的顺序问题 之前遇到个问题,在一段代码中这样设置WriteHeader,最后在header中取Name时怎么也取不到. w.WriteHeader(201) w.Header().Set("Name", "my name is smallsoup") 用 golang 写 http server 时,可以很方便可通过 w.Header.Set(k, v) 来设置 http response 中 header 的内容.但是需要特别注意的

  • Java response响应体和文件下载实现原理

    通过response 设置响应体: 响应体设置文本: PrintWriter getWriter() 获得字符流,通过字符流的write(String s)方法可以将字符串设置到response 缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览 器端. 关于设置中文的乱码问题 原因:response缓冲区的默认编码是iso8859-1,此码表中没有中文,可以通过 response的setCharacterEncoding(String charset) 设

  • Java中HttpServletResponse响应中文出现乱码问题

    以字符串的形式输出. 1.response.getWriter().write("您好中国hello"); 如果这样输出的话.则浏览器结果为: 2.加上代码 response.setCharacterEncoding("UTF-8"); response.getWriter().write("您好中国hello"); 则浏览器结果为: 这是因为浏览器解析问题. 加上代码: response.setHeader("Content-type

  • Java HttpServletResponse响应实现过程详解

    用户在客户端输入网址(虚拟路径)时,开始发送一个HTTP请求(请求行.请求头.请求体)至服务器.服务器内的Tomcat引擎会解析请求的地址,去找XML文件,然后根据虚拟路径找Servlet的真实路径,真实的Servlet会将请求的信息封装成request(请求)对象,然后再创建一个response(响应)对象,(此时的response内是空的)同时创建servlet对象,并调用service方法(或doGet和doPost方法). 这样就是把两个对象传给了服务器内的某个servlet的servi

  • 浅谈web服务器项目中request请求和response的相关响应处理

    我们经常使用别人的服务器进行构建网站,现在我们就自己来写一个自己的服务来使用. 准备工作:下载所需的题材及文档 注:完整项目下载 一.request请求获取  1.了解request请求 在写服务器之前,我们需要知道客户端发送给我们哪些信息?以及要求我们返回哪些信息?经过测试我们能够知道用户客户端发送的信息有以下几点: 客户端发送到服务器端的请求消息,我们称之为请求(request),其实就是一个按照http协议的规则拼接而成的字符串,Request请求消息包含三部分: 请求行 消息报头 请求正

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

    注:完整项目下载 在处理了核心任务之后,我们会发现有些请求并不是都是静态的,那么我们就需要进行实现处理动态请求的要求,如下面代码是我们请求的解决方式,我们只需在HttpRequestImpl实现类中,将如下代码实现具体的判断过程 //判断当前请求的否是静态资源 public boolean isStaticResource(){ return true; } //判断当前请求的否是动态资源 public boolean isDynamicResource(){ return true; } 1.

  • 浅谈ajax在jquery中的请求和servlet中的响应

    在jsp中,首先,你需要导入jquery的架包: 获取可返回站点的根路径: <% String path = request.getContextPath(); %> 在jquery中写ajax请求: <script type="text/javascript"> $(function(){ $(".B").click(function(){ $.ajax({ type: "GET", //对应servlet中的方法 ur

  • 浅谈JAVA在项目中如何自定义异常

    JAVA项目中自定义异常 1.数据返回处理类 @Data public class R<T> implements Serializable { private static final long serialVersionUID = -8497670085742879369L; @ApiModelProperty(value = "返回码", example = "200") private Integer code=200; @ApiModelPro

  • 浅谈如何在项目中使用Spring Cloud Alibaba Sentinel组件

    目录 Sentinel 是什么 Sentinel与Hystrix的区别 Sentinel分为两大部分: 一.控制台(Dashboard) 二.搭建客户端 1.在自己的项目中引入依赖 2.编辑项目中的 application.yml或者bootstrap.yml文件 3.资源是 Sentinel 中的一个关键概念.它可以是任何东西,例如服务.方法,甚至是代码片段. 三.查看接口的流量的详情 1.实时监控 2.簇点链路 3.等等:其他使用方法有待发掘 Sentinel 是什么 随着微服务的流行,服务

  • 浅谈vue3在项目中的逻辑抽离和字段显示

    目录 逻辑分层 将各个区域业务分开 这样做的优势 这样的场景应该如何处理 优化 reactive 不一定非要写在setup函数中 如何在页面上直接显示值 逻辑分层 我们在使用vue3开发项目的时候, 如何进行[区域分层]呢???? 举一个简单的小粒子 一个区域有[查询逻辑.修改后的保存逻辑.新增逻辑.删除逻辑] 这个页面可能还有其他的区域.A区域.B区域,C区域...[有很多逻辑] 这个时候我们可以将一个区域的逻辑分离出去 将各个区域业务分开 export default { setup ()

  • 浅谈在JAVA项目中LOG4J的使用

    一.直接使用: //输出到项目文件夹下output1.txt文件中 ////////////////////////////// // DEBUG - Here is some DEBUG // INFO - Here is some INFO // WARN - Here is some WARN // ERROR - Here is some ERROR // FATAL - Here is some FATAL ////////////////////////////// package

  • 浅谈redis在项目中的应用

    redis在项目中的应用 ps:PHP 会自动 关redis连接 不需要手动关 对于临时的数据 可以不经过数据库直接redis上操作 /*消息队列实例 */ public function insertinfo(){ //连接本地的 Redis 服务 $redis = new \Redis(); $redis->connect('127.0.0.1', 6379); //存储数据到列表中 $infos = array('info1' => 66, 'info2' => 88); $red

  • 浅谈在vue-cli3项目中解决动态引入图片img404的问题

    博主最近手头再做一个项目,需要调用天气接口,并且还要动态显示天气相关图片icon. 本来以为没什么大问题,结果硬生生被这个动态图片路径搞得民不聊生(博主还是 too young,too simple~),给出效果图: 就是那个红框选中的那个天气状况图标icon要根据当前城市获取当前城市天气状态码,再根据当前城市状态码找到这个对应的天气图标icon~~ 按照一般的开发模式,静态图片路径是相对路径还是绝对路径都可以,因为图片路径是静态的是死的,所以webpack去找这个图片路径的时候是能找到的. 但

  • 浅谈Web服务器和应用服务器的区别

    通俗的讲,Web服务器传送(serves)页面使浏览器可以浏览,然而应用程序服务器提供的是客户端应用程序可以调用(call)的方法(methods).确切一点,你可以说:Web服务器专门处理HTTP请求(request),但是应用程序服务器是通过很多协议来为应用程序提供(serves)商业逻辑(business logic). 下面让我们来细细道来: Web服务器(Web Server) Web服务器可以解析(handles)HTTP协议.当Web服务器接收到一个HTTP请求(request),

随机推荐