白痴与Servlet的深入交流(一)

请求和响应

Servlet最主要的作用就是处理客户端请求,并向客户端做出响应。为此,针对Servlet的每次请求,Web服务器在调用service()方法之前,都会创建两个对象,分别是HttpServletRequest和HttpServletResponse。

其中,HttpServletRequest用于封装HTTP请求消息,简称request对象。

HttpServletResponse用于封装HTTP响应消息,简称response对象。

request对象和response对象在请求Servlet过程中至关重要,接下来,通过一张图来描述浏览器访问Servlet的交互过程,如图所示
在这里插入图片描述
需要注意的是,在Web服务器运行阶段,每个Servlet都只会创建一个实例对象。然而,每次HTTP请求,Web服务器都会调用所请求Servlet实例的service(HttpServletRequest request,HttpServletResponse response)方法,重新创建一个request对象和一个response对象。

HttpServletResponse对象

在Servlet API中,定义了一个HttpServletResponse接口,它继承自ServletResponse接口,专门用来封装HTTP响应消息。由于HTTP响应消息分为状态行、响应消息头、消息体三部分,因此,在HttpServletResponse接口中定义了向客户端发送响应状态码、响应消息头、响应消息体的方法

发送状态码相关方法

在这里插入图片描述

发送响应消息头相关的方法

在这里插入图片描述

发送相应消息体相关的方法

由于在HTTP响应消息中,大量的数据都是通过响应消息体传递的,因此,ServletResponse遵循以IO流传递大量数据的设计理念。在发送响应消息体时,定义了两个与输出流相关的方法,具体如下

  • 1.getOutputStream()方法(字节流)
    该方法所获取的字节输出流对象为ServletOutputStream类型。由于ServletOutputStream是OutputStream的子类,它可以直接输出字节数组中的二进制数据。因此,要想输出二进制格式的响应正文,就需要使用getOutputStream()方法。既然可以返回字节流,就可以返回字符流
  • 2.getWriter()方法(字符流)
    该方法所获取的字符输出流对象为PrintWriter类型。由于PrintWriter类型的对象可以直接输出字符文本内容,因此,要想输出内容全为字符文本的网页文档,需要使用getWriter()方法。但是图片等二进制文件无法输出

活学活用小案例1

login.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>登录页面</h1>
	<font color="red">用户或密码错误,请重新输入</font><br />
	<form action="#" method="get">
		<table>
			<tr>
				<td>用户名:</td>
				<td><input type="text" name="username" /></td>
			</tr>
			<tr>
				<td>密码:</td>
				<td><input type="password" name="pwd" /></td>
			</tr>
			<tr>
				<td colspan="2" align="center">
				<input type="submit" name="submit" value="登陆" />
				</td>
			</tr>
		</table>
	</form>
	
</body>
</html>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>Review4</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
  	<servlet-name>PrintServlet</servlet-name>
  	<servlet-class>PrintServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>PrintServlet</servlet-name>
  	<url-pattern>/ps</url-pattern>
  </servlet-mapping>
</web-app>

PrintServlet.java


import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class PrintServlet
 */
public class PrintServlet extends HttpServlet {
    
    
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
    
    
		// TODO Auto-generated method stub
		// 相应行相关的方法
		// hangMethod(response);

		// 相应消息头相关的方法
		// headerMethod(response);

		// 响应体相关方法
		// 1.字节流对象
		// streamMethod(response);

