一、HttpServletResponse的应用
Web服务器发送给客户端浏览器的消息有3个部分:状态行、消息头和消息正文。
(1) 产生响应状态行
HTTP响应消息的状态行为分为3个部分:HTTP版本、状态码和状态信息。
・HTTP版本:HTTP/1.1 HTTP/1.0
100~199:表示服务器端成功接收HTTP请求,但是要求客户端继续提交下一次HTTP请求才能完成全部处理过程。
200~299:表示服务器端成功接收HTTP请求,并完成了全部处理过程。
300~399:表示客户端请求的资源已经移动了别的位置,并向客户端提供一个新的地址,一般这个新地址由HTTP响应消息头的Location字段指定。
400~499:表示客户端的请求有错误。
500~599:表示服务器端出现错误。
HttpServlet:
public void setStatus(int sc);
sc状态码:可以为整数,可以为常量(建议);
public void sendRedirect(String location) throws IOException;
通过sendRedirect方法可以将当前的
Servlet重定向到其他的Web资源上,这个URL可以使绝对路径(www.google.cn)或相对路径(/samples/test.html)
public void sendError(int sc) throws IOException;
public void sendError(int sc, String msg) throws IOException;
sc表示响应状态码(一般是404),msg表示状态消息。
(2) 设置响应消息头
HTTP响应消息头是由key-value对组成的,key表示字段名,value表示字段值,eg,
Content-Length: 1024
Content-Type: text/html
Content-Location: http://nokiaguy.blogjava.net
Accept-Ranges: bytes
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
Date: Tue, 30 Dec 2008 11:49:53 GMT
response
・public void addHeader(String name, String value);
・public void setHeader(String name, String value);
如出现同名name(不区分大小写),set使用覆盖,add使用新增(HTTP响应消息头允许存在多个同名的字段)
・public void addIntHeader(String name, int value);
・public void setIntHeader(String name, int value);
与上两种方法类似,只是整型字段避免将int类型转换为String类型的麻烦
・public void addDateHeader(String name, long date);
・public void setDateHeader(String name, long date);
・void setContentType(String type)
用于设置Servlet响应正文的MIME类型,对HTTP协议就是设置Content-Type字段的值
MINE类型消息:(<Tomcat安装目录>\conf\web.xml)
audio/x-mpeg
application/postscript
audio/x-aiff
image/png
text/html
・void setCharacterEncoding(String charset)
在使用setCharacterEncoding方法之前,如果Content-Type字段不存在,必须使用setContentType或setHeader方法添加Content-Type字段,否则setCharacterEncoding方法字符集类型不会出现在响应消息头上。
・void setContentLength(int len)
・boolean containsHeader(String name)
检查HTTP响应消息头是否存在此字段名。
・public void setLocale(java.util.Locale loc)
(3) 禁止浏览器缓存当前Web页面
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
(4) 网页定时刷新和定时跳转
response.setHeader("Refresh", "3"); //每隔3s页面刷新一次
response.setHeader("Refresh", "3;URL=http://www.google.cn"); //一定要有协议前缀,如:http://,否则只跳转到当前目录下网页。
response.sendRedirect("http://www.csdn.net");
package chapter5;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
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;
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html; charset=UTF-8");
String url = request.getParameter("url");
if (url == null) {
url = "http://www.google.cn";
response.setHeader("Refresh", "3;URL=" + url);
PrintWriter out = response.getWriter();
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
out.println(dateFormat.format(new java.util.Date()));
}
}
(5) 实现动态文件下载
package chapter5;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
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;
/**
* Servlet implementation class Download
public class Download extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#service(HttpServletRequest request, HttpServletResponse
* response)
protected void service(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String path = this.getServletConfig().getInitParameter("path");
String filename = request.getParameter("filename");
File dir = new File(path);
if (dir.exists()) {
if (filename != null) {
filename = dir.getPath() + File.separator + filename;
File downloadFile = new File(filename);
download(downloadFile, response);
} else {
listDir(dir, response);
}
private void download(File file, HttpServletResponse response)
throws ServletException, IOException {
if (file.exists()) {
if ((file.getName().length() - file.getName().lastIndexOf(".jpg")) == 4) {
response.setContentType("image/jpg");
response.addHeader("Content-Disposition", "filename="
+ URLEncoder.encode(file.getName(), "UTF-8"));
} else {
response.setContentType("application/octet-stream");
response.addHeader("Content-Disposition",
"attachement;filename="
+ URLEncoder.encode(file.getName(), "UTF-8"));
response.addHeader("Content-Length", String.valueOf(file.length()));
InputStream is = new FileInputStream(file);
byte[] buffer = new byte[8192];
int count = 0;
ServletOutputStream sos = response.getOutputStream();
while ((count = is.read(buffer)) > 0) {
sos.write(buffer, 0, count);
is.close();
sos.close();
}
private void listDir(File dir, HttpServletResponse response) throws ServletException, IOException{
response.setContentType("text/html; charset=UTF-8");
PrintWriter out=response.getWriter();
for (File file: dir.listFiles()){
if (file.isFile()){
out.print("<a href='Download?filename="+URLEncoder.encode(file.getName(), "UTF-8")+"'>");
out.println(file.getName()+"</a><br/>");
}
path是Download类的初始化参数
<servlet>
<description>
</description>
<display-name>Download</display-name>
<servlet-name>Download</servlet-name>
<servlet-class>
chapter5.Download</servlet-class>
<init-param>
<param-name>path</param-name>
<param-value>E:\Michelangelo\Video\Image</param-value>
</init-param>
</servlet>
二、HttpServletRequest的应用(1) 获得HTTP请求行信息
HTTP请求消息的请求行:请求方法(GET、POST、HEAD等) 资源路径 HTTP协议版本
・getMethod:返回HTTP请求消息的请求方法(GET、POST、HEAD),请求行的第一部分
・getRequestURI:返回请求行中资源名部分
・getQueryString:返回请求行中参数部分
・getProtocol:返回HTTP版本
・getContextPath:返回请求URL中Web应用程序的路径
・getPathInfo:返回额外的路径部分
・getPathTranslated:返回URL中额外信息所对应的服务端的本地路径
・getServletPaht:返回Servlet在web.xml中定义<url-pattern>元素的值
・getParameterNames:返回一个Enumeration对象,封装了URL的所有的请求参数名
・getParameter:返回某一个请求参数的值
(2) 获得网络连接信息
・ getRemoteAddr:返回客户机用于发送请求的IP地址
・ getRemoteHost:返回发出请求的客户机的主机名
・ getRemotePort:返回客户及使用的网络接口的端口号
・ getLocalAddr:返回Web服务器上接收请求的网络接口使用的IP地址
・ getLocalName:返回Web服务器上接收请求的网络接口使用的IP地址所对应的主机名
・ getLocalPort:返回Web服务器上接受请求的网络接口的端口号
・ getServerName:返回HTTP请求消息的Host字段值的主机名部分
・ getServerPort:返回HTTP请求消息的Host字段值的端口号部分
・ getScheme:返回所请求的协议名
・ getRequestURL方法:返回完整的URL请求,StringBuffer类型
(3) 获得HTTP请求消息头
・ getHeader:返回指定的HTTP请求消息头字段的值
・ getHeaders:返回一个Enumeration对象,该对象封装了某个指定名头字段的所有同名字段值
・ getHeaderNames:返回一个Enumeration对象,该对象封装了所有的HTTP请求消息头字段的名称
・ getIntHeader:返回一个指定的整型头字段的值
・ getDateheader:返回一个指定的日期头字段的值
・ getContentType:返回请求消息钟情求证我的MIME类型,也就是Content-Type头字段的值
・ getContentLength:返回请求消息中请求正文的长度(以字节为单位),也就是Content-Length字段的值,如果未指定长度,返回-1
・ getCharacterEncoding:返回请求消息正文的字符集编码,通常从Content-Type字段中提取
(4) 客户端身份验证
package chapter5;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class AuthenticateServlet
public class AuthenticateServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#service(HttpServletRequest request, HttpServletResponse response)
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setContentType("text/html; charset=UTF-8");
PrintWriter out =response.getWriter();
String base64Auth=request.getHeader("Authorization");
if (base64Auth==null || !base64Auth.toUpperCase().startsWith("BASIC")){
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setHeader("WWW-Authenticate", "BASIC realm=\""+
request.getContextPath()+"\"");
out.println("需要进行身份验证");
return;
sun.misc.BASE64Decoder base64Decoder=new sun.misc.BASE64Decoder();
String auth=new String(base64Decoder.decodeBuffer(base64Auth.substring(6)));
String[] array=auth.split(":");
if (array.length==2){
String user= array[0].trim();
String password=array[1].trim();
RequestDispatcher rd = request.getRequestDispatcher("HeaderInfo");
rd.include(request, response); // 输出所有的HTTP请求头
// 进行身份验证
if(user.equals("admin") && password.equals("1234"))
out.println("身份验证成功,该Servlet已经进入!");
else
out.println("身份验证失败!");
}
}
三、处理Cookie(1) 什么是Cookie
Cookie是在浏览器访问Web服务器上某个资源时,由Web服务器在HTTP消息响应头中附带的一组传送给浏览器的数据。
Web服务器通过HTTP响应消息头的Set-Cookie字段将多个Cookie发送到浏览器,每个Cookie使用Set-Cookie字段来设置。当浏览器发现HTTP响应消息头中有Set-Cookie时,就会根据Set-Cookie字段的值来决定如何处理这些Cookie,或只在当前浏览器窗口中有效。
(2) Cookie类
public Cookie (String name, String value)
name表示Cookie的值(不能包含空格、逗号、分号,并且不能以$开头), value表示Cookie的值。
・ getName:返回Cookie的名称
・ setValue和getValue:设置和返回Cookie的值
public void setValue(String newValue
public String getValue()
・ setMaxAge 和 getMaxAge:设置和返回Cookie在客户机的有效时间(秒为单位)。如果有效时间为0,则表示当Cookie信息发送到客户端浏览时立即被删除;如果设置为负数,则表示浏览器并不会把这个Cookie保存在硬盘上
・ setPath和getPath:设置和返回当前Cookie的有效Web路径。如果在创建某个Cookie时未设置它的path属性,那么该Cookie只对当前访问的Servlet所在的Web路径及其子路径有效。
・ setDomain和getDomain:设置和返回当前Cookie的有效域
・ setComment和getComment:设置和返回当前Cookie的注释部分
・ setVersion和getVersion:设置和返回当前Cookie的协议版本
・ setSevure和getSecure:设置和返回当前Cookie是否只能使用安全的协议传送
package chapter5;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class WriteCookie extends HttpServlet
{
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
// 临时Cookie
Cookie tempCookie = new Cookie("temp", "temporary cookie"); //
tempCookie.setMaxAge(-1); // 设为临时Cookie,-1是MaxAge的默认值
response.addCookie(tempCookie);
// 这个cookie不起作用
Cookie cookie = new Cookie("cookie", "deleted");
cookie.setMaxAge(0); // 超时设为0,浏览器接收以Cookie后立即被删除
response.addCookie(cookie);
// 持久化Cookie
String chinese = java.net.URLEncoder.encode("将Cookie保存到硬盘上", "UTF-8");
Cookie persistentCookie = new Cookie("pCookie", chinese);
persistentCookie.setMaxAge(60 * 60 * 24); // 有效期为1天
// 设置有效路径,设为“/”表示这个Cookie在整个站点都是有效的
persistentCookie.setPath("/");
response.addCookie(persistentCookie);
}
}
package chapter5;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ReadCookie extends HttpServlet
// 通过一个Cookie名获得Cookie对象,未找到指定名的Cookie对象,返回null
private Cookie getCookieValue(Cookie[] cookies, String name)
if (cookies != null)
for (Cookie c : cookies)
if (c.getName().equals(name))
return c;
}
return null;
}
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
response.setContentType("text/html; charset=UTF-8");
PrintWriter out = response.getWriter();
// 获得临时Cookie ,getCookies方法获得一个保存了请求消息头中所有Cookie的数组
Cookie tempCookie = getCookieValue(request.getCookies(), "temp");
if (tempCookie != null)
out.println("临时Cookie值:" + tempCookie.getValue() + "<br/>");
else
out.println("临时Cookie值:null</br>");
// 这个Cookie永远不可能获得,因为它的MaxAge为0
Cookie cookie = getCookieValue(request.getCookies(), "cookie");
if (cookie != null)
out.println("cookie:" + cookie.getValue() + "<br/>");
else
out.println("cookie:null</br>");
// 获得永久Cookie
Cookie persistentCookie = getCookieValue(request.getCookies(), "pCookie");
if (persistentCookie != null)
out.println("persistentCookie:" + java.net.URLDecoder.decode(persistentCookie.getValue(), "UTF-8"));
else
out.println("persistentCookie:null!");
}
四、处理Session
Session是服务器端的对象,用于保存当前会话中用户的数据。浏览器可以通过Cookie机制来跟踪Session对象,如果浏览器将Cookie功能关闭,或不支持Cookie,则可以采用重写URL来跟踪Session对象。
(1) HttpSession接口中的方法
・ getId:用于返回当前HeepSession对象的SessionID值。
String getId()
・ getCreationTime和getLastAccessedTime:用于返回当前的HttpSession对象的创建时间和上一次被访问的时间。
long getCreationTime()
getLastAccessedTime
・ setMaxInactiveInterval和getMaxInactiveInterval:设置和返回当前HttpSession对象可空闲的最长时间(s),设置为负数,则永远不过期。
void setMaxInactiveInterval(int interval)
int getMaxInactiveInterval()
・ isNew:判断当前HttpSession对象是否是新创建的
boolean isNew()
・ invalidate:用欲求昂至当前的HttpSession对象失效
void invalidate()
・ getServletContext返回当前HttpSession对象所属的Web应用程序的ServletContext对象,和GenericServlet接口的getServletContext方法返回同一个ServletContext对象。
ServletContext getServletContext()
・ setAttribute:用于将key-value对保持在Session域中
void setAttribute(String name, Object value)
・ getAttribute:返回Session指定key的value值
Object getAttribute(String name)
・ remoteAttribute:根据key删除Session域中某一个key-value对。
void removeValue(String name)
・ getAttributeNames:返回一个包含当前Session域中所有key值的Enumeration对象。
Enumeration getAttributeNames()
(2) HttpRequestSession接口中的Session方法
・ getSession:根据当前请求返回HttpSession对象
public HttpSession getSession();
public HttpSession getSession(boolean create);
・ isRequestedSessionIdValid:HttpSession对象是否超过了有效时间
boolean isRequestedSessionIdValid()
・ isRequestedSessionIdFromCookie:判断SessionID是否通过HTTP请求消息中的Cookie头字段传递过来的。
boolean isRequestedSessionIdFromCookie()
・ isRequestedSessionIdFromURL:判断SessionID是否通过HTTP请求消息中的URL请求参数传递过来的。
boolean isRequestedSessionIdFromURL()
(3) 通过重写URL跟踪Session
package chapter5;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class RewriteURL extends HttpServlet
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
HttpSession session = request.getSession();
response.setContentType("text/html; charset=UTF-8");
RequestDispatcher rd = request.getRequestDispatcher("HeaderInfo");
rd.include(request, response);
PrintWriter out = response.getWriter();
out.println("<br/><br/><a href='" + response.encodeURL("RewriteURL?param=value") + "'>RewriteURL</a>");
}