在我们真正开发的时候我们并不是直接使用servlet,而是使用httpservlet。
一、创建过程:
1、使用eclipse创建一个Dynamic web project。
dynamic web module version 需要选择2.5,否则没有web.xml 文件。
2、创建好项目后,在src路径下面创建包:httpservletResponseServlet
3、创建封装好的servlet。
右击包——new——servlet。
创建好的servlet中的代码:
package httpservletResponseServlet;
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 DemoServlet
*/
public class DemoServlet 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.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);
}
}
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>httpservlet_response</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>
<description></description>
<display-name>DemoServlet</display-name>
<servlet-name>DemoServlet</servlet-name>
<servlet-class>httpservletResponseServlet.DemoServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DemoServlet</servlet-name>
<url-pattern>/demoservlet</url-pattern>
</servlet-mapping>
</web-app>
二、http协议:
创建好一个demo后,我们来开始讲讲仅仅的主题response。
在【java】servlet执行过程和访问过程中我们说过,访问servlet时 ,会自动创建response和request两个对象。现在我们使用httpservlet时,同样也会创建这两个对象,只不过他叫做HttpServletRequest 和HttpServletResponse。如下图:
今天我们要讲的的就是这个HttpServletResponse。
在之前,我们还需要连接http协议:
1.什么是Http协议
HTTP,超文本传输协议(HyperText Transfer Protocol)是互联网上应用最为广泛的 一种网络协议。所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为 了提供一种发布和接收HTML页面的方法
2.Http协议的组成
Http协议由Http请求和Http响应组成,当在浏览器中输入网址访问某个网站时, 你的浏览器会将你的请求封装成一个Http请求发送给服务器站点,服务器接收到请 求后会组织响应数据封装成一个Http响应返回给浏览器。即没有请求就没有响应。
3、举例说明http请求:
编辑一个form.html的表单页面,如下:
当点击提交按钮的时候,可以抓包:
1)请求行
请求方式:POST、GET
请求的资源:/DemoEE/form.html
协议版本:HTTP/1.1
HTTP/1.0,发送请求,创建一次连接,获得一个web资源,连接断开。
HTTP/1.1,发送请求,创建一次连接,获得多个web资源,保持连接。
2)请求头
请求头是客户端发送给服务器端的一些信息,使用键值对表示key:value
3)请求体
当请求方式是post的时,请求体会有请求的参数,格式如下:
username=zhangsan&password=123
如果请求方式为get,那么请求参数不会出现在请求体中,会拼接在url地址后面
http://localhost:8080/myserver?username=zhangsan&password=123
4、http响应:
此时我们抓包可以得到http响应:
1)响应行
Http协议
状态码:
常用的状态码如下:
200 :请求成功。
302 :请求重定向。
304 :请求资源没有改变,访问本地缓存。
404 :请求资源不存在。通常是用户路径编写错误,也可能是服务器资源已删除。
500 :服务器内部错误。通常程序抛异常。
状态信息:状态信息是根据状态码变化而变化的
2)响应头
响应也都是键值对形式,服务器端将信息以键值对的形式返回给客户端
3)响应体
响应体是服务器回写给客户端的页面正文,浏览器将正文加载到内存,然后解析渲染 显示页面内容
三、response
了解完http协议后,我们正式进入正题:(对不起,写了五千字才可是进入正题)先来看一个response运行图:
1.response的运行流程
接下来我们就来看看如何在servlet中设置response中的各个属性:
2、通过response设置——响应行
1)设置响应行的状态码 setStatus(int sc)
在响应行中,都是通过设置状态码来自动显示对象的状态信息的。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 手动设置http响应行中的状态码:
response.setStatus(302);
}
我们用postman捕捉到:
如果我们换成404:
3、通过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表示设置
实例:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 手动设置http响应行中的状态码:
//response.setStatus(404);
// 设置响应头:
response.addHeader("myname", "cheng");
response.addIntHeader("myage", 22);
Date date=new Date(0);
response.addDateHeader("mybirthday", date.getTime());
}
(1)实现重定向:
我们都知道,通过设置响应行,我们可以将状态码改成302(重定向),那我们应该如何设置重定向呢。大概流程如下图:
特定:访问服务器两次。地址栏中的地址发生了变化。
为此,我们需要重定向是,我们就需要修改response中的两个东西。
1)状态码:302
2)响应头:location ——代表重定向的地址。
a)实例:我们使用servlet1 重定向到servlet2
servlet1代码:
package httpservletResponseServlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet1 用于重定向,将路径指向servlet2
*/
public class Servlet1 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 {
//没有响应,并告知客户端从定向到servlet2
//1、设置状态码302
response.setStatus(302);
// 设置响应头中的location
response.setHeader("Location", "/httpservlet_response/servlet2");
}
/**
* @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);
}
}
servlet2代码:
package httpservletResponseServlet;
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 Servlet2
*/
public class Servlet2 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 {
response.getWriter().write("hello the world!!");
}
/**
* @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);
}
}
访问结果如下:
回车:
封装方法:
//没有响应,并告知客户端从定向到servlet2
//1、设置状态码302
response.setStatus(302);
// 设置响应头中的location
response.setHeader(“Location”, “/httpservlet_response/servlet2”);
---------------------------------
替换为:
//封装一个重定向的方法sendredirect(url)
response.sendRedirect("/httpservlet_response/servlet2");
b) 延时刷新并重定向:
package httpservletResponseServlet;
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 refresh
*/
public class refresh 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 {
//5秒后,跳转到百度页面。
response.setHeader("refresh", "5;url=http://www.baidu.com");
}
/**
* @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);
}
}
注意:如果要实现页面的定时刷新,需要使用js,略。
4、通过response设置——响应体
(1)响应体设置文本——PrintWriter getWriter()
获得字符流,通过字符流的write(String s)方法可以将字符串设置到response 缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览器端。
package httpservletResponseServlet;
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 content_txt
*/
public class content_txt 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 {
PrintWriter writer=response.getWriter();
writer.write("hello the world!!");
}
/**
* @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);
}
}
发布结果:
我们现在改成汉字:
package httpservletResponseServlet;
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 content_txt
*/
public class content_txt 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 {
PrintWriter writer=response.getWriter();
//writer.write("hello the world!!");
writer.write("您好!!");
}
/**
* @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);
}
}
原因:response缓冲区的默认编码是iso8859-1,此码表中没有中文,可以通过 response的setCharacterEncoding(String charset) 设置response的编码。
我们先来看一个流程:
修改代码:
我们需要将字符串写入response缓存之前就设置好编码格式
(2)响应体设置字节——ServletOutputStream getOutputStream()
获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字 节,在由Tomcat服务器将字节内容组成Http响应返回给浏览器。这个一般在获取文件的时候使用。
我们通过一个照片下载说说:
1)在webcontent目录下放一个照片:a.jpg
2)代码:
package httpservletResponseServlet;
import java.io.FileInputStream;
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 imageservlet
*/
public class imageservlet 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 {
//使用response获取字节输出流
ServletOutputStream out=response.getOutputStream();
//获取服务器上照片
String Path=this.getServletContext().getRealPath("a.jpg");//这是相对路径,都是要获取webcontent目录下的文件。
FileInputStream in=new FileInputStream(Path);
int len=0;
byte[] buffer=new byte[1024];//以1024个字节为一组
while((len=in.read(buffer))>0) {
out.write(buffer,0,len);
}
in.close();
out.close();
}
/**
* @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);
}
}
四、源码下载:https://download.csdn.net/download/aiming66/10888246
备注:Tomcat:8.5
jdk:1.8