		// 响应体相关方法
		// 2.字符流向浏览器输出数据
		PrintWriter pWriter = response.getWriter();
		String valueString = "Rihood------33";
//		pWriter.print(valueString);
		pWriter.write(valueString);
	}

	private void streamMethod(HttpServletResponse response) throws IOException {
    
    
		ServletOutputStream outputStream = response.getOutputStream();
		String valueString = "Rihood";
		outputStream.write(valueString.getBytes());
	}

	private void headerMethod(HttpServletResponse response) {
    
    
		// 相应消息头相关的方法
		// 1.设置状态码
		response.setStatus(302);
		// 2.设置相应头,完成重定向
		response.setHeader("Location", "/Review4/login.html");
	}

	// 相应行相关的方法
	private void hangMethod(HttpServletResponse response) throws IOException {
    
    
		response.sendError(404, "Not exist!");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
    
    
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

全局配置:
在这里插入图片描述
调用行方法(调用发送错误信息的状态码及对应提示说明的文本信息)PrintServlet.java有效代码修改如下:

public class PrintServlet extends HttpServlet {
    
    
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
    
    
		// TODO Auto-generated method stub
		// 相应行相关的方法
		hangMethod(response);

		// 相应消息头相关的方法
		// headerMethod(response);

		// 响应体相关方法
		// 1.字节流对象
		// streamMethod(response);

		// 响应体相关方法
		// 2.字符流向浏览器输出数据
//		PrintWriter pWriter = response.getWriter();
//		String valueString = "Rihood------33";
//		pWriter.print(valueString);
//		pWriter.write(valueString);
	}

	private void streamMethod(HttpServletResponse response) throws IOException {
    
    
		ServletOutputStream outputStream = response.getOutputStream();
		String valueString = "Rihood";
		outputStream.write(valueString.getBytes());
	}

	private void headerMethod(HttpServletResponse response) {
    
    
		// 相应消息头相关的方法
		// 1.设置状态码
		response.setStatus(302);
		// 2.设置相应头,完成重定向
		response.setHeader("Location", "/Review4/login.html");
	}

	// 相应行相关的方法
	private void hangMethod(HttpServletResponse response) throws IOException {
    
    
		response.sendError(404, "Not exist!");
	}

运行结果:
在这里插入图片描述
调用消息头方法(设置状态码,设置相应头,完成重定向)PrintServlet.java有效代码修改如下:

public class PrintServlet extends HttpServlet {
    
    
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
    
    
		// TODO Auto-generated method stub
		// 相应行相关的方法
//		hangMethod(response);

		// 相应消息头相关的方法
		headerMethod(response);

		// 响应体相关方法
		// 1.字节流对象
		// streamMethod(response);

		// 响应体相关方法
		// 2.字符流向浏览器输出数据
//		PrintWriter pWriter = response.getWriter();
//		String valueString = "Rihood------33";
//		pWriter.print(valueString);
//		pWriter.write(valueString);
	}

	private void streamMethod(HttpServletResponse response) throws IOException {
    
    
		ServletOutputStream outputStream = response.getOutputStream();
		String valueString = "Rihood";
		outputStream.write(valueString.getBytes());
	}

	private void headerMethod(HttpServletResponse response) {
    
    
		// 相应消息头相关的方法
		// 1.设置状态码
		response.setStatus(302);
		// 2.设置相应头,完成重定向
		response.setHeader("Location", "/Review4/login.html");
	}

	// 相应行相关的方法
	private void hangMethod(HttpServletResponse response) throws IOException {
    
    
		response.sendError(404, "Not exist!");
	}

运行结果:
在这里插入图片描述
调用字节流方法,PrintServlet.java有效代码修改如下:

public class PrintServlet extends HttpServlet {
    
    
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
    
    
		// TODO Auto-generated method stub
		// 相应行相关的方法
//		hangMethod(response);

		// 相应消息头相关的方法
//		headerMethod(response);

		// 响应体相关方法
		// 1.字节流对象
		streamMethod(response);

		// 响应体相关方法
		// 2.字符流向浏览器输出数据
//		PrintWriter pWriter = response.getWriter();
//		String valueString = "Rihood------33";
//		pWriter.print(valueString);
//		pWriter.write(valueString);
	}

	private void streamMethod(HttpServletResponse response) throws IOException {
    
    
		ServletOutputStream outputStream = response.getOutputStream();
		String valueString = "Rihood";
		outputStream.write(valueString.getBytes());
	}

	private void headerMethod(HttpServletResponse response) {
    
    
		// 相应消息头相关的方法
		// 1.设置状态码
		response.setStatus(302);
		// 2.设置相应头,完成重定向
		response.setHeader("Location", "/Review4/login.html");
	}

	// 相应行相关的方法
	private void hangMethod(HttpServletResponse response) throws IOException {
    
    
		response.sendError(404, "Not exist!");
	}

运行结果:
在这里插入图片描述
调用字符流方法,PrintServlet.java有效代码修改如下:

public class PrintServlet extends HttpServlet {
    
    
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
    
    
		// TODO Auto-generated method stub
		// 相应行相关的方法
//		hangMethod(response);

		// 相应消息头相关的方法
//		headerMethod(response);

		// 响应体相关方法
		// 1.字节流对象
//		streamMethod(response);

		// 响应体相关方法
		// 2.字符流向浏览器输出数据
		PrintWriter pWriter = response.getWriter();
		String valueString = "Rihood------33";
		pWriter.print(valueString);
//		pWriter.write(valueString);
	}

	private void streamMethod(HttpServletResponse response) throws IOException {
    
    
		ServletOutputStream outputStream = response.getOutputStream();
		String valueString = "Rihood";
		outputStream.write(valueString.getBytes());
	}

	private void headerMethod(HttpServletResponse response) {
    
    
		// 相应消息头相关的方法
		// 1.设置状态码
		response.setStatus(302);
		// 2.设置相应头,完成重定向
		response.setHeader("Location", "/Review4/login.html");
	}

	// 相应行相关的方法
	private void hangMethod(HttpServletResponse response) throws IOException {
    
    
		response.sendError(404, "Not exist!");
	}

运行结果:
在这里插入图片描述
注:
在字符流方法中,可以调用print方法或者write方法,将想输出的字符文本内容输出到浏览器上
在这里插入图片描述
Attention!!!
虽然response对象的getOutputStream()和getWriter()方法都可以发送响应消息体,但是,它们之间互相排斥,不可同时使用,否则会发生IllegalStateException异常

解决中文乱码

字节流处理办法

可能乱码,但是我的没有乱码,所以不需要这个解决办法,但是这个解决办法还是可以了解一下

ChineseServlet.java


import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class ChineseServlet
 */
public class ChineseServlet extends HttpServlet {
    
    
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
    
    
		// TODO Auto-generated method stub
		String dataString = "中国加油";
		
		// 让浏览器端的编码也是utf-8解码
		response.setHeader("Content-Type", "text/html;charset=utf-8");
		//response.setContentType("text/html;charset=utf-8"); 第二种也可解决
		// 让服务器端的中文编码格式为utf-8编码
		ServletOutputStream outputStream = response.getOutputStream();
		outputStream.write(dataString.getBytes("utf-8"));
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
    
    
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>Review4</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>PrintServlet</servlet-name>
    <servlet-class>PrintServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>PrintServlet</servlet-name>
    <url-pattern>/ps</url-pattern>
  </servlet-mapping>
  <servlet>
    <description></description>
    <display-name>ChineseServlet</display-name>
    <servlet-name>ChineseServlet</servlet-name>
    <servlet-class>ChineseServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ChineseServlet</servlet-name>
    <url-pattern>/cs</url-pattern>
  </servlet-mapping>
</web-app>

全局配置:
在这里插入图片描述
运行结果如下:
在这里插入图片描述
在这里插入图片描述

字符流处理办法

肯定会有乱码,如下图
在这里插入图片描述
web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>Review4</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>PrintServlet</servlet-name>
    <servlet-class>PrintServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>PrintServlet</servlet-name>
    <url-pattern>/ps</url-pattern>
  </servlet-mapping>
  <servlet>
    <description></description>
    <display-name>ChineseServlet</display-name>
    <servlet-name>ChineseServlet</servlet-name>
    <servlet-class>ChineseServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ChineseServlet</servlet-name>
    <url-pattern>/cs</url-pattern>
  </servlet-mapping>
  <servlet>
    <description></description>
    <display-name>ChineseServlet2</display-name>
    <servlet-name>ChineseServlet2</servlet-name>
    <servlet-class>ChineseServlet2</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ChineseServlet2</servlet-name>
    <url-pattern>/cs2</url-pattern>
  </servlet-mapping>
</web-app>

ChineseServlet2.java


import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class ChineseServlet2
 */
public class ChineseServlet2 extends HttpServlet {
    
    
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
    
    
		// TODO Auto-generated method stub
		
		// 处理服务器的编码,支持utf-8编码
		response.setCharacterEncoding("utf-8");
		// 处理浏览器的编码,支持utf-8解码
		response.setHeader("Content-Type", "text/html;charset=utf-8");
		//response.setContentType("text/html;charset=utf-8");第二种办法
		String dataString = "中国";
		PrintWriter pWriter = response.getWriter();
		pWriter.print(dataString);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
    
    
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

全局配置:
在这里插入图片描述
运行结果:
在这里插入图片描述
在这里插入图片描述
In conclusion,还是response.setContentType(“text/html;charset=utf-8”);真香!!!
因为它最简单,两种类型的乱码都支持

定时跳转并刷新

在这里插入图片描述
核心代码:

response.setHeader("Refresh", "5;URL=/Review4/login.html");

参考文档中关于setHeader的功能介绍
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
refreshServlet.java


import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class refreshServlet
 */
public class refreshServlet extends HttpServlet {
    
    
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
    
    
		// TODO Auto-generated method stub
		response.setHeader("Refresh", "5;URL=/Review4/login.html");
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
    
    
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

全局配置:
在这里插入图片描述
运行流程:

地址栏输入rs
在这里插入图片描述
过五秒后,地址跳转到login.html页面
在这里插入图片描述
在这里插入图片描述
refreshServlet.java


import java.io.IOException;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class refreshServlet
 */
public class refreshServlet extends HttpServlet {
    
    
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
    
    
		// TODO Auto-generated method stub
//		response.setHeader("Refresh", "5;URL=/Review4/login.html");
		response.setHeader("Refresh", "5");
		response.getWriter().print(new Date());

		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
    
    
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

运行流程:

在地址栏输入rs
在这里插入图片描述
每隔五秒刷新一次
在这里插入图片描述

之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!

猜你喜欢

转载自blog.csdn.net/qq_44631615/article/details/111244753
今日推荐