服务器响应的生成:HTTP响应报头
前面提到了,web服务器响应一般由状态行,一个或多个响应报头(其中一个必须为Content-Type),一个空行和关联文档组成,要让servlet发挥最大的效力,你不仅需要知道如何生成文档(事实上以后都是用jsp来完成这个工作的),更重要的是要知道 有效地利用状态行和响应报头
如前所述,HTTP响应报头的设置,经常是和状态代码的设置结合一起的,例如文档发生移动的状态代码300到307都伴随一个Location头,401(Unauthorized)
代码经常包括伴随WWW-Authenticate的报头。
即使在设置正常的状态代码时,指定报头也是十分重要的。响应报头可以用来:指定cookie,提供页面的修改日期(用于客户端缓存),指示浏览器在指定的时间间隔后重新载入页面,给出文件的大小使持续性http连接的应用成为可能,指定生成文档的类型以及执行许多其他任务。
7.1 在servlet中设置响应报头
1, 指定报头时,最通用的方式是使用HttpServletResponse的setHeader方法,接受两个字符串,报头名和报头值:
setHeader(String headerName, String headerValue);//注意这样就只能设置报头值是String类型的报头了
这是通用的方法,对于含有整数和日期的报头,提供了专门的方法,消去上述职能设置String值的缺点:
setDateHeader(String header, long milliseconds)
setIntHeader(String header, int headerValue)
2, HTTP允许同名的报头名多次出现,有时候我们希望加入新的报头,这时就用addHeader,addDateHeader,addIntHeader;(set替换,add新增),如果需要知道是否已经包含了特定的报头,可以用containsHeader进行检查。
3, HttpServletResponse还提供了许多方便的方法来指定常用的报头(就不用再使用setHeader了)
setContentType(String mimeType) 设置Content-Type报头,大多数servlet都要用到这个
setContentLength(int length) 设置Content-Length报头,如果浏览器支持持续性http连接,这个报头将十分有用
addCookie(Cookie c) 见cookie管理
sendRedirect(String address) 将状态代码设为302,并设置Location报头
7.2 理解HTTP1.1响应报头
理解常见报头的含义:
Allow 指定服务器支持的请求方法
Cache-Control
Connection close值指定浏览器不要使用持续性http连接
Content-Disposition
Content-Encoding 页面传输使用的编码,gzip,,,
Content-Language
Content-Length
Content-Type 响应文档的mime类型
Expires
Last-Modified
Location 通知浏览器文档的地址
Pragma
Refresh 表明浏览器多长时间后请求最新的页面 例如response.setIntHeader("Refresh", 30);
Retry-After 告诉客户程序多久后重复它的请求
Set-Cookie
WWW-Authenticate
棕色表示的报头在下面的示例中会用到
7.3 示例:构建Excel表格
servlet也可以生成Excel类型,Excel的MIME类型是application/vnd.ms-excel:
response.setContentType("application/vnd.ms-excel");
PrintWriter out = response.getWriter();
package coreservlets;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
//输出一个简单的excel表格
public class ApplesAndOranges extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/vnd.ms-excel");//设置setContent-Type报头指定输出格式
PrintWriter out = response.getWriter();
//excel接受制表符/t
out.println("\tQ1\tQ2\tQ3\tQ4\tTotal");
out.println("Apples\t78\t87\t92\t29\t=SUM(B2:E2)");
out.println("Oranges\t77\t86\t93\t30\t=SUM(B3:E3)");
}
}
请求:http://localhost:8080/Servlet/servlet/ApplesAndOranges的结果----
打开表格内容为:
7.4 servlet状态的持续以及页面的自动重载
如果你的jsp或者servlet执行一项耗时较长的计算任务,比如20秒或者更多,你不能知网计算完成后再将结果发送至客户,到那时客户可能已经放弃并离开该页面或者更坏---用户单击Reload重新计算过程。解决方案:
1)一种跨请求存储数据的方式
对于不专属于任意客户的数据,可以将其存储在servlet的字段变量中(实例变量),对于用户专用的数据,可以将其存储在HttpSession对象中(参见后续章节),对于其他servlet和jsp页面需要用到的数据,可以存储到ServletContex中(后续章节)。
2)一种在请求发送给用户后,继续保持运算的方式
启动一个线程,系统为了应答请求而启动的线程,在响应完成后线程自动结束,但其他的线程会保持运行。要将线程的优先级设为一个较低的值,才不至于影响整个服务器的运行
3)一种在更新的结果就绪后,使浏览器得到它的方式
遗憾的是,服务器主动的将新结果发送给浏览器并不容易,因为浏览器并不维护一个与服务器之间保持打开的连接,只能让浏览器去主动请求,这样就用Refresh报头来指定重新请求的时间间隔
7.5 使用servlet生成jpeg图像
跟excel差不多,就是具体过程麻烦点,不写在这了
这两章主要都在讲服务器对浏览器请求的响应,要理解响应的格式,这两章分开讲解了响应内容中的状态码和报头,理解servlet是怎样利用这些状态码和响应报头来完成一些应用的