Servlet 学习(四)
HTTP 响应的构成
1、HTTP 响应行:
- 协议、状态、描述
- HTTP 1.1 中定义的状态代码
100-199 是信息性代码,标示客户应该采取的其它动作
200-299 表示请求成功
300-399 表示那些已经移走的文件,常包括Location 报头,指出新的地址
400-499 表示由客户引发的错误
500-599 表示由服务器引发的错误
2、HTTP 响应报头: (头部/首部/响应头)
- 响应头和响应正文之间用空行分隔
- 常用的响应报头
3、HTTP 响应正文:
- 响应正文可以是 HTML 、CSS 、 JavaScript 、TXT ....
response.getWriter();
- 响应正文可以是也可以是 二进制文件,比如 mp4 、mp3 、jpeg 、gif 、doc 、pdf
response.getOutputStream();
HttpServletResponse类型的对象
1、基于HTTP 协议的请求响应机制的信息交换过程
- 建立连接:
客户端与服务器建立TCP 连接
- 发送请求:
建立连接后,客户端把请求消息发送到服务器的相应端口上
- 处理请求
Servlet 容器接受到HTTP 请求
解析HTTP 请求并封装相应的对象
- 发送响应:
服务器在处理完客户端请求之后,要向客户端发送响应消息
- 关闭连接:
客户端和服务器双方都可以通过关闭Socket 来结束TCP/IP 对话
2、与响应报头有关的方法:
- void setHeader( String name , String value ) 设置响应报头的通用方法
- boolean containsHeader( String name ) 判断指定名称的响应报头是否存在,存在即返回true
- void addCookie( Cookie cookie ) 在 响应报头中 添加 一个 Cookie ( 在 set-cookie 报头中追加一个 cookie 值 ,相当于 setHeader( "set-cookie" , value ))
- void setContentType( String mimeType ) 相当于 setHeader( "content-type" , mimeType )
- 常用的 MIME(Multipurpose Internet Mail Extension) 类型:
application/octet-stream 未识别 或 二进制数据 application/pdf PDF 文档
video/mpeg MPEG 视频文件 image/gif 动态图片
image/jpeg 照片图片( .jpeg 、.jpg ) image/png 透明图片text/html HTML文档
text/plain 纯文本文档 text/css CSS样式
text/javascript JavaScript 脚本代码 text/xml XML 文档
text/json JSON 格式的文本 ( JSON : JavaScript Object Notation )
响应报头测试案例一:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Response</title>
<style type="text/css">
a {
display: block ;
width: 400px ;
line-height: 50px ;
border: 1px solid blue ;
margin: 10px auto ;
text-align: center ;
}
</style>
</head>
<body> <a href="/Servlet/header/first"> First Header Servlet ( content type) </a> <a href="/Servlet/header/second"> Second Header Servlet ( refresh ) </a> <a href="/Servlet/image/show"> Show Image Servlet ( content dispositoin ) </a> <a href="/Servlet/image/down"> Download Image Servlet ( content dispositoin ) </a> <a href="/Servlet/status"> Response Status Servlet ( content dispositoin ) </a> <a href="/Servlet/redirect"> My Redirect Servlet ( content dispositoin ) </a> </body>
</html>
package ecut.response; import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; @WebServlet( urlPatterns= { "/header/first" , "/f" } ) public class FirstHeaderServlet extends HttpServlet { private static final long serialVersionUID = -5880198269462470756L; @Override
protected void service( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException {
request.setCharacterEncoding( "UTF-8" );
response.setCharacterEncoding( "UTF-8" ); //设置响应的字符编码 (在服务器上起作用) // 获得可以向客户端发送数据的输出流之前,就需要设置响应报头
//response.setHeader( "content-type" , "text/html;charset=UTF-8" ); //设置响应正文的MIME(多任务因特网邮件扩充)类型
response.setContentType( "text/html;charset=UTF-8" ); // 设置响应正文的 MIME 类型
// 这里的 charset=UTF-8 用来告知 WEB 客户端 以何种编码处理接受到的 字符 System.out.println( response.containsHeader( "content-type" ) ); PrintWriter w = response.getWriter();
// 发送响应正文
w.println( "<div style='text-align:center ; border : 1px solid blue ; height : 400px ; width : 500px ; margin : auto auto ; '>" );
w.println( "天天向上" );
w.println( "</div>" ); } }
运行结果如下:
控制台输出true,页面跳转到如下页面
Servlet 3.0 开始允许使用注解来标注Servlet
- @WebServlet在一个实现过Servlet 接口的类上标注,声明这是一个Servlet
@WebServlet 的常用属性
String name 指定当前Servlet 的名称,相当于xml 中的servlet-name
String[] value 指定当前Servlet 对应的url (与url-pattern 对应)
String[] urlPatterns 与value 作用相同
int loadOnStartup 作用与load-on-startup ,设定Servlet 的加载顺序
boolean asyncSupported 指定是否支持异步操作
WebInitParam[] initParams 用于设置Servlet 初始化参数
- @WebInitParam必须与@WebServlet 、@Filter 等联合使用,用于配置Servlet 或Filter 的初始化参数,等同于init-param。
@WebInitParam 的属性
String name : 用于设置初始化参数的名称
String value : 用于设置初始化参数的值
响应报头测试案例二:
package ecut.response; 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.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; @WebServlet( value = { "/header/second" , "/s" , "/refresh" } )
public class SecondHeaderServlet extends HttpServlet { private static final long serialVersionUID = -5880198269462470756L; private Date date = new Date();//只创建一次不要反复创建
private DateFormat df = new SimpleDateFormat( "yyyy年MM月dd日 HH:mm:ss.SSS" ); @Override
protected void service( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException {
request.setCharacterEncoding( "UTF-8" );
response.setCharacterEncoding( "UTF-8" ); // 设置 响应 的字符编码 (在服务器上起作用) // 动态获得当前 WEB 应用 的 路径 ( context path )
String applicationPath = request.getContextPath() ; System.out.println( "applicationPath : " + applicationPath );
//每3秒刷新一次
//response.setHeader( "refresh" , "3,URL=" + applicationPath + "/refresh" ); // response.setHeader( "refresh" , "3,URL=/Servlet/refresh" ); // 定时刷新 response.setHeader( "refresh" , "3,URL=/Servlet/header/first"); // 定时跳转 response.setContentType( "text/html;charset=UTF-8" ); // 设置响应正文的 MIME 类型 PrintWriter w = response.getWriter();
w.println( "<div style='text-align:center ; border : 1px solid blue ; height : 400px ; width : 500px ; margin : auto auto ; '>" ); date.setTime( System.currentTimeMillis() );
w.println( df.format( date ) ); w.println( "</div>" ); } }
运行结果:
3秒后跳转到first页面
响应报头里设置 响应正文为二进制文件测试案例一:
package ecut.response; import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths; 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; @WebServlet( "/image/show" )
public class ShowImageServlet extends HttpServlet { private static final long serialVersionUID = 1376233444161496825L; @Override
protected void service(HttpServletRequest request , HttpServletResponse response )
throws ServletException, IOException {
request.setCharacterEncoding( "UTF-8" );
response.setCharacterEncoding( "UTF-8" ); response.setHeader( "content-type" , "image/jpeg" ); // 响应报头 content-disposition 用来设置 响应正文中的二进制数据是 在浏览器显示 还是 由浏览器下载
response.setHeader( "content-disposition" , "inline" );
//Path接口表示一个目录或一个文件对应的路径(它可以定位本地系统中的一个文件或目录)
//Paths类是一个工具类,其中定义了两个静态方法,专门用来返回Path对象:
//static Path get(String first, String... more)转换的路径字符串,或一个字符串序列,当加入形成一个路径字符串, Path。
Path source = Paths.get( "D:/Koala.jpg" );
//FileInputStream in = new FileInputStream( "D:/Koala.jpg" ); // 获得可以向客户端发送二进制数据的字节输出流
ServletOutputStream out = response.getOutputStream();
// nio将 source 中的内容 "复制" 到 out 对应的输出流,实际上就完成了输出操作
Files.copy( source, out ) ; /*
byte[] bytes = new byte[32] ;
int n ;
while( ( n = in.read( bytes ) ) != -1 ){
out.write( bytes , 0 , n );
}
*/ } }
运行结果:
在浏览器中展示了响应的图片
响应报头里设置 响应正文为二进制文件测试案例二:
package ecut.response; import java.io.IOException;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths; 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; @WebServlet( "/image/down" )
public class DownloadImageServlet extends HttpServlet { private static final long serialVersionUID = 448136179136896451L; @Override
protected void service(HttpServletRequest request , HttpServletResponse response )
throws ServletException, IOException {
request.setCharacterEncoding( "UTF-8" );
response.setCharacterEncoding( "UTF-8" ); String name = "Koala.jpg" ; Path source = Paths.get( "D:/" , name ); response.setHeader( "content-type" , "image/jpeg" ); // 响应报头 content-disposition 用来设置 响应正文中的二进制数据是 在浏览器显示 还是 由浏览器下载
name = URLEncoder.encode( name , "UTF-8" ); // 如果文件名中含有汉字,则需要对汉字进行编码
System.out.println( "编码后:" + name );
response.setHeader( "content-disposition" , "attachment;filename='" + name + "'" ); // 获得可以向客户端发送二进制数据的字节输出流
ServletOutputStream out = response.getOutputStream();
// 将 source 中的内容 "复制" 到 out 对应的输出流,实际上就完成了输出操作
Files.copy( source, out ) ; } }
运行结果:
对应目录下增加了相应的图片
3、与响应状态有关的方法:
- void sendError( int statusCode , String statusMessage )
响应状态测试案例一:
package ecut.response; import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; @WebServlet( "/status" )
public class ResponseStatusServlet extends HttpServlet { private static final long serialVersionUID = -7904861099406918294L; @Override
protected void service( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException {
request.setCharacterEncoding( "UTF-8" );
response.setCharacterEncoding( "UTF-8" ); int statusCode = 404 ;
String statusMessage = "这个Servlet是存在的,但是就是不让你访问" ;
response.sendError( statusCode , statusMessage );
//response.setStatus(statusCode); //效果不明显 response.setContentType( "text/html;charset=UTF-8" ); PrintWriter w = response.getWriter();
w.println( "<div style='text-align:center ; border : 1px solid blue ; height : 400px ; width : 500px ; margin : auto auto ; '>" );
w.println( "天天向上" );
w.println( "</div>" ); } }
运行结果如下:
响应状态测试案例二:
package ecut.response; import java.io.IOException; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; @WebServlet( "/redirect" )
public class MyRedirectServlet extends HttpServlet { private static final long serialVersionUID = -6205011155467276976L; @Override
protected void service( HttpServletRequest request, HttpServletResponse response )
throws ServletException, IOException {
request.setCharacterEncoding( "UTF-8" );
response.setCharacterEncoding( "UTF-8" ); try {
Thread.sleep( 5000 );
} catch (InterruptedException e) {
e.printStackTrace();
} // 设置响应状态代码
response.setStatus( 302 ); // 通知 WEB 客户端 需要打开另外的一个 "位置"
// 设置 响应报头
//response.setHeader( "location" , request.getContextPath() + "/pages/request/index.html" );
response.setHeader( "location" , "http://www.baidu.com" ); // response.sendRedirect( request.getContextPath() + "/index.html" ); } }
302 命令浏览器链接到新的位置: sendRedirect( String url ),该方法会生成302 响应和Location 报头; url 可以是相对,也可以是绝对。
运行结果如下:
重定向达到百度页面
转载请于明显处标明出处
http://www.cnblogs.com/AmyZheng/p/8830801.html
Servlet 学习(四)的更多相关文章
- Servlet学习四——传输文本
在最初使用Servlet时,觉得get方法很好用,也了解到传输一般性的变量,除了文件流和安全性外,都可以用get方法,所以,也就习惯用get方法了. 在实现一个注册方法过程中,中文注册都是乱码,跟踪后 ...
- jsp/servlet学习四之jsp初窥
jsp页面本质上是一个servlet,jsp页面是一个以.jsp结尾的文本文件. jsp自带的API包含4个包: javax.servlet.jsp.包含用于servlet/jsp容器将jsp页面翻译 ...
- Servlet学习(四)——response
1.概述 在创建Servlet时会覆盖service()方法,或doGet()或doPost(),这些方法都有两个参数,一个是代表请求的request和代表响应response. service方法中 ...
- Servlet学习(九)——request
request运行流程在Servlet学习(四)——response已介绍,不再赘述 1.通过抓包工具获取Http请求 因为request代表请求,所以我们可以通过该对象分别获得Http请求的请求行, ...
- Servlet学习笔记(四)
目录 Servlet学习笔记(四) 一.会话技术Cookie.session 1. 什么是会话技术? 2. 会话技术有什么用? 3. Cookie 3.1 什么是Cookie? 3.2 使用Cooki ...
- Servlet 学习笔记
Servlet 运行在服务器上的 java 类: Servlet 容器为 javaWeb 应用提供运行时环境,负责管理 servlet 和 jsp 生命周期,以及管理他们的共享数据. 现在我们知道了 ...
- Servlet学习:(三)Servlet3.0 上传文件
转: Servlet学习:(三)Servlet3.0 上传文件 2018年08月03日 11:57:58 iDark_CSDN 阅读数:362 一.注意事项 客户端(浏览器) 表单的提交方法必须是 ...
- (转)SpringMVC学习(四)——Spring、MyBatis和SpringMVC的整合
http://blog.csdn.net/yerenyuan_pku/article/details/72231763 之前我整合了Spring和MyBatis这两个框架,不会的可以看我的文章MyBa ...
- servlet的四个作用域
作用域规定的是变量的有效期限,servlet有四个作用域对象,这里只说三个: 一. request作用域: 1.作用范围: 就是指从http请求发起,到服务器处理结束,返回响应的整个过程.在这个过程中 ...
- TweenMax动画库学习(四)
目录 TweenMax动画库学习(一) TweenMax动画库学习(二) TweenMax动画库学习(三) Tw ...
随机推荐
- mac 电脑安装express、npm…… 报 ‘Missing write access to /usr/local/lib/node_modules’错误解决办法
mac电脑安装express框架.npm…… 报 Missing write access to /usr/local/lib/node_modules 错误 终端输入sudo chown -R $U ...
- 虚拟机安装archLinux+xfce桌面教程(更新时间2017-5-8)
本教程转自http://blog.sina.com.cn/u/5692023517 感谢大神写出如此详细的教程并允许转载 本教程的目的:为了让新手安装arch不再那么难, 一个好的教程可以少走很多弯路 ...
- python GIL锁与多cpu
多核CPU linux : cat /proc/cpuinfo 如果你不幸拥有一个多核CPU,你肯定在想,多核应该可以同时执行多个线程. 如果写一个死循环的话,会出现什么情况呢? 打开Mac OS ...
- oracle 唯独测试视图
--建立用户分配权限 create user groper identified by groper / grant connect,resource to groper / grant create ...
- 刷题11. Container With Most Water
一.题目说明 11.Container With Most Water,这个题目难度是Medium. 二.我的做法 乍一看,简单啊,两个for循环就可以了,我在本地写的. #include<io ...
- java篇 之 多态
2018-9-28 多态: 重载也称为静态多态(静态在编译阶段就能确定)(动态是跟运行时挂钩) 尽量去选择关系轻的,降低耦合度(紧密度) 内聚: 减少与外界的联系,降低与其他对象和类的联系 对象与对象 ...
- 吴裕雄 python 机器学习——数据预处理流水线Pipeline模型
from sklearn.svm import LinearSVC from sklearn.pipeline import Pipeline from sklearn import neighbor ...
- Android如何运行他人工程
首先新建一个本地的新工程做对比,用记事本打开以下的几个工程文件,把本地工程文件的内容覆盖掉他人工程的文件内容,注意只覆盖两个工程共有的内容条目即可,不要删掉他人工程的其他依赖!(具体哪几个文件本人还没 ...
- Windows 10下一步一步创建 Scrapy框架的项目
此文是本人的学习笔记,网上搜索了很多资料,也走了一些弯路,记录下安装的过程,以便日后回顾 1.安装Anaconda3,安装时默认选项 2.装完Anaconda3后,打开系统变量在path路径下增加An ...
- Elasticsearch系列---初识mapping
概要 本篇简单介绍一下field数据类型mapping的相关知识. mapping是什么? 前面几篇的实战案例,我们向Elasticsearch索引数据时,只是简单地把JSON文本放在请求体里,至于J ...