精华帖 (2) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-04-10
最后修改:2010-04-10
译者 jarfield博客 http://jarfield.iteye.com获取参数 除非servlet
调用javax.servlet.http.HttpServletRequest
的getParameter
、getParameterMap
、getParameterNames
和getParameterValues
方
法来读取请求参数,否则,我们都不需要解析query string
或HTTP
请求体(request
body
)。 因此,HttpRequest
类实现的这四个方法,都
是先调用parseParameter
方法。 package org.apache.catalina.util; import java.util.HashMap; import java.util.Map; public final class ParameterMap extends HashMap { public ParameterMap() { super (); } public ParameterMap(int initialCapacity) { super(initialCapacity); } public ParameterMap(int initialCapacity, float loadFactor) { super(initialCapacity, loadFactor); } public ParameterMap(Map map) { super(map); } private boolean locked = false; public boolean isLocked() { return (this.locked); } public void setLocked(boolean locked) { this.locked = locked; } private static final StringManager sm = StringManager.getManager("org.apache.catalina.util"); public void clear() { if (locked) throw new IllegalStateException(sm.getString("parameterMap.locked")); super.clear(); } public Object put(Object key, Object value) { if (locked) throw new IllegalStateException (sm.getString("parameterMap.locked")); return (super.put(key, value)); } public void putAll(Map map) { if (locked) throw new IllegalStateException (sm.getString("parameterMap.locked")); super.putAll(map); } public Object remove(Object key) { if (locked) throw new IllegalStateException (sm.getString("parameterMap.locked")); return (super.remove(key)); } }
现在,让我们看看parseParameters
方法是如何工作的。 if (parsed) return;
ParameterMap results = parameters; if (results == null) results = new ParameterMap();
接着,parseParameters 方法打开ParameterMap 的 锁,以便修改它。 results.setLocked(false);
下一步,parseParameters 方法检查编码,如果编码为空则赋予默认编码。 String encoding = getCharacterEncoding(); if (encoding == null) encoding = "ISO-8859-1";
// Parse any parameters specified in the query string String queryString = getQueryString(); try { RequestUtil.parseParameters(results, queryString, encoding); } catch (UnsupportedEncodingException e) { ; } 下一步,parseParameters 方法尝试看看HTTP 请求体中是否包含参数。如果用户使用POST 方法发送请求,content length 大 于0 ,并且content type 是application/x-www-form-urlencoded , 那么请求体中就会包含参数。解析请求体的代码如下。 // Parse any parameters specified in the input stream String contentType = getContentType(); if (contentType == null) contentType = ""; int semicolon = contentType.indexOf(';'); if (semicolon >= 0) { contentType = contentType.substring (0, semicolon).trim(); } else { contentType = contentType.trim(); } if ("POST".equals(getMethod()) && (getContentLength() > 0) && "application/x-www-form-urlencoded".equals(contentType)) { try { int max = getContentLength(); int len = 0; byte buf[] = new byte[getContentLength()]; ServletInputStream is = getInputStream(); while (len < max) { int next = is.read(buf, len, max - len); if (next < 0 ) { break; } len += next; } is.close(); if (len < max) { throw new RuntimeException("Content length mismatch"); } RequestUtil.parseParameters(results, buf, encoding); } catch (UnsupportedEncodingException ue) { ; } catch (IOException e) { throw new RuntimeException("Content read fail"); } }
// Store the final results results.setLocked(true); parsed = true; parameters = results; 创建HttpResponse 对 象HttpResponse 类实现了javax.servlet.http.HttpServletResponse 接口,跟随该类的 还有一个门面类HttpResponseFacade 。Figure 3.3 展现了HttpResponse 和 相关类的类图。 public PrintWriter getWriter() { // if autoflush is true, println() will flush, // but print() will not. // the output argument is an OutputStream writer = new PrintWriter(output, true); return writer; }
public PrintWriter getWriter() throws IOException { ResponseStream newStream = new ResponseStream(this); newStream.setCommit(false); OutputStreamWriter osr = new OutputStreamWriter(newStream, getCharacterEncoding()); writer = new ResponseWriter(osr); return writer; } 静态资源处理器和Servlet 处 理器ServletProcessor 类和第2 章的ex02.pyrmont.ServletProcessor 类 是类似的。它们都只有一个方法:process 。然而,ex03.pyrmont.connector.ServletProcessor 的process 方法接受一个HttpRequest 对 象和一个HttpResponse 对象,而不是Request 对象和Response 对 象。下面是本章应用的process 方法原型: public void process(HttpRequest request, HttpResponse response) {
servlet = (Servlet) myClass.newInstance(); HttpRequestFacade requestPacade = new HttpRequestFacade(request); HttpResponseFacade responseFacade = new HttpResponseFacade(response); servlet.service(requestFacade, responseFacade); ((HttpResponse) response).finishResponse();
运行应用程序要在Windows 运行该应用,在工作目录运行以下命令: java -classpath ./lib/servlet.jar;./ ex03.pyrmont.startup.Bootstrap
java -classpath ./lib/servlet.jar:./ ex03.pyrmont.startup.Bootstrap
要显示index.html ,使用下面的URL : http://localhost:808O/index.html 要调用PrimitiveServlet,直接在浏览器中访问下面的URL: http://localhost:8080/servlet/PrimitiveServlet
Hello. Roses are red. Violets are blue. http://localhost:8080/servlet/ModernServlet
http://localhost:8080/servlet/ModernServlet?userName=tarzan&password=pwd
总结本章你已经学习到了连接器 是如何工作的。本章构建的连接器 ,是Tomcat 4 默 认连接器 的一个简化版本。正如你知道的,这个默认连接器 因为低效而被不推荐使用(deprecated )。 例如,所有的HTTP 请求headers都被解析,即使servlet 从来没有使用它们。结果,默认连接器 运行速度缓慢,并被更快的Coyote 代替。Coyote 的代码可以从Apache基金会网站下载到。无论如何,默认连接器都是一个很好的学 习工具,我们将在第4 章详细讨论它。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2010-04-14
很多时候都是想着解决一个问题才去看源代码的。
基本用研究源代码的时间都可以找到很多替代品。 |
|
返回顶楼 | |
发表时间:2010-04-26
FeiXing2008 写道 很多时候都是想着解决一个问题才去看源代码的。
基本用研究源代码的时间都可以找到很多替代品。 因人 而异 |
|
返回顶楼 | |
发表时间:2010-04-30
后边的没有了吗?楼主加油继续了
|
|
返回顶楼 | |
发表时间:2010-05-11
bangyan2003 写道 FeiXing2008 写道 很多时候都是想着解决一个问题才去看源代码的。
基本用研究源代码的时间都可以找到很多替代品。 因人 而异 不错不错,同上 |
|
返回顶楼 | |
发表时间:2010-05-11
FeiXing2008 写道 很多时候都是想着解决一个问题才去看源代码的。
基本用研究源代码的时间都可以找到很多替代品。 说实话,很同意你的看法,不过我一般还是会去查源代码。 |
|
返回顶楼 | |
浏览 3720 次