Java Web __ Servlet请求和响应

HttpServletResponse对象

在Servlet API中,定义了一个HttpServletResponse接口,它继承自ServletResponse,专门用来封装HTTP响应消息。

发送状态码的方法

  1. setStatus(int status)方法
  2. sendError(int sc)方法

setStatus(int status)方法
该方法用于设置HTTP响应消息的状态码,并生成响应状态行。

注意
正常情况下,Web服务器会默认产生一个状态码为200的状态行。

sendError(int sc)方法
该方法用于发送表示错误信息的状态码。

在response对象中,有两个重载:

  1. public void sendError(int code) throws java.io.IOException
    只是发送错误信息的状态码。

  2. public void sendError(int code, String message) throws java.io.IOException
    除了发送状态码外,还可以增加一条用于提示说明的文本信息,该文本信息将出现在发送给客户端的正文内容中。

响应状态码常量
由于响应状态码是一个三位的十进制数,非常难以记忆,
为此,在HttpServletResponse接口中,定义了一系列响应状态码常量。
image

发送响应消息头的方法

image

发送响应消息体的e方法**

  1. getOutputStream()方法
  2. getWriter()方法

getOutputStream()方法
该方法所获取为ServletOutputStream类型的字节输出流对象。
是OutputStream的子类,它可以直接输出字节数组中的二进制数据。
因此要想输出二进制格式的响应正文,就需要使用getOutputStream()方法。

getWriter()方法
该方法获取为PrintWriter类型的字符输出流对象。
因此,要想输出内容全为字符文本的网页文档,需要使用getWriter()方法。

注意:
虽然response对象的getOutputStream()和getWriter()方法都可以发送响应消息体,
但是,它们之间互相排斥,不可同时使用,否则会发生IllegalStateException异常。

HttpServletResponse应用

中文输出乱码问题

由于计算机中的数据都是以二进制形式存储的,因此,当传输文本时,就会发生字符和字节之间的转换。

字符与字节之间的转换是通过查码表完成的,将字符转换成字节的过程称为编码,将字节转换成字符的过程称为解码。
如果编码和解码使用的码表不一致,就会导致乱码问题。

网页定时刷新并转跳

在web开发中,有时会遇到定时跳转页面的需求。

实现这个功能需要用到:Refresh头字段
它可以通知浏览器在指定的时间内自动刷新并跳转到其它页面。

response.setHeader(“Refresh”,“3”)这样的语句,来设置当前页面定时刷新。

禁止浏览器缓存页面

在某些特定的场合下,缓冲页面会影响网页的部分功能。例如,动态页面中的Javascript脚本文件如果得不到及时更新,就会影响网页效果
为了避免这种情况的发生,在HTTP响应消息中,需要在一个响应消息中设置三个头字段,具体如下:

Expires:0
Cache-Control:no-cache
Pragma : no-cache

一般在响应消息中将上述三个头字段都进行设置

package cn.itcast.chapter05.response; 
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class CacheServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8"); 
        response.setDateHeader("Expires",0);
        response.setHeader("Cache-Control","no-cache"); 
        response.setHeader("Pragma","no-cache");  
		PrintWriter out = response.getWriter();
		out.println("本次响应的随机数为:" + Math.random());
		out.println("<form action='NotServlet'" + "method='POST'>" +
			"第一个参数:<input type='text' name='p1'><br>" +
			"第二个参数:<textarea name='p2'></textarea><br>" +
			"<input type='submit' value='提交'> " +
			"</form>");
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}
}

当表单数据填写完成后,点击“提交”按钮,此时,服务器返回一个404错误的页面,该页面暂时无需理会。
点击浏览器的回退按钮,返回到刚才填写的表单页面,发现浏览器之前填写的表单内容都不在了,而且重新生成了一个随机数。
由此说明,HttpServletRespons对象实现了禁止浏览器缓存页面的功能。

请求重定向

请求重定向是指:Web服务器接受到客户端的请求后,可能由于某些条件限制,不能访问当前请求URL所指向的Web资源,而是指定了一个新的资源路径,让客户端重新发送请求。

HttpServletResponse接口中,定义了一个sendRedirect()方法,该方法用于生成302响应码和Location响应头,从而通知客户端重新访问Location响应头中指定的URL
public void sendRedirect(java.lang.String location) throws java.io.IOException

注意
参数location可以使用相对URL,Web服务器会自动将相对URL翻译成绝对URL,再生成Location头字段。

原理:
image

用户登录的案例

  1. 编写用户登录的界面login.html和登录成功的界面welcome.html
  2. 编写处理用户登录请求的LoginServlet
package cn.itcast.chapter05.response; 
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class LoginServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		// 用HttpServletRequest对象的getParameter()方法获取用户名和密码
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		// 假设用户名和密码分别为:itcast和123
		if (("itcast").equals(username) &&("123").equals(password)) {
			// 如果用户名和密码正确,重定向到 welcome.html
                        response.sendRedirect("/chapter05/welcome.html");
		} else {
			// 如果用户名和密码错误,重定向到login.html
			response.sendRedirect("/chapter05/login.html");
		}
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}
}

HttpServletRequest对象

获取请求行信息的方法

当访问Servlet时,会在请求消息的请求行中,包含请求方法、请求资源名,请求路径等信息,
为了获取这些信息,在HttpServletRequest接口中,定义了一系列用于获取请求行信息的方法,如下表所示。
image

