宝山做网站,做网站的空间,鹤壁建设网站,用vue做多页面网站板块一 Servlet编程#xff1a;第四节 HttpServletResponse对象全解与重定向 一、什么是HttpServletResponse二、响应数据的常用方法三、响应乱码问题字符流乱码字节流乱码 四、重定向#xff1a;sendRedirect请求转发和重定向的区别 在上一节中#xff0c;我们系统的学习了… 板块一 Servlet编程第四节 HttpServletResponse对象全解与重定向 一、什么是HttpServletResponse二、响应数据的常用方法三、响应乱码问题字符流乱码字节流乱码 四、重定向sendRedirect请求转发和重定向的区别 在上一节中我们系统的学习了请求响应在Servlet中service()方法的第一个形参HttpServletRequest请求对象这一节中我们将学习它的兄弟service()方法的第二个形参HttpServletResponse响应对象 一、什么是HttpServletResponse
在我们已然熟悉的浏览器访问Servlet的过程中。Request和Response 对象分别代表请求和响应通过Request对象获取客户端数据通过 Response 对象向客户端输出数据 service()方法中形参接收的是HttpServletResponse接口的实例化对象它继承自ServletResponse接口专门用来封装HTTP响应消息由于HTTP响应消息分为状态行、响应消息头、消息体三部分详见HTTP协议理论与服务器请求响应原理小节因此在HttpServletResponse中定义了状态行、响应消息头、消息体三部分。
状态行部分 响应消息头包含了关于响应的附加信息例如内容类型、内容长度、缓存控制等。由setStatus(int status)方法实现该方法用于设置HTTP响应消息的状态码并生成相应代码默认会生成一个状态码为200的状态行响应消息头部分 响应消息头包含了关于响应的附加信息例如内容类型、内容长度、缓存控制等。可以使用setHeader(String name, String value)方法设置响应消息头的字段和值例如setHeader(Content-Type, text/html)设置内容类型为HTML。如果要设置相同字段的多个值可以使用addHeader(String name, String value)方法例如addHeader(Set-Cookie, cookie1value1)。此外还可以使用一些特定的方法来设置常见的响应消息头例如setContentType(String type)、setContentLength(int len)等消息体部分 消息体包含了实际的响应数据。可以通过获取ServletOutputStream或PrintWriter对象来写入响应消息体。getOutputStream()方法返回一个可以写入二进制数据的ServletOutputStream对象。 getWriter()方法返回一个可以写入字符数据的PrintWriter对象。 可以使用这些对象的方法将数据写入响应消息体例如print(String s)、write(byte[] b)等。
二、响应数据的常用方法
接收到客户端请求后,可以通过HttpServletResponse对象直接进行响应,响应时需要获取输出流。 有两种形式:
getWriter() 获取字符流(只能响应字符串)getOutputStream() 获取字节流(能响应一切数据)
响应回的数据到客户端被浏览器解析 注意:两者不能同时使用
实例 在start.java导入PrintWriter类并在service()中写入测试代码
// 获取字符输出流
PrintWriter writer resp.getWriter();
//输出数据
writer.write(Hello);启动服务器在浏览器中访问得 在start.java中导入ServletOutputStream类并在service()中写入测试代码
//得到字节输出流
ServletOutputStream out resp.getOutputStream();
// 输出数据
out.write(Hi.getBytes());启动服务器在浏览器中访问得 但当两者同时使用时 start.java
package www.caijiyuan;import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;WebServlet(/start)
public class start extends HttpServlet {Overrideprotected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 获取字符输出流PrintWriter writer resp.getWriter();//输出数据writer.write(Hello);//得到字节输出流ServletOutputStream out resp.getOutputStream();// 输出数据out.write(Hi.getBytes());}
}启动服务器在浏览器中访问只得到了第一个的打印内容 这是为什么呢查看报错信息 原来是getWriter()已经调用过response对象了如果再响应一次response对象就已经不存在了
三、响应乱码问题
在上一节中我们使用request.setCharacterEncoding(UTF-8);解决了请求时中文乱码的问题同样在响应时也存在中文乱码问题。这是因为服务器响应的数据也会经过网络传输服务器端有一种编码方式在客户端也存在一种编码方式当两端使用的编码方式不同时则出现乱码。
字符流乱码
对于getWriter()获取到的字符流,响应中文必定出乱码,由于服务器端在进行编码时默认会使用ISO-8859-1格式的编码该编码方式并不支持中文。要解决该种乱码只能在服务器端告知服务器使用一种能够支持中文的编码格式这也是我们在解决请求时中文乱码的方法
response.setCharacterEncoding(UTF-8);此时还只完成了一半的工作 要保证数据正确显示还需要指定客户端的解码方式
response.setHeader(content-type, text/html; charsetUTF-8);两端指定编码后乱码就解决了。一句话:保证发送端和接收端的编码一致
实例 我们在start.java的service()中写入测试测试代码试图打印中文
// 获取字符输出流
PrintWriter writer resp.getWriter();
//输出数据
writer.write(汤米尼克);启动服务器在浏览器中访问发现输出中文乱码 设置服务器和客户端的编码格式统一
// 设置服务端的编码
resp.setCharacterEncoding(UTF-8);
// 设置客户端的响应类型及编码
resp. setHeader(content-type, text/html; charsetUTF-8);
// 获取字符输出流
PrintWriter writer resp.getWriter();
// 输出数据
writer.write(汤米尼克);重启浏览器再在浏览器中访问就解决问题了 理解了原理其实我们还可以同时设置客户端和服务端的编码方式
response.setContentType( text/html; charsetUTF-8);这一句就可以替换上面的两句
字节流乱码
对于getOutputStream()方式获取到的字节流,响应中文时,由于本身就是传输的字节,所以此时可能出现乱码,也可能正确显示。当服务器端给的字节恰好和客户端使用的编码方式一致时则文本正确显示,否则出现乱码。无论如何我们都应该准确掌握服务器和客户端使用的是那种编码格式,以确保数据正确显示。 因此字节流乱码的解决方式与上面字符流乱码的解决方式一样在响应发出之前同时设置服务器和客户端的编码格式统一即可
response.setContentType( text/html; charsetUTF-8);四、重定向sendRedirect
重定向是一种服务器为指导的客户端行为。 怎么理解这句话呢客户端发出一个请求被服务器接收处理后进行响应在响应的同时服务器会给客户端一个新的地址(下次请求的地址当客户端接收到响应后会立刻、马上自动根据服务器给的新地址发起第二个请求服务器接收请求并作出响应重定向完成。可以看出这个过程中有两个请求存在其中两个Servlet的Request对象并不共享、不能传值属于客户端行为。
在Servlet中重定向的语句为
response.sendRedirect(url);实例从start.java重定向到after.java的过程 在start.java的service()中写入重定向前的测试代码
System.out.println(这里是start);
resp.sendRedirect(after);在after.java的service()中写入重定向到底测试代码
System.out.println(这里是after);启动服务器在浏览器中输入start的地址 回车访问后地址立即跳转到after说明重定向的地址栏会发生改变 同时控制台输出了 那么重定向在服务器中的响应头是如何实现的 如下图在开发者工具中打开响应头的内容 会发现start文件响应行的状态码是302这就是重定向的状态码 并且响应头键值对中Location键的值就是要重定向到的地址after文件 这与我们在第一节 HTTP协议理论与服务器请求响应原理中学习的响应头的知识首尾呼应起来了
请求转发和重定向的区别
上一节中我们学习了Request对象的请求转发这一节又学习了Response对象的重定向两兄弟让人傻傻分不清必须好好区分区分
请求转发重定向request.getRequestDispatcher(url).forward(request, response);response.sendRedirect(url);服务器端行为客户端行为一次请求Request域中数据共享两次请求Request域中数据不共享地址栏不发生变化地址栏发生变化跳转只能在当前站点内跳转任意地址
在这一节中我们学习了HttpServletResponse对象学习了字符流字节流响应方法、重定向方法。不禁思考Servlet作为“后端”在Web交互中最重要的作用就是传递各种数据但目前我们学到的传值的方法还知之甚少在下一节中我们将学习Cookie对象、HttpSession对象、ServletContext对象它们作为不同特点的容器在Servlet上可以实现不同范围的传值