HttpServletResponse
1.HttpServletResponse概述
我们在创建Servlet时会覆盖service()方法,或doGet()/doPost(),这些方法都有两个参数,一个为代表请求的request和代表响应response。
service方法中的response的类型是ServletResponse,而doGet/doPost方法的response的类型是HttpServletResponse,HttpServletResponse是ServletResponse的子接口,功能和方法更加强大,今天我们学习HttpServletResponse。
2. Response运行流程
3. 通过抓包工具获取Http响应
因为response代表响应,所以我们可以通过该对象分别设置Http响应的响应行,响应头和响应体
4.通过response设置响应行
设置响应行的状态码: setStatus(int sc)
代码演示:
package com.oracle.demo01; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Servlet01 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置响应行的状态码:response.setStatus(int类型的数值);当响应成功后的状态码就是你设置的 response.setStatus(404); response.getWriter().write("hello dandan..."); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
5.通过response设置响应头
addHeader(
String name,
String value)
addIntHeader(
String name, int value)
addDateHeader(
String name, long date)
setHeader(
String name,
String value)
重定向
setDateHeader(
String name, long date)
setIntHeader(
String name, int value)
其中,add表示添加,而set表示设置
重定向需要:1.状态码:302
2.响应头:location 代表重定向地址
重定向代码演示:
package com.oracle.demo01; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Servlet02 extends HttpServlet { //重定向: //1.服务器访问两次 //2.地址栏地址会有变化 //当访问第一个Servletet02的时候,第一个没有资源,但是会返回一个响应,告知客户端Servlet03有资源 //客户端就会自己跳转到Servlet03的页面 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // //1.设置状态码 // response.setStatus(302); // //2.设置响应头Location,重定向 // response.setHeader("Location", "/WEB03/Servlet03"); //开发中上面的方法一般不用,会使用下面封装好的方法 //开发中封装好的 专门用于重定向的方法:response.sendRedirect(); response.sendRedirect("/WEB03/Servlet03"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
6.通过response设置响应体
(1)响应体设置文本
PrintWriter
getWriter()
流程:获得字符流,通过字符流的write(
String s)
方法可以将字符串设置到response缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览器端。(必须会说)
关于设置中文的乱码问题
原因:response缓冲区的默认编码是iso8859-1,此码表中没有中文,可以通过response的setCharacterEncoding(
String charset)
设置response的编码
但我们发现客户端还是不能正常显示文字
原因:我们将response缓冲区的编码设置成UTF-8,但浏览器的默认编码是本地系统的编码,因为我们都是中文系统,所以客户端浏览器的默认编码是GBK,我们可以手动修改浏览器的编码是UTF-8。
我们还可以在代码中指定浏览器解析页面的编码方式,
通过response的setContentType(
String type)
方法指定页面解析时的编码是UTF-8
response.setContentType("text/html;charset=UTF-8");
上面的代码不仅可以指定浏览器解析页面时的编码,同时也内含setCharacterEncoding的功能,所以在实际开发中只要编写response.setContentType("text/html;charset=UTF-8");就可以解决页面输出中文乱码问题。
解决中文乱码代码演示:
package com.oracle.demo01; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Servlet04 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //解决中文乱码的问题 //设置缓冲区的编码为UTF-8 // response.setCharacterEncoding("UTF-8"); // //告知客户端给我用UTF-8解码 // response.setHeader("Content-Type", "text/html;charset=UTF-8"); response.setContentType("text/html;charset=UTF-8"); response.getWriter().write("中国"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
(2)响应头设置字节
ServletOutputStream
getOutputStream()
在浏览器上输出一个文件,前提是浏览器可以解析,不能解析就是提供下载
获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字 节,在由Tomcat服务器将字节内容组成Http响应返回给浏览器。
响应头设置时间自动跳转:
package com.oracle.demo01; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Servlet03 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //定时刷新的响应头:定时刷新跳转到另一个网页 response.setHeader("refresh", "5;url=http:///www.baidu.com"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
Jsp代码:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script type="text/javascript"> var time=5; //全局函数,当全部页面加载完成后才会执行的函数 window.onload=function(){ var second=document.getElementById("second"); timer=setInterval(function(){ //定时器函数 second.innerHTML=time; time--; if(time==0){ clearInterval(timer); //清除定时器 location.href="http://www.baidu.com"; } }, 1000); } </script> </head> <body> 恭喜你,注册成功,<span style="color:red" id="second">5</span> 秒后跳转,如不跳转,请点击<a href="http://www.baidu.com">这里</a> </body> </html>
练习题:
1. 文件的下载:
package com.oracle.demo02; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //import sun.misc.BASE64Encoder; public class DownloadServlet extends HttpServlet { //服务器提供文件下载的方法 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.获得下载的文件的名称 String filename=request.getParameter("filename"); //解决中文乱码的问题 filename=new String(filename.getBytes("ISO8859-1"),"UTF-8"); //获取浏览器的请求头User-Agent String agent=request.getHeader("User-Agent"); String filenameEncoding=""; //根据不同的浏览器进行编码(模板代码复制即可,不需要记忆) if (agent.contains("MSIE")) { // IE浏览器 filenameEncoding = URLEncoder.encode(filename, "utf-8"); filenameEncoding = filename.replace("+", " "); } // else if (agent.contains("Firefox")) { // // 火狐浏览器 // BASE64Encoder base64Encoder = new BASE64Encoder(); // filenameEncoding = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?="; // } else { // 其它浏览器 filenameEncoding = URLEncoder.encode(filename, "utf-8"); } //2.设置要下载的文件的类型----客户端通过文件的MIME类型区分文件的类型 response.setContentType(this.getServletContext().getMimeType(filename)); //3.告诉你的客户端该文件不能直接解析,而是以附件的形式打开(下载) response.setHeader("Content-Disposition", "attachment;filename="+filenameEncoding); //4.获取文件的绝对路径 String path=this.getServletContext().getRealPath("download/"+filename); //5.创建输入流 InputStream in=new FileInputStream(path); //6.获取输出流--通过response获得输出流 ServletOutputStream out=response.getOutputStream(); //7.文件复制的模板代码 int len=0; byte[] bytes=new byte[1024]; while((len=in.read(bytes))!=-1){ out.write(bytes,0,len); //输出到浏览器上 } //8.释放资源 in.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
Jsp代码:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Insert title here</title> </head> <body> <h1>使用a标签直接指向服务器上的资源提供下载功能</h1> <a href="/WEB03/download/中国.txt">中国.txt</a> <a href="/WEB03/download/commons.zip">commons.zip</a> <a href="/WEB03/download/dameinv.jpg">dameinv.jpg</a> <h1>使用服务器端编码的方式实现下载功能</h1> <a href="/WEB03/DownloadServlet?filename=中国.txt">中国.txt</a> <a href="/WEB03/DownloadServlet?filename=commons.zip">commons.zip</a> <a href="/WEB03/DownloadServlet?filename=dameinv.jpg">dameinv.jpg</a> </body> </html>
2. 将图片输出到页面:
package com.oracle.demo02; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyServlet01 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //使用response获取字节输出流,负责写给客户端的 ServletOutputStream out=response.getOutputStream(); //确定数据源,将图片读到程序中 String realPath=this.getServletContext().getRealPath("dameinv.jpg"); //获取图片路径 InputStream in=new FileInputStream(realPath); int len=0; byte[] bytes=new byte[1024]; while((len=in.read(bytes))!=-1){ //将程序中的字节数组写到客户端 out.write(bytes,0,len); } //释放资源 in.close(); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
3. 注册到数据库:
dao层代码:
package com.oracle.demo02; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class Dao { public int dao(String username,String pwd) throws SQLException{ Connection conn=JDBCUtils.getConnection(); String sql="insert into user (username,password) values(?,?)"; PreparedStatement pst=conn.prepareStatement(sql); pst.setString(1, username); pst.setString(2, pwd); int row=pst.executeUpdate(); JDBCUtils.close(pst, conn); return row; } }
service层代码:
package com.oracle.demo02; import java.sql.SQLException; public class Service { public String service(String username,String pwd) throws SQLException{ Dao d=new Dao(); int count=d.dao(username, pwd); String mes=""; if(count>0){ mes="注册成功"; }else{ mes="注册失败"; } return mes; } }
servlet层代码:
package com.oracle.demo02; import java.io.IOException; import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class InsertServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); String username=request.getParameter("username"); String pwd=request.getParameter("pwd"); Service s=new Service(); try { String mes=s.service(username, pwd); response.getWriter().write(mes); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
JDButils代码:
package com.oracle.demo02; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class JDBCUtils { public static Connection getConnection(){ try{ //注册驱动 Class.forName("com.mysql.jdbc.Driver"); String username="root"; String password="123456"; String url="jdbc:mysql://localhost:3306/goods?characterEncoding=utf-8"; //获得连接 Connection conn=DriverManager.getConnection(url,username,password); return conn; }catch(Exception ex){ throw new RuntimeException(ex+"数据库连接失败"); } } //关闭数据库的方法 public static void close(ResultSet rs,Statement sta,Connection conn){ if(rs!=null){ try { rs.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(sta!=null){ try { sta.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(conn!=null){ try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void close(Statement sta,Connection conn){ if(sta!=null){ try { sta.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(conn!=null){ try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
Jsp代码:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script type="text/javascript"> function changeImg(obj){ obj.src="/WEB03/CheckImgServlet?time="+new Date().getTime(); } </script> </head> <body> <div><%=request.getAttribute("loginInfo")==null?"":request.getAttribute("loginInfo") %></div> <form action="/WEB03/LoginServlet" method="post"> 验证码:<input type="text" name="checkcode"> <img src="/WEB03/CheckImgServlet" onclick="changeImg(this)"> <input type="submit" value="登陆"> </form> </body> </html>