完整代码请参考:https://github.com/devway9/java-exercise/tree/master/servlet-jsp
目录
- 1 HTTP响应的格式
- 2 如何设置状态代码
- 3 HTTP响应报文头
- 4 Servlet状态的持续和页面的自动重载
- 5 使用Servlet生成Excel
正文
1 HTTP响应的格式
1) Web服务器响应的格式由以下内容构成:
① 状态行:由HTTP版本(如HTTP/1.1)+状态码+状态码对应的信息构成。
② 响应报文头。
③ 空行。
④ 相应的文档。
2 如何设置状态代码
1) 系统自动设置的状态码是200。如果需要修改,可以使用HttpServletResponse的以下方法修改:
① setStatus:设置任意状态码,必须在PrintWriter使用前调用。
② sendRedirect:生成302响应以及Location报文头,重定向到指定的URL。
③ sendError:设置一个错误状态码(一般为404),以及一段描述信息返回给客户端。
④ 状态码一般使用HttpServletResponse的SC_**常量,而不直接使用数字。
2) HTTP1.1的状态码:
① 100-199:信息性的标示用户应该采取的其他动作。
② 200-299:请求成功。
③ 300-399:重定向。
④ 400-499:客户引发的错误。
⑤ 500-599:服务器引发的错误。
3) 状态码详解:
① 100(Contiune,继续):如果客户端发送100的请求,表示在询问是否在随后的请求中可以发送附件文档,服务器可以返回100,表示继续,或者返回417告诉浏览器不接受。
② 200(OK,一切正常)。
③ 202(Accepted,已接受):请求已接受,但处理未完成。
④ 204(No Content,没有新文档):浏览器继续显示之前的文档。
⑤ 205(Reset Content,重置内容):表示没有新的文档,但浏览器需要重置当前文档。
⑥ 301(Moved Permanently,被永久移动):表示文件已移向别处,新URL在Loaction响应报文头中给出。
⑦ 302(Found,找到):类似301,大多数浏览器等同对待301和302,。使用sendRedirect和refresh不同,sendRedirect不显示中间输出,可以用于以下场景:
a) 判断用户需要重定向的地址。
b) 跟踪用户的行为。
c) 执行边界效应,设置cookie等。
d) response.sendRedirect("http://www.baidu.com")和下面的代码等价:
response.setStatus(302);
response.setHeader("Location","http://www.baidu.com");
⑧ 303(See Other,检查其他文档):类似301和302
⑨ 304(Not Modified,未发生更改):表示缓存的版本是最新的。一般不直接设置该状态,而是用getLastModified方法。
⑩ 307(Temporanry Redirect,临时重定向):如果接收到303响应,则继续进行GET和POST的重定向,如果接收到307响应,则对GET请求继续重定向,POST请求则不重定向。
11 400(Bad request,错误请求):表明客户请求中含有语法错误。
12 401(Unauthorize,未授权)。
13 403(Forbidden,资源不可用):服务器拒绝提供相关资源。
14 404(Not Found,未找到):客户端给定的地址找不到资源。
15 405(Method Not Allowed,方法不允许):资源不允许使用该请求方法(GET、POST、HEAD、PUT、DELETE等)。
16 415(Unsupported Media type,不支持的媒体类型):服务器不知道如何处理附加文件的类型。
17 417(Expectation Failed,期望不满足):参考状态100。
18 500(Internal Server Error,服务器内部错误)。
19 501(Not Implemented,未实现):表示服务器不支持客户端发送的命令,比如PUT。
20 503(Service Unavailable,服务不可用):由于服务器不能做出相应,比如线程池或数据库连接池被占用。
21 505(HTTP Version Not Supported,不支持的HTTP版本)。
package com.devway.servlet.response; import com.devway.servlet.common.BaseServlet; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * TestResponseCode class * * @author devway * @date 2017-12-06 */ public class TestResponseCode extends BaseServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doGet(req, resp); //resp.setStatus(204); //resp.setStatus(307); // resp.setHeader("Location","http://www.baidu.com"); //505 //System.out.println(1/0); out.println("测试setStatus:"+resp.getStatus()); //重定向 //resp.sendRedirect("http://www.baidu.com"); //resp.sendError(405,"页面错误"); } }
3 HTTP响应报文头
1) 使用HttpServletResponse的方法设置响应报文头。
2) setHeader/addHeader:将指定名称的响应报文头设定为指定的值,set和add方法的区别在于,如果已存在同名的报文头名字,使用set会替换报文头的值,而使用add则是新增一个同名的报文头。
3) setDateHeader/addDateHeader:省去将毫米数转为Date的步骤。
4) setIntHeader/addIntHeader:省去将int转为String的步骤。
5) setContentType:设置Content-Type报文头。
6) setContentLength:设置Content-Length报文头,在浏览器支持持续性HTTP连接时,这个报文头很有用。
7) addCookie:插入cookie,没有setCookie方法。
8) sendRedirect:将状态代码设为302,同时设置Location报文头。
9) 报文头详解:
① Allow:指定服务器支持的请求方法(GET、POST等),405响应需要用到这个报文头。
② Cache-Control:告诉客户端,什么环境可以安全的缓存文档,可以取以下值
a) public:文档可以缓存。
b) private:适用单个用户,只能存储在私有缓存中。
c) no-cache:不能缓存。
d) no-store:不能缓存,且不能存储在磁盘的临时目录中。
e) must-revalidate:每次使用文档时,客户端必须联系原来的服务器重新验证文档。
f) proxy-revalidate:只适用于共享缓存,其他和must-revalidate相同。
g) max-age=xxx:xxx秒之后,将该文档认为失效,可替代Expires,如果两个都存在,则max-age优先。
h) s-mas-age=xxx:共享缓存在xx秒之后将文档认为失效。
③ Connection:如果为close,则指示浏览器不要使用持续性HTTP连接,可以省略Content-Length报文头,如果未指定,则默认为持续性连接。
④ Content-Disposition:控制用户请求所得的内容存为一个文件的时候提供一个默认的文件名,文件直接在浏览器上显示或者在访问时弹出文件下载对话框。
⑤ Content-Encodig:页面传输中使用的编码方式。
⑥ Content-Language:文档使用的语言。
⑦ Content-Length:响应的字节数。
⑧ Content-Type:设置响应文档的MIME类型以及字符编码,MIME一般指定为text/htm,如果字符编码没指定,则默认为ISO-8859_1。也可使用setContentType方法。常见的MIME类型:
a) application/msword:Microsoft Word 文档。
b) application/pdf: .pdf文件。
c) application/vnd.ms-excel:excel。
d) application/x-java-archive:JAR文件。
e) application/zip:zip文件。
f) image/gif:GIF图像。
g) text/css:HTML层叠样式表。
h) text/html:HTML文档。
i) text/plain:纯文本。
j) text/xml:xml文件。
⑨ Expires:过期时间。
⑩ Last-Modified:文件的最后修改时间,时间单位为毫秒。
11 Location:重定向地址,状态代码在300-399,都应该包括这个报文头。
12 Refresh:表明浏览器间隔x秒后,自动刷新页面,时间单位为秒。response.setIntHeader("Refresh",30);如果要跳转到新页面,则设置response.setHeader("Refresh","5;URL="http://www.baidu.com");一般将这部分放入HTML页面的HEAD中,间接的设置这个报文头,而不是在服务器显示设置。<META HTTP-EQUIV="Refresh" Content="5;URL="http://www.baidu.com">
13 Retry-After:和状态码503结合使用,告诉客户端多久后可以重复请求。
14 WWW-Authenticate:和401结果使用,告诉浏览器应该提供那种类型的验证。
package com.devway.servlet.response; import com.devway.servlet.common.BaseServlet; import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; /** * TestSetHeader class * * @author devway * @date 2017-12-07 */ public class TestSetHeader extends BaseServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doGet(req, resp); //set***方法,如果有同名的报文头则替换,而add***方法,则即使报文头已存在,也添加一个同名的新的报文头 resp.setHeader("headerName ","headerValue"); resp.setDateHeader("headerDate",System.currentTimeMillis()); resp.setIntHeader("headerInt",1001); resp.addHeader("headerName","headerValue1"); resp.addDateHeader("headerDate",System.currentTimeMillis()+1000000); resp.addIntHeader("headerInt",1002); resp.setContentType("text/html;charset=\"utf-8\""); //resp.setContentLength(200); resp.addCookie(new Cookie("c","c1")); //指定服务器支持的请求方法(GET、POST等),405响应需要用到这个报文头 resp.setHeader("allow","GET"); //告诉客户端,什么环境可以安全的缓存文档 //resp.setHeader("Cache-Control","no-cache"); resp.setHeader("Cache-Control","public"); //resp.setContentType("application/vnd.ms-excel;charset=utf-8"); //resp.setHeader("Content-Disposition","attachment;filename=1.xls"); //设置内容的过期时间 resp.setDateHeader("Expires",10*1000); println("test"); //resp.setHeader("Refresh","2"); //resp.setHeader("refresh","3;URL=\"http://www.baidu.com\""); //resp.setIntHeader("Refresh",2); } }
4 Servlet状态的持续和页面的自动重载
1) 对于处理耗时较长的任务,需要以下功能:
① 一种跨请求存储数据的方式:对于不属于客户的数据,存储在servlet的字段中;对于用户专属的数据,存储在HttpSession对象中;于其他servlet和jsp需要用到的数据,存储在ServletContext中。
② 一种在请求发送给客户之后,继续运算的方式:启动一个线程。
③ 一种在计算结果继续后,使浏览器得到他的方式:使用Refresh响应报文头。
5 使用Servlet生成Excel
1) 如何创建Excel
① Excel支持多种不同格式的输出:制表符分隔的数据、HTML表格、本地二进制格式。
② 构建Excel,使用response.setContentType("application/vnd.ms-excel");
2) 使用制表符生成Excel
package com.devway.servlet.response; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; /** * TestExcel class * * @author devway * @date 2017-12-07 */ public class TestExcel extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("application/vnd.ms-excel"); PrintWriter out = resp.getWriter(); out.println("\tQ1\tQ2\tQ3\tQ4\tTotal"); out.println("Apples\t1\t2\t3\t4\t=SUM(B2:E2)"); out.println("Oranges\t2\t2\t3\t4\t=SUM(B3:E4)"); } }