JSP网络编程-请求和响应-HttpServletRequest-HttpServletResponse-学习笔记
2012-05-31 10:56
986 查看
1 Servlet请求与HttpServletRequest对象
1.1 生命周期
仅在HttpServlet的service方法内有效,如果在某次请求的处理过程中保存了HttpServletRequest的引用,在另一次请求的处理过程中不能使用。因为这个引用所指向的HttpServletRequest对象已经被填入了另一次请求的数据。
1.2 获取请求参数
ServletRequest | 方法说明 |
---|---|
+String getParameter(String name) | 不存在则返回null;存在多个返回任一个 |
+String[] getParameterValues(String name) | 返回名为name的所有参数值;不存在返回null,不是空数组 |
+Enumeration getParameterNames() | 获取所有的参数名,元素类型为String,不存在则返回空对象,不是null |
+Map getParameterMap() | 返回 key(String)和value(String[]) |
1.3 实例
.1.3.1 建立应用程序目录结构
E:\Tomcat 5.5\webapps\ E:\Tomcat 5.5\webapps\northhujia E:\Tomcat 5.5\webapps\northhujia\src E:\Tomcat 5.5\webapps\northhujia\WEB-INF E:\Tomcat 5.5\webapps\northhujia\WEB-INF\classes
.1.3.2 新建请求页面
<!-- 文件名 E:\Tomcat 5.5\webapps\northhujia\form.html --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>选择</title> </head> <body> <form method="post" action="./who_you_like_most"><center> <p>你最喜欢谁?按Ctrl键可选多个<p/> <select size="6" name="heroes" multiple> <!-- multiple指定可多选 --> <option value="李牧">李牧</option> <option value="韩信">韩信</option> <option value="卫青">卫青</option> <option value="霍去病">霍去病</option> <option value="马援">马援</option> <option value="王守仁">王守仁</option> </select> <br/> <br/> 为什么:<input type="text" name="why" /> <br/> <br/> <input type="submit"> <br/> <br/> <input type="reset"> </center></form> </body> </html>
.1.3.3 新建Servlet类
/** E:\Tomcat 5.5\webapps\northhujia\src\WhoYouLikeMost.java */ package com.jc.hujd; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class WhoYouLikeMost extends HttpServlet{ public void doPost(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{ /** 告诉req对象以GB2312编码读取参数值 */ req.setCharacterEncoding("GB2312"); String[] heroes = req.getParameterValues("heroes"); String why = req.getParameter("why"); resp.setContentType("text/html;charset=GB2312"); PrintWriter pw=resp.getWriter(); pw.println("<center>"); pw.println("<br/>你最喜欢的有:"); /** 如果一个都没选,则返回null,所以必须进行检查 */ if(heroes != null){ for(int k=0;k<heroes.length;k++) { pw.println("<br/>"+heroes[k]); } }else{ pw.println("<br/>怎么搞的,你一个都不喜欢?!"); } pw.println("<br/>原因是:"); /** 文本框不填时表单会提交空字符串,所以不会有null问题 */ pw.println(why); pw.println("</center>"); } }
.1.3.4 编译Servlet类
Microsoft Windows XP [版本 5.1.2600] (C) 版权所有 1985-2001 Microsoft Corp. E:\Tomcat 5.5\webapps\northhujia\src>javac WhoYouLikeMost.java -cp ..\..\..\common\lib\servlet-api.jar -d ..\WEB-INF\classes E:\Tomcat 5.5\webapps\northhujia\src>
.1.3.5 配置 web.xml
<!-- E:\Tomcat 5.5\webapps\northhujia\WEB-INF\web.xml --> <?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <servlet> <servlet-name> chooseheroes </servlet-name> <servlet-class> com.jc.hujd.WhoYouLikeMost </servlet-class> </servlet> <servlet-mapping> <servlet-name>chooseheroes</servlet-name> <url-pattern>/who_you_like_most</url-pattern> </servlet-mapping> </web-app>
.1.3.6 运行
现在的目录结构是:E:\Tomcat 5.5\webapps\northhujiaE:\Tomcat 5.5\webapps\northhujia\src\WhoYouLikeMost.java
E:\Tomcat 5.5\webapps\northhujia\form.html
E:\Tomcat 5.5\webapps\northhujia\WEB-INF\web.xml
E:\Tomcat 5.5\webapps\northhujia\WEB-INF\classes\com\jc\hujd\WhoYouLikeMost.class启动Tomcat,在浏览器中打开:http://localhost:8080/northhujia/form.html
1.4 读取请求消息头中的键值对
常见键值对如:Referer: URL用户当前页面是从URL跳转过来的,通过检查URL的值可实现简单防盗链功能Accept-Encoding: gzip常用获取消息头的方法:ServletRequest | 方法说明 |
---|---|
+ int getContentLength() | POST方式时的消息头,指示消息体的长度 |
+ String getContentType() | POST数据的类型和编码,很多浏览器不发送这个消息头 |
+ String getProtocol() | HTTP 1.0 或 HTTP 1.1 |
派生出---> | |
HttpServletRequest | 方法说明 |
+ String getHeader(String name) | 不存在则返回null,存在多个返回其中一个 |
+ Enumeration getHeaders(String name) | 返回所有值,不存在则返回空对象,不是 null |
+ Enumeration getHeaderNames() | 返回所有消息头名,不会返回null |
+ long getDateHeader(String name) | 返回名为name的日期格式的消息头的值,不存在返回-1,不是日期格式,抛出异常 |
+ String getMethod() | POST 或 GET |
+ String getRequestURI() | 消息头第一行的URI,不含参数 |
+ String getQueryString() | 获取附加在URL后的参数字符串 |
1.5 参考资料:HTTP请求和响应的格式
HTTP请求包括三部分:请求行(Request Line),头部(Headers)和数据体(Body)。其中,请求行由请求方法(method),请求网址Request-URI和协议 (Protocol)构成,而请求头包括多个属性,数据体则可以被认为是附加在请求之后的文本或二进制文件。下面这个例子显示了一个HTTP请求的Header内容,这些数据是真正以网络HTTP协议从IE浏览器传递到Apache服务器上的。GET /qingdao.html HTTP/1.1 Accept:text/html Accept-Language:zh-cn Accept-Encoding:gzip,deflate User-Agent:Mozilla/4.0(compatible;MSIE 5.01;Windows NT 5.0;DigExt) Host: www.6book.net Referer: http://www.6book.net/beijing.html Connection:Keep-Alive这段程序使用了6个Header,还有一些Header没有出现。我们参考这个例子具体解释HTTP请求格式。HTTP请求行:请求行格式为Method Request-URI Protocol。在上面这个例子里,„GET / HTTP/1.1“是请求行。) 2) Accept:指浏览器或其他客户可以接爱的MIME文件格式。可以根据它判断并返回适当的文件格式。
Accept-Charset:指出浏览器可以接受的字符编码。英文浏览器的默认值是ISO-8859–1.
Accept-Language:指出浏览器可以接受的语言种类,如en或en-us,指英语。
Accept-Encoding:指出浏览器可以接受的编码方式。编码方式不同于文件格式,它是为了压缩文件并加速文件传递速度。浏览器在接收到Web响应之后先解码,然后再检查文件格式。
Authorization:当使用密码机制时用来标识浏览器。
Cache-Control:设置关于请求被代理服务器存储的相关选项。一般用不到。
Connection:用来告诉服务器是否可以维持固定的HTTP连接。HTTP/1) 1使用Keep-Alive为默认值,这样,当浏览器需要多个文件时(比如一个HTML文件和相关的图形文件),不需要每次都建立连接。
Content-Type:用来表名request的内容类型。可以用HttpServletRequest的getContentType()方法取得。
Cookie:浏览器用这个属性向服务器发送Cookie。Cookie是在浏览器中寄存的小型数据体,它可以记载和服务器相关的用户信息,也可以用来实现会话功能。
Expect:表时客户预期的响应状态。
From:给出客户端HTTP请求负责人的email地址。
Host:对应网址URL中的Web名称和端口号。
If-Match:供PUT方法使用。
If-Modified-Since:客户使用这个属性表明它只需要在指定日期之后更改过的网页。因为浏览器可以使用其存储的文件而不必从服务器请求,这样节省了Web资源。由于Servlet是动态生成的网页,一般不需要使用这个属性。
If-None-Match:和If-Match相反的操作,供PUT方法使用。
If-Unmodified-Since:和If-Match-Since相反。
Pragma:这个属性只有一种值,即Pragma:no-cache,表明如果servlet充当代理服务器,即使其有已经存储的网页,也要将请求传递给目的服务器。
Proxy-Authorization:代理服务器使用这个属性,一般用不到。
Range:如果客户有部分网页,这个属性可以请求剩余部分。
Referer:表明产生请求的网页URL。比如从网页/beijing.html中点击一个链接到网页/qingdao.html,在向服务器发送的GET /beijing.html中的请求中,Referer是http://www.6book.net/qingdao.html 。这个属性可以用来跟踪Web请求是从什么网站来的。
Upgrage:客户通过这个属性设定可以使用与HTTP/1.1不同的协议。
User-Agent:是客户浏览器名称。
Via:用来记录Web请求经过的代理服务器或Web通道。
Warning:用来由客户声明传递或存储(cache)错误。文章出处:DIY部落(http://www.diybl.com/…/131762.html)例2 POST请求:
POST / HTTP1.1 Host:www.wrox.com User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022) Content-Type:application/x-www-form-urlencoded Content-Length:40 Connection: Keep-Alive name=Professional%20Ajax&publisher=Wiley说明:Content-Type 说明了请求主体的内容是如何编码的
浏览器始终以application/x-www-form-urlencoded的格式编码来传送数据,这是针对简单URL编码的MIME类型.
Content-Length 说明了请求主体的字节数.
最后请求主体.名称-值对的形式
1.6 实例:按原格式打印出上一个例子中HTTP请求信息(POST)
.1.6.1 Servlet类
/** E:\Tomcat 5.5\webapps\northhujia\src\EchoHttpRequest.java */ package com.jc.hujd; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.Enumeration; public class EchoHttpRequest extends HttpServlet{ public void doPost(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{ /** 告诉req对象以GB2312编码读取参数值 */ req.setCharacterEncoding("GB2312"); String str=req.getMethod()+" "+req.getRequestURI()+" "+req.getProtocol()+"\n"; String hn=""; for(Enumeration e=req.getHeaderNames();e.hasMoreElements();){ hn = e.nextElement().toString(); str += hn + ": "+req.getHeader(hn)+"\n"; } str += "\n"; byte b[] = new byte[1024]; int len; try{ len=req.getInputStream().readLine(b,0,1024); str += new String(b,0,len,"GB2312"); }catch(Exception e){ str += e.getMessage(); } /**数组拷贝 System.arrayCopy(Object src, int srcPos, Object dest, int destPos, int length); src 源数组 srcPos 从第几位开始拷贝 dest 目标数组 destPos 目标数组放置的起始位置 length 表示要拷贝的长度 */ /** 当我们从文件中读数据时,最好使用InputStream方式, 然后采用String(byte[] bytes, String encoding) 指明文件的编码方式。 String(byte[] bytes, int offset, int length, String charsetName) */ resp.setContentType("text/html;charset=GB2312"); PrintWriter pw=resp.getWriter(); pw.println("<html><body><TextArea cols=250 rows=20 >"); pw.println(str); pw.println("\n</TextArea></body></html>"); } }
.1.6.2 修改form.html为form_post.html
<form method="post" action="./echo_http_request"><center>
.1.6.3 修改web.xml
<!-- E:\Tomcat 5.5\webapps\northhujia\WEB-INF\web.xml --> <?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> <servlet> <servlet-name> chooseheroes </servlet-name> <servlet-class> com.jc.hujd.WhoYouLikeMost </servlet-class> </servlet> <servlet-mapping> <servlet-name>chooseheroes</servlet-name> <url-pattern>/who_you_like_most</url-pattern> </servlet-mapping> <servlet> <servlet-name> echohttprequest </servlet-name> <servlet-class> com.jc.hujd.EchoHttpRequest </servlet-class> </servlet> <servlet-mapping> <servlet-name>echohttprequest</servlet-name> <url-pattern>/echo_http_request</url-pattern> </servlet-mapping> </web-app>
.1.6.4 运行
重新启动Tomcat,访问http://localhost:8080/northhujia/form_post.html返回结果是POST /northhujia/echo_http_request HTTP/1.1 accept: application/x-shockwave-flash, image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/x-silverlight, 星号/星号 referer: http://localhost:8080/northhujia/form_post.html accept-language: zh-cn content-type: application/x-www-form-urlencoded accept-encoding: gzip, deflate user-agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1; GreenBrowser) host: localhost:8080 content-length: 25 connection: Keep-Alive cache-control: no-cache heroes=%C2%ED%D4%AE&why=3注意:content-length: 25 是说最后的POST的内容(最后一行)是25个字符。
2 Servlet响应与HttpServletResponse
2.1 参考资料:HTTP响应的格式
<status-line> <headers> <blank line> [<response-body>]例:
HTTP/1.1 200 OK Date: Fri, 22 May 2009 06:07:21 GMT Content-Type: text/html; charset=UTF-8 <html> <head></head> <body> <!--body goes here--> </body> </html>说明:HTTP状态码200,找到资源,并且一切正常.
Date:生成响应的日期和时间.
Content-Type:指定了MIME类型的HTML(text/html),编码类型是UTF-8
第一行 = 协议版本 + 状态码 + 状态描述
状态码1--:允许客户端发送文件
2--:请求成功
3--:资源地址已改变
4--:请求错误,不能处理请求
5--:服务器错误:如 ServletException会导致 500 Internal Server Error
2.2 HttpServletResponse对象
ServletResponse | 方法说明 |
---|---|
+ void setBufferSize(int size) | 设置消息体缓存大小 |
+ void setContentType(String type) | 设置消息头Content-Type |
+ void setContentLength(int len) | 设置消息头Content-Length |
+ ServletOutputStream getOutputStream() | 二进制流 |
+ PrintWriter getWriter() | 文本输出流 |
派生出---> | |
HttpServletResponse | 方法说明 |
+ void setStatus(int sc) | … |
+ void setHeader(String n,String v) | … |
+ void addHeader(String n,String v) | … |
+ void setIntHeader(String n,int v) | … |
+ void setDateHeader(String n,long v) | … |
+ void addDateHeader(String n,long v) | … |
2.3 使用 HttpServletResponse对象
... resp.setStatus(resp.SC_OK); resp.setHeader(name,value); ... resp.setContentType("text/html;charset=GB2312"); resp.setBufferSize(size); PrintWriter pw=resp.getWriter(); ...
2.4 转化HTML文件的工具类
import java.io.*; public class NorthhujiaUtil{ public static void main(String[] args){ System.out.println(NorthhujiaUtil.escapeHtml("<html>\"=")); } public static String escapeHtml(String str){ if( str == null ){ return null; } int len = str.length(); StringBuffer sb = new StringBuffer(len); for(int i=0; i<len; i++){ char c = str.charAt(i); switch( c ){ case ' ': sb.append(" "); break; case '<': sb.append("<"); break; case '>': sb.append(">"); break; case '&': sb.append("&"); break; case '"': sb.append("quot;"); break; default: sb.append(c); }//end switch }//end for return sb.toString(); } }
2.5 输出二进制文件
/* 选自 傅进勇《JSP网络编程》 */ package com.cxpub.chpt4; import java.io.*; import java.util.Random; import java.awt.Font; import java.awt.Graphics; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; import javax.servlet.*; import javax.servlet.http.*; public class ImageExample extends HttpServlet{ private Random rand; private Font font; private int width; private int height; private void outputImage(OutputStream out) throws IOException{ String str = Integer.toString(1000+rand.nextInt(9000)); BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); for(int i=0; i<20; i++){ int x = rand.nextInt(width); int y = rand.nextInt(height); bi.setRGB(x, y, 0xFFFFFF); } Graphics g = bi.getGraphics(); g.setFont(font); g.drawString(str, 0, height-1); g.dispose(); ImageIO.write(bi, "jpg", out); } public void init(){ rand = new Random(System.currentTimeMillis()); font = new Font("Courier New", Font.ITALIC, 20); width = 50; height = 20; } public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ String text = req.getParameter("text"); resp.setContentType("image/jpeg"); outputImage(resp.getOutputStream()); } }
2.6 设置Response Header
package com.cxpub.chpt4; import java.util.Date; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class RefreshExample extends HttpServlet{ public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ resp.setIntHeader("Refresh", 5); resp.setContentType("text/html; charset=GBK"); PrintWriter pw = resp.getWriter(); pw.println("<html><body>"); pw.println("当前系统时间是:<br>"); pw.println(new Date()); pw.println("</body></html>"); } };
相关文章推荐
- HttpServletResponse响应头与HttpServletRequest请求头及编码问题
- HttpServletRequest&&HttpServletResponse参数的接收和响应
- Servlet学习笔记(三):HTTP请求与响应
- Web 的请求HttpServletrequest和响应HttpServletResponse
- Jsp/Servlet读书笔记(二) -- HttpServletRequest和HttpServletResponse
- The code of method _jspService(HttpServletRequest, HttpServletResponse) is exceeding the 65535 bytes limit
- JavaWeb学习笔记--HttpServletRequest、HttpServletResponse对象常用方法
- The code of method _jspService(HttpServletRequest, HttpServletResponse) is exceeding the 65535 bytes
- (9)http请求与响应(两部分:HttpServletRequest,HttpServletResponse,java文件读入写出需掌握)
- 不二极端编程之JavaWeb详解(HttpServletRequest,HttpServletResponse)
- The code of method _jspService(HttpServletRequest, HttpServletResponse) is exceeding the 65535 bytes
- The code of method _jspService(HttpServletRequest, HttpServletResponse) is exceeding the 65535 bytes
- 从零开始学习Java Web(四):初识HttpServletRequest和HttpServletResponse
- Filter处理HttpServletRequest & HttpServletResponse 笔记
- struts2学习笔记---获得HttpServletResponse或HttpServletRequest对象的几种方法
- “The code of method _jspService(HttpServletRequest, HttpServletResponse) is exceeding the 65535 bytes limit” 的我之解決辦法
- 学习笔记2:YII请求组件request和响应组件response
- Tomcat 解决The code of method _jspService(HttpServletRequest, HttpServletResponse) is exceeding the 65535 bytes limit
- 南哥带你学 Java 之 JavaEE 设置全局配置、请求转发、请求重定向、HttpServletResponse 和 HttpServletRequest
- Fix The code of method _jspService(HttpServletRequest, HttpServletResponse) is exceeding the 65535 b