首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

JSP网络编程-请求和响应-HttpServletRequest-HttpServletResponse-学习札记

2012-09-10 
JSP网络编程-请求和响应-HttpServletRequest-HttpServletResponse-学习笔记1 Servlet请求与HttpServletReq

JSP网络编程-请求和响应-HttpServletRequest-HttpServletResponse-学习笔记
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\northhujiaE:\Tomcat 5.5\webapps\northhujia\srcE:\Tomcat 5.5\webapps\northhujia\WEB-INFE:\Tomcat 5.5\webapps\northhujia\WEB-INF\classes
.1.3.2 新建请求页面
.1.3.3 新建Servlet类
.1.3.6 运行

现在的目录结构是:

E:\Tomcat 5.5\webapps\northhujiaE:\Tomcat 5.5\webapps\northhujia\src\WhoYouLikeMost.javaE:\Tomcat 5.5\webapps\northhujia\form.htmlE:\Tomcat 5.5\webapps\northhujia\WEB-INF\web.xmlE:\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.1Accept:text/htmlAccept-Language:zh-cnAccept-Encoding:gzip,deflateUser-Agent:Mozilla/4.0(compatible;MSIE 5.01;Windows NT 5.0;DigExt)Host: www.6book.netReferer: http://www.6book.net/beijing.htmlConnection: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.1Host:www.wrox.comUser-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-urlencodedContent-Length:40Connection: Keep-Alivename=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
.1.6.4 运行

重新启动Tomcat,访问http://localhost:8080/northhujia/form_post.html

返回结果是

POST /northhujia/echo_http_request HTTP/1.1accept: 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.htmlaccept-language: zh-cncontent-type: application/x-www-form-urlencodedaccept-encoding: gzip, deflateuser-agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1; GreenBrowser)host: localhost:8080content-length: 25connection: Keep-Alivecache-control: no-cacheheroes=%C2%ED%D4%AE&why=3

注意:content-length: 25 是说最后的POST的内容(最后一行)是25个字符。

2 Servlet响应与HttpServletResponse2.1 参考资料:HTTP响应的格式
<status-line><headers><blank line>[<response-body>]

例:

HTTP/1.1 200 OKDate: Fri, 22 May 2009 06:07:21 GMTContent-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 Error2.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("&nbsp;");                      break;                  case '<':                      sb.append("&lt;");                      break;                  case '>':                      sb.append("&gt;");                      break;                  case '&':                      sb.append("&amp;");                      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>");  }};
3 各种编码参考规范3.1 ASCII

一个字节,最高位为0,最大为 B01111111 = D127

3.2 ISO-8859–1/Latin-1

一个字节,最高位为0时与ASCII兼容,最高位为1时定义其它字符。

3.3 GBK编码(GuoBiaoKuoZhan)

是对简体编码gb2312的扩展,含简繁体、日、韩文,兼容ASCII

解析方法:

如果某字节是0,则此字节是一个ASCII字符如果某字节是1,则此字节与后一字节共同组成一个双字节字符。

由于双字节字符的第二个字节最高位可以是0,也可以是1,故解析时必须从文件的第一个字节开始。

3.4 Unicode

一系列编码的统称,分为UCS和UTF两类

.3.4.1 UCS (Universal Character Set)

每个字符的字节数是固定的

UCS-2

UCS-2用两个字节表示一个字符,与ISO-8859–1兼容。在一个ISO-8859–1字符前加一个值为0的字节,即是相应的UCS-2字符。

具体的规范有三个:

UCS-2LE: little endian 先存储/传输低位字节UCS-2BE: big endian 先存储/传输高位字节UCS-2: 两种方式的结合。以U+FEFF加在整个文本前,由接受者判断是LE还是BE。

UCS-2最多表示65536个字符

UCS-4

每字符四个字节,很少使用

.3.4.2 UTF (Unicode/UCS Transformation Format)

-UTF-16

UCS-2的扩展 Java程序使用此编码

UTF-8

每字符1–4个字节不等。

解析方法:

如果某字节高位是0,则此字节是单字节字符,及一个ASCII码0xxxxxxx如果某字节最高三位是110,则此字节与后一个字节共同组成一个双字节字符,表示其它字母字符110xxxxxxxxxxxxx如果某字节最高三位是1110,则此字节与后两个字节共同组成一个三字节字符,表示中日韩文等1110xxxxxxxxxxxxxxxxxxxx

中文用UTF-8每个汉字用三个字节表示

热点排行