获取请求消息头的方法

当请求Servlet时,需要通过请求头向服务器传递附加信息,例如,客户端可以接受的数据类型,压缩方式,语言等等。
在HttpServletRequest接口中,定义了一系列用于获取HTTP请求头字段!
image

利用Referer请求头防止“盗链”

一些站点为了吸引人气并且提高站点访问量,提供了各种软件的下载页面,但是它们本身没有这些资源,只是将下载的超链接指向其它站点上的资源。
而真正提供了下载资源的站点为了防止这种“盗链”,就需要检查请求来源,只接受本站链接发送的下载请求,阻止其它站点链接的下载请求。

编写一个DownManagerServlet类,负责提供下载内容,但它要求下载请求的链接必须是通过本网站进入的,否则,会将请求转发给下载说明的HTML页面。

package cn.itcast.chapter05.request; 
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class DownManagerServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
         response.setContentType("text/html;charset=utf-8");
		PrintWriter out = response.getWriter();
         String referer = request.getHeader("referer");// 获取referer头的值
		String sitePart = "http://" + request.getServerName();// 获取访问地址
         // 判断referer头是否为空,这个头的首地址是否以sitePart开始的
		if (referer != null && referer.startsWith(sitePart)) {
			// 处理正在下载的请求
			out.println("dealing download ...");
		} else {
			// 非法下载请求跳转到download.html页面
			RequestDispatcher rd = request.getRequestDispatcher("/download.html");
			rd.forward(request, response);
		}
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}
}

获取请求消息体的方法

在HttpServletRequest 接口中,接收请求消息体时,定义了两个与输入流相关的方法,具体如下:

  1. getInputStream()方法
    该方法用于获取表示实体内容的ServletInputStream对象。

  2. getReader()方法
    该方法用于获取表示实体内容的BufferedReader对象,
    该对象会将实体内容中的字节数据按照请求消息中指定的字符集编码转换成文本字符串!

注意:
HttpServletRequest 获取请求消息的两个方法是互斥的,即getInputStream()和getReader()方法不能同时使用,否则会抛出IllegalStateException异常。

HttpServletRequest应用

解决请求参数的中文乱码

填写表单数据难免会输入中文,当请求参数中存在中文时,会遇到中文乱码现象。
HttpServletRequest接口中,提供了一个setCharacterEncoding()方法,该方法用于设置request对象的解码方式。

例如:request.setCharacterEncoding("gbk")

注意

  1. 这种解决乱码的方式只对POST方式有效,而对GET方式无效。

  2. 对于GET的请求,可以通过在代码中解决:
    name=new String(name.getBytes("iso8859-1"),"gbk");

获取网络连接信息

当Web服务器与客户端进行通信时,经常需要获取客户端的一些网络连接信息。为此,在ServletRequest接口中,定义了一系列用于获取客户端网络连接信息的方法。

image

通过request对象传递数据

  1. setAttribute()方法
    该方法用于将一个对象与一个名称关联后存储进ServletRequest对象中,其完整语法定义如下:
    public void setAttribute(java.lang.String name,java.lang.Object o);

  2. getAttribute()方法
    该方法用于从ServletRequest对象中返回指定名称的属性对象,其完整的语法定义如下:
    public java.lang.String getAttribute (java.lang.String name);

  3. removeAttribute方法
    该方法用于从ServletRequest对象中删除指定名称的属性.
    其完整的语法定义如下:
    public void removeAttribute(java.lang.String name);

  4. getAttributeNames方法
    该方法用于返回一个包含ServletRequest对象中的所有属性名的Enumeration对象,在此基础上,可以对ServletRequest对象中的所有属性进行遍历处理。
    其语法定义如下:

public java.util.Enumeration getAttributeNames();

转发

RequestDispatcher对象的应用
ServletRequest接口
ServletRequest接口中定义了两个获取RequestDispatcher对象的方法,

  1. getRequestDispatcher(String path)
    用于返回封装了某个路径所指定资源的RequestDispatcher对象。

  2. getNamedDispatcher(String name)
    用于返回封装了某个Web资源的RequestDispatcher对象,传递给该方法的参数是在Web应用程序部署好的某个Web资源名称

获取到RequestDispatcher对象后,
最重要的工作就是通知其它Web资源处理当前的Servlet请求,接口中,定义了两个相关方法

  1. forward(ServletRequest request,ServletResponse response)
    该方法用于将请求从一个Servlet传递给另外的一个Web资源。

  2. include(ServletRequest request,ServletResponse response)
    该方法用于将其它的资源作为当前响应内容包含进来

请求转发
在Servlet中,如果当前Web资源不想处理它的访问请求,可以通过forward()方法将当前请求传递给其它的Web资源进行处理,这种方式称为请求转发。

工作原理
image

注意
存储在request对象中的数据只对当前请求有效,而对其它请求无效。

请求包含
请求包含指的是使用include()方法将Servlet请求转发给其它Web资源进行处理。
与请求转发不同的是
在请求包含返回的响应消息中,既包含了当前Servlet的响应消息,也包含了其他Web资源所作出的响应消息。

工作原理
image

posted @ 2022-06-21 08:48  kingwzun  阅读(191)  评论(0编辑  收藏  举报