一、请求报文
客户端在向服务器发送数据时,不仅有一些显式的数据(用户名、密码等),
还需要传递一些隐式的数据,例如是否缓冲、是否长连接、报文长度等信息。
请求报文就包含这些隐式和显式的信息。
请求报文结构:
1.请求行:主要包括请求方式(如POST、GET等),请求对应的URL与请求头字段HOST中的属性组成完整的请求URL。
2.请求头:是HTTP的报文头,报文头包含若干属性,由键值对组成。
3.请求体:是报文体,将页面中提交的相关信息以键值对的方式组合成一个字符串。
(例如username=111&pwd=1234&sex=0&like=1)
请求报文样例:
获取请求头信息的方法:
javax.servlet.http.HttpServletRequest.getHeaderNames()
获取所有头部字段名。
javax.servlet.http.HttpServletRequest.getHeader(String name)
以字符串形式返回指定的请求头字段(name)的值。
<!DOCTYPE html> <!-- http://localhost:8080/TestServlet/Test.html --> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <!--表单提交调用servlet --> <!-- http://localhost:8080/TestServlet/TestServlet.html --> <form name = f1 action = "/TestServlet/TestServlet.html" method = "get"> username:<input type = "text" name = "username"></input><br> pwd:<input type = "password" name = "pwd"></input><br> 性别:<input type = "radio" name = "sex" value = "0"> 男 <input type = "radio" name = "sex" value = "1">女<br> 爱好:<input type = "checkbox" name = "like" value = "1">篮球 <input type = "checkbox" name = "like" value = "2">足球<br> <input type = "submit" value = "提交"> </form> </body> </html>
import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestServlet extends HttpServlet{ // private PrintStream out = System.out; private String initParam = null; private String contextParam = null; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter out = resp.getWriter(); //获取所有头部字段名 Enumeration headNames = req.getHeaderNames(); //打印html头部代码 printHtmlPage(out,true); //绘制html表格显示获取参数 out.println("<table border = 2>"); //遍历包含所有头部字段的枚举对象 while(headNames.hasMoreElements()) {//判断是否有更多元素 String headName = (String)headNames.nextElement();//获取当前枚举参数。 //根据当前头部字段获取对应值 String values = req.getHeader(headName); //输出头部字段 out.println("<tr>"); out.print("<td>"); out.print(headName); out.print("</td>"); //输出头部字段所对应的值 out.print("<td>"); out.print(values); out.print("</td>"); out.println("</tr>"); } out.println("</table>"); //打印html尾部代码 printHtmlPage(out,false); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doGet(req, resp); } //打印HTML页面,head为True打印HTML头部代码,为false打印尾部HTML代码 private void printHtmlPage(PrintWriter out, boolean head) { if(head) { out.println("<!DOCTYPE html>\r\n" + "<!-- http://localhost:8080/TestServlet/Test.html -->\r\n" + "<html>\r\n" + "<head>\r\n" + "<meta charset=\"UTF-8\">\r\n" + "<title>Insert title here</title>\r\n" + "</head>\r\n" + "<body>"); }else { out.println("</body>\r\n" + "</html>"); } } }
host:请求的目标域名和端口号
connection:表示是否需要持久连接。(HTTP 1.1默认进行持久连接)
content-length:报文中实体主体的大小。
cache-control:缓存策略。
Origin:请求的来源域名和端口号 (跨域请求时,浏览器会自动带上这个头信息)。
upgrade-insecure-requests:让浏览器升级请求从http到https。
content-type:互联网媒体类型;也叫做MIME类型,在Http协议消息头中,使用Content-Type来表示具体请求中的媒体类型信息。
常见媒体类型:
text/html : HTML格式
text/plain :纯文本格式
text/xml : XML格式
image/gif :gif图片格式
image/jpeg :jpg图片格式
image/png:png图片格式
application/xhtml+xml :XHTML格式
application/xml : XML数据格式
application/atom+xml :Atom XML聚合格式
application/json : JSON数据格式
application/pdf :pdf格式
application/msword : Word文档格式
application/octet-stream : 二进制流数据(如常见的文件下载)
application/x-www-form-urlencoded : <form encType=””>中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)
user-agent:浏览器信息。
accept:代表客户端希望接收的数据类型。
referer:请求资源的完整URL。
accept-encoding:请求的 HTTP 标头通告其内容编码,通常是一个压缩算法。
accept-language:请求头允许客户端声明它可以理解的自然语言,以及语言的权重(q=0.9),权重即高即越希望选择该语言。
关于头字段对应含义可参阅:https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
二、响应报文
响应报文结构:
响应行:包含报文协议、版本、状态码、状态描述。(HTTP/1.1 200 OK)
响应头:报文头包含若干属性,由键值对组成(向客户端发送的数据类型、刷新时间等),与请求头类型。
响应体:响应体主要就是我们需要的正文信息。
响应头对应的属性和含义可参阅:https://www.cnblogs.com/wangyang108/p/5755525.html
实际中可以根据需求设置一些响应头信息,已满足某些需求。
设置响应头信息方法:
void javax.servlet.http.HttpServletResponse.setHeader(String name, String value)
//设置对应头部字段名的值
void javax.servlet.ServletResponse.setContentType(String type)
//设置发送到客户端的响应的内容类型
还有其他对应属性的setXXX方法,可参阅API.
下面来看几个小例子。
2.1设置发送到客户端的内容为Excel表格。
import java.io.IOException; import java.io.PrintWriter; import java.util.Collection; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestResponseInfomation extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub //设置响应消息为Excel格式
resp.setContentType("application/vnd.ms-excel"); PrintWriter out = resp.getWriter();
//设置Excle内容 out.println("\tQ1\tQ2\tQ3\tQ4\tTotal"); out.println("Apple\t78\t87\t99\t12\t=SUM(B2:D2)"); out.println("orange\t8\t8\t9\t2\t=SUM(B2:D2)"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub super.doGet(req, resp); } }
<servlet-mapping> <servlet-name>testResponse</servlet-name> <url-pattern>/TestResponse.xls</url-pattern> </servlet-mapping>
使用Chrome浏览器测试时,最好将Servlet-Mapping最后部分为XXX.xls。
IE,Edge则没有此限制,。
2.2设置发送到客户端的内容为图片。
import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestResponseInfomation extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub int len = -1;//设置写入字节数 resp.setContentType(" image/jpeg");//设置内容为图片jpg格式 InputStream is = new FileInputStream("F:\\依风\\Pictures\\下载图片\\bg.jpg"); //获取response的输出流 OutputStream os = resp.getOutputStream(); byte[] buff = new byte[1024]; while((len = is.read(buff)) != -1) { os.write(buff,0,len); } os.flush(); os.close(); is.close(); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub super.doGet(req, resp); } }
2.3设置刷新时间。
例如在响应界面中输出当前时间,每秒刷新一次。(实际中不建议这样每秒刷新一次,比较占用服务器资源)
这样界面上的时间就不不停增加,呈现出一种动态的效果。
import java.io.IOException; import java.io.PrintWriter; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestResponseInfomation extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub resp.setHeader("Refresh", "1"); PrintWriter out = resp.getWriter(); printHtmlPage(out,true); DateFormat df = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss"); out.print("<h1>" + df.format(new Date(System.currentTimeMillis())) + "</h1>"); printHtmlPage(out,false); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub super.doGet(req, resp); } //打印HTML页面,head为True打印HTML头部代码,为false打印尾部HTML代码 private void printHtmlPage(PrintWriter out, boolean head) { if(head) { out.println("<!DOCTYPE html>\r\n" + "<!-- http://localhost:8080/TestServlet/Test.html -->\r\n" + "<html>\r\n" + "<head>\r\n" + "<meta charset=\"UTF-8\">\r\n" + "<title>Insert title here</title>\r\n" + "</head>\r\n" + "<body>"); }else { out.println("</body>\r\n" + "</html>"); } } }
浏览器每过一秒会刷新一次,从Servlet获取新的时间输出到界面上,这样比较浪费服务器资源,
平常不建议使用
参考资料:https://blog.csdn.net/u010256388/article/details/68491509/