HttpservletRequest对象
该请求对象是 javax.servlet.http. HttpServletRequest 对象的一个实例。每次客户端请求一个页面时,JSP 引擎就会创建一个新的对象来表示这个请求。请求对象提供方法来获取 HTTP 标题信息,包括表单数据,cookies,HTTP 方法等。
S.N. | 方法 & 描述 |
---|---|
1 | Cookie[] getCookies() 返回一个数组,其中包含客户端用这个请求发送的所有 Cookie 对象。 |
2 | Enumeration getAttributeNames() 返回一个枚举包含此请求可用的属性的名称。 |
3 | Enumeration getHeaderNames() 返回一个这个请求包含的所有标题名称的枚举。 |
4 | Enumeration getParameterNames() 返回一个字符串对象的枚举,该字符串对象包括包含在此请求中的参数的名称。 |
5 | HttpSession getSession()
扫描二维码关注公众号,回复:
3872845 查看本文章
返回与此请求相关的当前会话,或者如果该请求没有会话,那么就创建一个。 |
6 | HttpSession getSession(boolean create) 返回与这个请求相关的当前的HttpSession或,如果没有当前会话并且 create 为真,那么返回一个新的会话。 |
7 | Locale getLocale() 返回客户会接受内容的首选区域设置,基于所包含的 accept – language 标题 |
8 | Object getAttribute(String name) 作为一个对象返回指定属性的值,如果指定的名称没有属性,返回 null。 |
9 | ServletInputStream getInputStream() 使用 ServletInputStream 将请求的主体作为二进制数据检索。 |
10 | String getAuthType() 返回用于保护 servlet 的验证方案的名称,例如,“BASIC”或“SSL”,如果 JSP 没有被保护,那么返回 null |
11 | String getCharacterEncoding() 返回在该请求内部使用的字符编码的名称。 |
12 | String getContentType() 返回该请求主体的 MIME 类型,如果不知道类型,返回 null。 |
13 | String getContextPath() 返回表示请求上下文的请求 URI 的一部分。 |
14 | String getHeader(String name) 将指定的请求标题的值作为一个字符串返回。 |
15 | String getMethod() 返回生成该请求的 HTTP 方法的名称,比如 GET,POST,或 PUT。 |
16 | String getParameter(String name) 将一个请求参数的值作为字符串返回,如果参数不存在,返回 null。 |
17 | String getPathInfo() 返回与客户端生成请求时发送的 URL 相关联的任何额外的路径信息。 |
18 | String getProtocol() 返回请求协议的名称和版本。 |
19 | String getQueryString() 返回在路径后包含在请求 URL 的查询字符串。 |
20 | String getRemoteAddr() 返回发送请求的客户端的互联网协议(IP)地址。 |
21 | String getRemoteHost() 返回发送请求的客户机的全称。 |
22 | String getRemoteUser() 如果用户已经通过身份验证,就返回发出这一请求的登录用户,如果用户没有被验证,那么返回 null。 |
23 | String getRequestURI() 从取决于 HTTP 请求首行的查询字符串的协议名称中返回请求 URL 的一部分。 |
24 | String getRequestedSessionId() 返回客户端指定的会话 ID。 |
25 | String getServletPath() 返回调用 JSP 的请求 URL 的部分。 |
26 | String[] getParameterValues(String name) 返回一个字符串对象数组,其中包含所有的给定的请求参数的值,如果参数不存在,那么返回 null。 |
27 | boolean isSecure() 返回一个布尔值表示是否使用一个安全通道发出了这个请求,比如 HTTPS。 |
28 | int getContentLength() 以字节为单位,返回请求的主体长度并通过输入流使其可用,如果长度是未知的,那么返回 -1。 |
29 | int getIntHeader(String name) 作为 int 返回指定请求标题的值。 |
30 | int getServerPort() 返回收到这个请求的端口号。 |
HttpServletResponse 对象
该响应对象是 javax.servlet.http.HttpServletResponse 的一个实例。正如服务器创建请求对象,它也创建了一个对象来表示客户端的响应。
S.N. | 方法 & 描述 |
---|---|
1 | String encodeRedirectURL(String url) 将指定的 URL 编码用于 sendRedirect 方法,如果不需要编码,则返回的 URL 不变。 |
2 | String encodeURL(String url) 编码由包括会话 ID 指定的 URL,或者,如果不需要编码,返回的 URL 不变。 |
3 | boolean containsHeader(String name) 返回一个布尔值表明指定的响应标题是否已经设置。 |
4 | boolean isCommitted() 返回一个布尔值表明响应是否已经提交。 |
5 | void addCookie(Cookie cookie) 将指定的 cookie 添加到响应中。 |
6 | void addDateHeader(String name, long date) 添加一个带有给定名称和日期值的响应标题。 |
7 | void addHeader(String name, String value) 添加一个带有给定名称和值的响应标题。 |
8 | void addIntHeader(String name, int value) 添加一个带有给定名称和整数值的响应标题。 |
9 | void flushBuffer() 将缓冲区的内容强行写入到客户端。 |
10 | void reset() 清除缓冲区中的全部数据,以及状态码和标题。 |
11 | void resetBuffer() 清除响应中没有清除头或状态码的潜在的缓冲区的内容。 |
12 | void sendError(int sc) 使用指定的状态代码给客户端发送一个错误响应,并清除缓冲区。 |
13 | void sendError(int sc, String msg) 使用指定的状态给客户端发送一个错误响应。 |
14 | void sendRedirect(String location) 使用指定的重定向位置 URL 给客户端发送一个临时的重定向响应。 |
15 | void setBufferSize(int size) 为响应主体设置首选缓冲区大小。 |
16 | void setCharacterEncoding(String charset) 设置将被发送到客户端的响应的字符编码(MIME字符集)例如 UTF-8。 |
17 | void setContentLength(int len) 设置 HTTP servlet 中的响应的主体内容的长度,这种方法设置了 HTTP 内容-长度标题。 |
18 | void setContentType(String type) 如果响应尚未提交,设置要被发送到客户端的响应的内容类型。 |
19 | void setDateHeader(String name, long date) 用给定的名称和日期值设置一个响应标题。 |
20 | void setHeader(String name, String value) 用给定的名称和值设置一个响应标题。 |
21 | void setIntHeader(String name, int value) 用给定的名称和整数值设置一个响应标题。 |
22 | void setLocale(Locale loc) 如果反应尚未提交,设置响应的语言环境。 |
23 | void setStatus(int sc) 为响应设置状态码。 |
HTTP状态码
编码: | 消息: | 描述: |
---|---|---|
100 | Continue | 只有一部分的服务器请求已经收到,但只要没有被拒绝,客户端应该继续请求 |
101 | Switching Protocols | 服务器交换了协议。 |
200 | OK | 请求是 OK |
201 | Created | 请求已经完成,新的资源被创建 |
202 | Accepted | 请求被接受处理,但是处理还没有完成。 |
203 | Non-authoritative Information | |
204 | No Content | |
205 | Reset Content | |
206 | Partial Content | |
300 | Multiple Choices | 一个链接列表。用户可以选择一个链接然后跳转到那个位置。最多可选择 5 个地址 |
301 | Moved Permanently | 请求页面已经被移到新的 url 中 |
302 | Found | 请求页面暂时被移到新的 url 中 |
303 | See Other | 请求页面可在不同的 url 中找到 |
304 | Not Modified | |
305 | Use Proxy | |
306 | Unused | 该代码是在前一版本使用的。它已不再使用,但该代码保留下来了。 |
307 | Temporary Redirect | 请求页面被暂时移到新的url中。 |
400 | Bad Request | 服务器没有理解请求。 |
401 | Unauthorized | 请求页面需要用户名和密码 |
402 | Payment Required | 你还不能使用这个代码 |
403 | Forbidden | 不允许访问请求页面 |
404 | Not Found | 服务器找不到请求页面。 |
405 | Method Not Allowed | 在请求中指定的方法不允许使用。 |
406 | Not Acceptable | 服务器只能生成一个不被客户端接收的响应。 |
407 | Proxy Authentication Required | 在这个请求得到服务之前,你必须验证一个代理服务器。 |
408 | Request Timeout | 请求花费的时间比服务器准备等待的时间长。 |
409 | Conflict | 由于冲突请求不能实现。 |
410 | Gone | 请求页面不再可用。 |
411 | Length Required | "内容-长度" 没有被定义。没有它服务器不会接受请求。 |
412 | Precondition Failed | 服务器给出给定的请求评估的前提为假。 |
413 | Request Entity Too Large | 服务器不会接受请求,因为请求实体太大。 |
414 | Request-url Too Long | 服务器不会接受请求,因为 url 太长。当你把“post”请求转换为带有很长的查询信息的“get”请求时,这种情况就会发生 |
415 | Unsupported Media Type | 服务器不会接受请求因为媒体类型不支持。 |
417 | Expectation Failed | |
500 | Internal Server Error | 请求未完成。服务器遇到了意外情况。 |
501 | Not Implemented | 请求未能完成。服务器不支持所需的功能。 |
502 | Bad Gateway | 请求未能完成。服务器从上游服务器收到无效响应 |
503 | Service Unavailable | 请求未能完成。服务器暂时过载或瘫痪。 |
504 | Gateway Timeout | 网关超时。 |
505 | HTTP Version Not Supported | 服务器不支持“http 协议”版本。 |
S.N. | 方法 &描述 |
---|---|
1 | public void setStatus ( int statusCode ) 此方法设置一个任意的状态码。setStatus 方法接受一个 int(状态码)作为参数。如果你的响应包含一个特殊的状态码和文档,在实际中用 PrintWriter 返回任何内容之前一定要调用 setStatus。 |
2 | public void sendRedirect(String url) 该方法生成一个 302 响应以及一个位置标题给出新文档的 URL。 |
3 | public void sendError(int code, String message) 这种方法发送一个状态码(通常是 404)以及一个在 HTML 文档内自动格式化的短消息并发送到客户端。 |
表单处理
http://www.test.com/hello?key1=value1&key2=value2
Post方法
-
getParameter(): 调用 request.getParameter() 方法得到一种形式参数的值。
-
getParameterValues():如果参数出现不止一次,那么就调用这个方法并返回多个值,例如复选框。
-
getParameterNames():如果你想要在当前请求下得到一个所有参数的完整的列表,那么调用这个方法。
- getInputStream(): 调用这个方法读取来自客户端二进制数据流。
过滤器
-
在请求访问后端资源之前从客户端拦截请求。
- 在响应发送回客户端之前从服务器操作响应
Servlet 过滤器方法
一个过滤器是一个简单的 Java 类,实现了 javax.servlet.Filter 接口。javax.servlet.Filter接口定义了三个方法:
S.N. | 方法 & 描述 |
---|---|
1 | public void doFilter (ServletRequest, ServletResponse, FilterChain) 由于客户端在链尾请求响应,每次请求/响应对通过链时,容器会调用此方法。 |
2 | public void init(FilterConfig filterConfig) 由 web 容器调用此方法,向过滤器表明它将被放置在服务中。 |
3 | public void destroy() 由 web 容器调用此方法,向过滤器表明它将从服务中被去掉。 |
// Implements Filter class public class LogFilter implements Filter { public void init(FilterConfig config) throws ServletException{ // Get init parameter String testParam = config.getInitParameter("test-param"); //Print the init parameter System.out.println("Test Param: " + testParam); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException { // Get the IP address of client machine. String ipAddress = request.getRemoteAddr(); // Log the IP address and current timestamp. System.out.println("IP "+ ipAddress + ", Time " + new Date().toString()); // Pass request back down the filter chain chain.doFilter(request,response); } public void destroy( ){ /* Called before the Filter instance is removed from service by the web container*/ } }在web.xml中
<filter>
<filter-name>LogFilter</filter-name>
<filter-class>LogFilter</filter-class>
<init-param>
<param-name>test-param</param-name>
<param-value>Initialization Paramter</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LogFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Cookies
-
服务器脚本向浏览器发送的一系列cookies。例如姓名、年龄、身份证号码等。
-
浏览器将这个信息存储在本地机器上,以供将来使用。
- 下次当浏览器向web服务器发送任何请求时,将这些 cookies 信息发送给服务器,服务器使用这些信息来识别用户或可能用于其他目的。
Servlet Cookies 方法
下面是与 Cookie 对象关联的有用的方法列表,你可以在 JSP 中操作 cookies 时使用:
S.N. | 方法 & 描述 |
---|---|
1 | public void setDomain(String pattern) 此方法设置了 cookie 适用的领域,例如 tutorialspoint.com。 |
2 | public String getDomain() 此方法得到了 cookie 适用的领域,例如 tutorialspoint.com。 |
3 | public void setMaxAge(int expiry) 该方法设置了在 cookie 到期之前需要多少时间(以秒为单位)。如果你不设置这个,cookie 只持续到当前会话。 |
4 | public int getMaxAge() 该方法返回了最大持续时间的 cookie,以秒为单位指定,默认情况下,-1表示 cookie 会持续到浏览器关闭。 |
5 | public String getName() 该方法将返回 cookie 的名称。这个名字创建后不能更改。 |
6 | public void setValue(String newValue) 这个方法设置了与 cookie 相关的值。 |
7 | public String getValue() 这个方法得到了与 cookie相关的值。 |
8 | public void setPath(String uri) 该方法设置了 cookie 应用的路径。如果你不指定路径,那么与当前页面相同的目录以及子目录中的所有 URL都会返回 cookie。 |
9 | public String getPath() 该方法获取 cookie 应用的路径。 |
10 | public void setSecure(boolean flag) 此方法设置布尔值,该值表明 cookie 是否只能通过加密连接发送(例如 SSL)。 |
11 | public void setComment(String purpose) 这种方法指定了描述 cookie 目的的评论。如果浏览器向用户展示了这个 cookie,那么评论是有用的。 |
12 | public String getComment() 该方法返回描述 cookie 目的的评论,如果 cookie 没有评论,那么返回 null。 |
用 JSP 设置 Cookies
用 JSP 设置 Cookies 包括三个步骤:
(1) 创建一个 Cookie 对象: 用 cookie 的名称和值调用 cookie 构造函数,名称和值是字符串。
Cookie cookie = new Cookie("key","value");
记住,这个名字和值都不应该包含空格或任何以下字符:
[ ] ( ) = , " / ? @ : ;
(2) 设置最大持续时间: 使用 setMaxAge 指定 cookie 的有效期是多长时间(以秒为单位)。以下是建立了一个持续 24 小时的 cookie。
cookie.setMaxAge(60*60*24);
(3) 将 cookie 发送到 HTTP 响应标题中: 使用 response.addCookie 在 HTTP 响应标题中添加 cookies,如下所示:
response.addCookie(cookie);
用 JSP 读取 Cookies
想要读取 cookie,你需要通过调用 HttpServletRequest 的 getCookies() 方法创建一个 javax.servlet.http 数组。然后通过数组循环,使用 getName() 和 getValue() 方法来访问每个 cookie 和相关的值。
示例
让我们读取之前例子中设置的 cookies:
<html> <head> <title>Reading Cookies</title> </head> <body> <center> <h1>Reading Cookies</h1> </center> <% Cookie cookie = null; Cookie[] cookies = null; // Get an array of Cookies associated with this domain cookies = request.getCookies(); if( cookies != null ){ out.println("<h2> Found Cookies Name and Value</h2>"); for (int i = 0; i < cookies.length; i++){ cookie = cookies[i]; out.print("Name : " + cookie.getName( ) + ", "); out.print("Value: " + cookie.getValue( )+" <br/>"); } }else{ out.println("<h2>No cookies founds</h2>"); } %> </body> </html>
用 JSP 删除 Cookies
删除 cookies 非常简单。如果你想删除一个 cookie,那么你只需要按照以下三步来处理:
-
读取一个已经存在的 cookie 并把它保存在 Cookie 对象中。
-
使用 setMaxAge() 方法将 cookie 的持续时间设置为 0 来删除一个已经存在的 cookie。
- 将这个 cookie 添加到响应标题中。
会话跟踪
JSP 使用 servlet 提供的 HttpSession 接口,该接口提供了一种方法来识别网站中跨多个页面请求或访问的用户,并存储用户信息。
默认情况下,JSP 为每个新的客户端自动的启用会话跟踪和一个新的被实例化的 HttpSession 对象。禁用会话跟踪需要通过设置页面指令会话属性为 false 显式地关闭它,如下所示:
<%@ page session="false" %>
S.N. | 方法 & 描述 |
---|---|
1 | public Object getAttribute(String name) 该方法返回会话中与指定的名称绑定的对象,如果没有绑定对象名称,返回 null。 |
2 | public Enumeration getAttributeNames() 该方法返回一个字符串对象的枚举,其中包含绑定到这个会话的所有对象的名字。 |
3 | public long getCreationTime() 该方法返回创建会话的时间,自GMT时间1970年1月1日凌晨以来,以毫秒为单位。 |
4 | public String getId() 该方法返回一个字符串,其中包含分配给这个会话的唯一标识符。 |
5 | public long getLastAccessedTime() 该方法返回上次客户端发送与这个会话相关的请求的时间,自GMT时间1970年1月1日凌晨以来,毫秒的数量。 |
6 | public int getMaxInactiveInterval() 该方法返回最大时间间隔,以秒为单位,servlet 容器在客户端访问中将打开这个会话。 |
7 | public void invalidate() 这个方法使会话无效并解除全部绑定到该会话的对象。 |
8 | public boolean isNew( 如果客户端还不知道会话或如果客户选择不加入会话,这个方法返回 true。 |
9 | public void removeAttribute(String name) 该方法从会话中删除制定名称的绑定对象。 |
10 | public void setAttribute(String name, Object value) 该方法使用指定的名称解除会话的一个对象。 |
11 | public void setMaxInactiveInterval(int interval) 在 servlet 容器使这个会话无效之前,这种方法在客户端请求之间指定了时间,以秒为单位,。 |
删除会话数据
当你完成了用户会话数据,你有以下几种选择:
-
删除一个特定的属性: 你可以调用 public void removeAttribute(String name) 方法来删除与特定的键相关的值。
-
删除整个会话: 你可以调用 public void invalidate() 方法来删除整个会话。
-
设置会话超时: 你可以调用 public void setMaxInactiveInterval(int interval) 方法分别为每个会话设置超时。
-
注销用户: 服务器可以支持 servlet 2.4,你可以调用 logout 来注销 Web 服务器的客户端,并使所有属于该的用户的会话无效。
- web.xml 配置: 如果你使用的是 Tomcat,除了上述方法外,你还可以在 web.xml文件中设置会话超时,如下所示。
<session-config>
<session-timeout>15</session-timeout>
</session-config>
文件上传
- 表单 method 的属性应该设置为 POST 方法,不能使用 GET 方法。
-
表单 enctype 的属性应该设置为 multipart/formdata。
-
表单 action 的属性应该设置为一个把文件上传到后台服务器的 JSP 文件。下面的例子是使用程序uploadFile.jsp 来上传文件。
- 为了上传一个单一的文件,你应该使用一个带有属性type="file"的< input .../ >标签。为了允许多个文件上传,包含多个输入标签,它们带有不同的name属性的值。浏览器将浏览按钮与每个输入标签进行关
<%@ page import="java.io.*,java.util.*, javax.servlet.*" %>
<%@ page import="javax.servlet.http.*" %>
<%@ page import="org.apache.commons.fileupload.*" %>
<%@ page import="org.apache.commons.fileupload.disk.*" %>
<%@ page import="org.apache.commons.fileupload.servlet.*" %>
<%@ page import="org.apache.commons.io.output.*" %>
<%
File file ;
int maxFileSize = 5000 * 1024;
int maxMemSize = 5000 * 1024;
ServletContext context = pageContext.getServletContext();
String filePath = context.getInitParameter("file-upload");
// Verify the content type
String contentType = request.getContentType();
if ((contentType.indexOf("multipart/form-data") >= 0)) {
DiskFileItemFactory factory = new DiskFileItemFactory();
// maximum size that will be stored in memory
factory.setSizeThreshold(maxMemSize);
// Location to save data that is larger than maxMemSize.
factory.setRepository(new File("c:\\temp"));
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// maximum file size to be uploaded.
upload.setSizeMax( maxFileSize );
try{
// Parse the request to get file items.
List fileItems = upload.parseRequest(request);
// Process the uploaded file items
Iterator i = fileItems.iterator();
out.println("<html>");
out.println("<head>");
out.println("<title>JSP File upload</title>");
out.println("</head>");
out.println("<body>");
while ( i.hasNext () )
{
FileItem fi = (FileItem)i.next();
if ( !fi.isFormField () )
{
// Get the uploaded file parameters
String fieldName = fi.getFieldName();
String fileName = fi.getName();
boolean isInMemory = fi.isInMemory();
long sizeInBytes = fi.getSize();
// Write the file
if( fileName.lastIndexOf("\\") >= 0 ){
file = new File( filePath +
fileName.substring( fileName.lastIndexOf("\\"))) ;
}else{
file = new File( filePath +
fileName.substring(fileName.lastIndexOf("\\")+1)) ;
}
fi.write( file ) ;
out.println("Uploaded Filename: " + filePath +
fileName + "<br>");
}
}
out.println("</body>");
out.println("</html>");
}catch(Exception ex) {
System.out.println(ex);
}
}else{
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet upload</title>");
out.println("</head>");
out.println("<body>");
out.println("<p>No file uploaded</p>");
out.println("</body>");
out.println("</html>");
}
%>
处理日期
SN | 方法描述 |
---|---|
1 | boolean after(Date date) 如果调用的 Date 对象包含的日期晚于指定的日期,则返回 true,否则返回 false。 |
2 | boolean before(Date date) 如果调用的 Date 对象包含的日期早于指定的日期,则返回 true,否则返回 false。 |
3 | Object clone( ) 重复调用的 Date 对象。 |
4 | int compareTo(Date date) 比较调用的 Date 对象与 date 的值。如果值是相等的,则返回 0。如果调用的 Date 对象比 date 更早,则返回一个负数。如果调用 Date 对象是晚于 date 的,则返回一个正数。 |
5 | int compareTo(Object obj) 如果 obj 是 Date 类,则操作与 compareTo(Date) 是同一个,否则抛出 ClassCastException 异常。 |
6 | boolean equals(Object date) 如果调用的 Date 对象与指定的日期有相同的时间和日期,则返回 true,否则返回 false。 |
7 | long getTime( ) 返回从 1970 年 1 月 1 日凌晨 0 点开始至今的毫秒数。 |
8 | int hashCode( ) 返回调用对象的哈希编码 |
9 | void setTime(long time) 由指定的时间设置时间和日期,它表示从 1970 年 1 月 1 日凌晨 0 点开始到指定时间的毫秒数。 |
10 | String toString( ) 转换调用的 Date 对象到 string 类型,并且返回该结果。 |
<%@ page import="java.io.*,java.util.*" %> <%@ page import="javax.servlet.*,java.text.*" %> <html> <head> <title>Display Current Date & Time</title> </head> <body> <center> <h1>Display Current Date & Time</h1> </center> <% Date dNow = new Date( ); SimpleDateFormat ft = new SimpleDateFormat ("E yyyy.MM.dd 'at' hh:mm:ss a zzz"); out.print( "<h2 align=\"center\">" + ft.format(dNow) + "</h2>"); %> </body> </html>
Simple DateFormat 格式化代码
指定时间格式使用一个时间模式字符串。在这个模式中,所有 ASCII 字母被保留为模式字母,它们被定义为如下:
字符 | 描述 | 例子 |
---|---|---|
G | 时代指示符 | AD |
y | 四位数的某年 | 2001 |
M | 一年中的某月 | July or 07 |
d | 一月中的某日 | 10 |
h | A.M./P.M. (1~12)的某小时 | 12 |
H | 一天 (0~23)中的某小时 | 22 |
m | 一小时中的某分钟 | 30 |
s | 一分钟中的某秒 | 55 |
S | 毫秒 | 234 |
E | 一周中的某天 | Tuesday |
D | 一年中的某天 | 360 |
F | 一月中的一周的某天 | 2 (second Wed. in July) |
w | 一年中的某周 | 40 |
W | 一月中的某周 | 1 |
a | A.M./P.M.标记 | PM |
k | 一天(1~24)中的某小时 | 24 |
K | A.M./P.M. (0~11)的某小时 | 10 |
z | 时区 | Eastern Standard Time |
' | 消逝的文本 | Delimiter |
" | 单引号 | ` |
页面重定向
转发在服务器端完成的;重定向是在客户端完成的
转发的速度快;重定向速度慢
转发的是同一次请求;重定向是两次不同请求
转发不会执行转发后的代码;重定向会执行重定向之后的代码
转发地址栏没有变化;重定向地址栏有变化
转发必须是在同一台服务器下完成;重定向可以在不同的服务器下完成
点击计数器
<%@ page import="java.io.*,java.util.*" %> <html> <head> <title>Applcation object in JSP</title> </head> <body> <% Integer hitsCount = (Integer)application.getAttribute("hitCounter"); if( hitsCount ==null || hitsCount == 0 ){ /* First visit */ out.println("Welcome to my website!"); hitsCount = 1; }else{ /* return visit */ out.println("Welcome back to my website!"); hitsCount += 1; } application.setAttribute("hitCounter", hitsCount); %> <center> <p>Total number of visits: <%= hitsCount%></p> </center> </body> </html>
计数器重置
如果你重新启动你的应用程序如 Web 服务器,这将重置你的应用程序变量,点击计数器将重置为零。为了避免这种损失,你可以用下面专业的方法实现点击计数器:
-
定义一个带有单一计数的数据库表,我们叫做点击量。设置它的值为 0。
-
每次点击,读取该表得到点击量的值。
-
点击量加 1,更新该表中的值。
-
显示点击计数器的新值作为总页面的点击量。
- 如果你想计算所有页面的点击量,对所有的页面实现上面的逻辑。