热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【JSPHTTP状态码】【JSP表单处理】【JSP过滤器】【JSPCookie处理】【JSPSession】【JSP文件上传】

JSP HTTP 状态码HTTP请求与HTTP响应的格式相近,都有着如下结构:以状态行+CRLF(回车换行)开始零行或多行头模块+CRLF一个空行,比如CRLF可选的消息体比如文件,查询数据,查询输出
JSP HTTP 状态码

HTTP请求与HTTP响应的格式相近,都有着如下结构:

  • 以状态行+CRLF(回车换行)开始
  • 零行或多行头模块+CRLF
  • 一个空行,比如CRLF
  • 可选的消息体比如文件,查询数据,查询输出

举例来说,一个服务器响应头看起来就像下面这样:

HTTP/1.1 200 OK
Content-Type: text/html
Header2: ...
...
HeaderN: ...
(Blank Line)


...

...

 

状态行包含HTTP版本,一个状态码,和状态码相对应的短消息。

 

下表列出了可能会从服务器返回的HTTP状态码和与之关联的消息:

状态码消息描述
100Continue只有一部分请求被服务器接收,但只要没被服务器拒绝,客户端就会延续这个请求
101Switching Protocols服务器交换机协议
200OK请求被确认
201Created请求时完整的,新的资源被创建
202Accepted请求被接受,但未处理完
203Non-authoritative Information 
204No Content 
205Reset Content 
206Partial Content 
300Multiple Choices一个超链接表,用户可以选择一个超链接并访问,最大支持5个超链接
301Moved Permanently被请求的页面已经移动到了新的URL下
302Found被请求的页面暂时性地移动到了新的URL下
303See Other被请求的页面可以在一个不同的URL下找到
304Not Modified 
305Use Proxy 
306Unused已经不再使用此状态码,但状态码被保留
307Temporary Redirect被请求的页面暂时性地移动到了新的URL下
400Bad Request服务器无法识别请求
401Unauthorized被请求的页面需要用户名和密码
402Payment Required目前还不能使用此状态码
403Forbidden禁止访问所请求的页面
404Not Found服务器无法找到所请求的页面
405Method Not Allowed请求中所指定的方法不被允许
406Not Acceptable服务器只能创建一个客户端无法接受的响应
407Proxy Authentication Required在请求被服务前必须认证一个代理服务器
408Request Timeout请求时间超过了服务器所能等待的时间,连接被断开
409Conflict请求有矛盾的地方
410Gone被请求的页面不再可用
411Length Required"Content-Length"没有被定义,服务器拒绝接受请求
412Precondition Failed请求的前提条件被服务器评估为false
413Request Entity Too Large因为请求的实体太大,服务器拒绝接受请求
414Request-url Too Long服务器拒绝接受请求,因为URL太长。多出现在把"POST"请求转换为"GET"请求时所附带的大量查询信息
415Unsupported Media Type服务器拒绝接受请求,因为媒体类型不被支持
417Expectation Failed 
500Internal Server Error请求不完整,服务器遇见了出乎意料的状况
501Not Implemented请求不完整,服务器不提供所需要的功能
502Bad Gateway请求不完整,服务器从上游服务器接受了一个无效的响应
503Service Unavailable请求不完整,服务器暂时重启或关闭
504Gateway Timeout网关超时
505HTTP Version Not Supported服务器不支持所指定的HTTP版本

设置HTTP状态码的方法

下表列出了HttpServletResponse 类中用来设置状态码的方法:

S.N.方法 & 描述
1public void setStatus ( int statusCode )

 

此方法可以设置任意的状态码。如果您的响应包含一个特殊的状态码和一个文档,请确保在用PrintWriter返回任何内容前调用setStatus方法
2public void sendRedirect(String url)

 

此方法产生302响应,同时产生一个 Location 头告诉URL 一个新的文档
3public void sendError(int code, String message)

 

此方法将一个状态码(通常为 404)和一个短消息,自动插入HTML文档中并发回给客户端

HTTP状态码程序示例

接下来的例子将会发送407错误码给浏览器,然后浏览器将会告诉您"Need authentication!!!"。






<%
// 设置错误代码,并说明原因
response.sendError(407, "Need authentication!!!" );
%>

访问以上JSP页面,将会得到以下结果:

js_http_status_codes

您也可以试试使用其他的状态码,看会不会得到什么意想不到结果。

JSP 表单处理

我们在浏览网页的时候,经常需要向服务器提交信息,并让后台程序处理。浏览器中使用 GET 和 POST 方法向服务器提交数据。


GET 方法

GET方法将请求的编码信息添加在网址后面,网址与编码信息通过"?"号分隔。如下所示:

http://www.runoob.com/hello?key1=value1&key2=value2

GET方法是浏览器默认传递参数的方法,一些敏感信息,如密码等建议不使用GET方法。

用get时,传输数据的大小有限制 (注意不是参数的个数有限制),最大为1024字节。


POST 方法

一些敏感信息,如密码等我们可以通过POST方法传递,POST提交数据是隐式的。

POST提交数据是不可见的,GET是通过在url里面传递的(可以看一下你浏览器的地址栏)。

JSP使用getParameter()来获得传递的参数,getInputStream()方法用来处理客户端的二进制数据流的请求。


JSP 读取表单数据

  • getParameter(): 使用 request.getParameter() 方法来获取表单参数的值。

  • getParameterValues(): 获得如checkbox类(名字相同,但值有多个)的数据。 接收数组变量 ,如checkbox类型

  • getParameterNames():该方法可以取得所有变量的名称,该方法返回一个 Enumeration。

  • getInputStream():调用此方法来读取来自客户端的二进制数据流。


使用URL的 GET 方法实例

以下是一个简单的URL,并使用GET方法来传递URL中的参数:

http://localhost:8080/testjsp/main.jsp?name=菜鸟教程&url=http://ww.runoob.com

testjsp 为项目地址。

以下是 main.jsp 文件的JSP程序用于处理客户端提交的表单数据,我们使用getParameter()方法来获取提交的数据:

<%@ page language="java" cOntentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>







使用 GET 方法读取数据



  • 站点名:
    <%= request.getParameter("name")%>


  • 网址:
    <%= request.getParameter("url")%>




接下来我们通过浏览器访问 http://localhost:8080/testjsp/main.jsp?name=菜鸟教程&url=http://ww.runoob.com 输出结果如下所示:


使用表单的 GET 方法实例

以下是一个简单的 HTML 表单,该表单通过GET方法将客户端数据提交 到 main.jsp 文件中:









站点名:


网址:



将以上HTML代码保存到test.htm文件中。 将该文件放置于当前jsp项目的 WebContent 目录下(与 main.jsp 同一个目录)。

通过访问 http://localhost:8080/testjsp/test.html 提交表单数据到 main.jsp 文件,演示 Gif 图如下所示:

在 "站点名" 与 "网址" 两个表单中填入信息,并点击 "提交" 按钮,它将输出结果。


使用表单的 POST 方法实例

接下来让我们使用POST方法来传递表单数据,修改main.jsp与Hello.htm文件代码,如下所示:

main.jsp文件代码:

<%@ page language="java" cOntentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>







使用 POST 方法读取数据



  • 站点名:
    <%
    // 解决中文乱码的问题
    String name = new String((request.getParameter("name")).getBytes("ISO-8859-1"),"UTF-8");
    %>
    <%=name%>


  • 网址:
    <%= request.getParameter("url")%>




代码中我们使用 new String((request.getParameter("name")).getBytes("ISO-8859-1"),"UTF-8")来转换编码,防止中文乱码的发生。

以下是test.htm修改后的代码:









站点名:


网址:



通过访问 http://localhost:8080/testjsp/test.html 提交表单数据到 main.jsp 文件,演示 Gif 图如下所示:


传递 Checkbox 数据到JSP程序

复选框 checkbox 可以传递一个甚至多个数据。

以下是一个简单的HTML代码,并将代码保存在test.htm文件中:









Google
菜鸟教程

淘宝



以上代码在浏览器访问如下所示:

以下为main.jsp文件代码,用于处理复选框数据:

<%@ page language="java" cOntentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>







从复选框中读取数据



  • Google 是否选中:
    <%= request.getParameter("google")%>


  • 菜鸟教程是否选中:
    <%= request.getParameter("runoob")%>


  • 淘宝是否选中:
    <%= request.getParameter("taobao")%>




通过访问 http://localhost:8080/testjsp/test.html 提交表单数据到 main.jsp 文件,演示 Gif 图如下所示:


读取所有表单参数

以下我们将使用 HttpServletRequest 的 getParameterNames() 来读取所有表单参数,该方法可以取得所有变量的名称,该方法返回一个枚举。

一旦我们有了一个 Enumeration(枚举),我们就可以调用 hasMoreElements() 方法来确定是否还有元素,以及使用nextElement()方法来获得每个参数的名称。

<%@ page language="java" cOntentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>







读取所有表单参数






<%
Enumeration paramNames = request.getParameterNames();
while(paramNames.hasMoreElements()) {
String paramName = (String)paramNames.nextElement();
out.print("\n");
String paramValue = request.getParameter(paramName);
out.println("\n");
}
%>
参数名参数值
" + paramName + " " + paramValue + "


以下是test.htm文件的内容:









Google
菜鸟教程

淘宝



现在我们通过浏览器访问 test.htm 文件提交数据,输出结果如下:

通过访问 http://localhost:8080/testjsp/test.html 提交表单数据到 main.jsp 文件,演示 Gif 图如下所示:

你可以尝试使用以上的JSP代码读取其它对象,如文本框,单选按钮或下拉框等等其他形式的数据。

JSP 过滤器

JSP 和 Servlet 中的过滤器都是 Java 类。

过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息。

可以将一个或多个过滤器附加到一个 Servlet 或一组 Servlet。过滤器也可以附加到 JavaServer Pages (JSP) 文件和 HTML 页面。

过滤器是可用于 Servlet 编程的 Java 类,可以实现以下目的:

  • 在客户端的请求访问后端资源之前,拦截这些请求。
  • 在服务器的响应发送回客户端之前,处理这些响应。

根据规范建议的各种类型的过滤器:

  • 身份验证过滤器(Authentication Filters)。
  • 数据压缩过滤器(Data compression Filters)。
  • 加密过滤器(Encryption Filters)。
  • 触发资源访问事件过滤器。
  • 图像转换过滤器(Image Conversion Filters)。
  • 日志记录和审核过滤器(Logging and Auditing Filters)。
  • MIME-TYPE 链过滤器(MIME-TYPE Chain Filters)。
  • 标记化过滤器(Tokenizing Filters)。
  • XSL/T 过滤器(XSL/T Filters),转换 XML 内容。

过滤器通过 Web 部署描述符(web.xml)中的 XML 标签来声明,然后映射到您的应用程序的部署描述符中的 Servlet 名称或 URL 模式。

当 Web 容器启动 Web 应用程序时,它会为您在部署描述符中声明的每一个过滤器创建一个实例。

Filter 的执行顺序与在 web.xml 配置文件中的配置顺序一致,一般把 Filter 配置在所有的 Servlet 之前。

Servlet 过滤器方法

过滤器是一个实现了 javax.servlet.Filter 接口的 Java 类。javax.servlet.Filter 接口定义了三个方法:

序号方法 & 描述
1public void doFilter (ServletRequest, ServletResponse, FilterChain)
该方法完成实际的过滤操作,当客户端请求方法与过滤器设置匹配的URL时,Servlet 容器将先调用过滤器的 doFilter 方法。FilterChain 用于访问后续过滤器。
2public void init(FilterConfig filterConfig)
web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,读取web.xml配置,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次)。开发人员通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。
3public void destroy()
Servlet容器在销毁过滤器实例前调用该方法,在该方法中释放Servlet过滤器占用的资源。

FilterConfig 使用

Filter 的 init 方法中提供了一个 FilterConfig 对象。

如 web.xml 文件配置如下:


    LogFilter
    com.runoob.test.LogFilter
    
        Site
        菜鸟教程
    

    

 

在 init 方法使用 FilterConfig 对象获取参数:

public void init(FilterConfig config) throws ServletException {
    // 获取初始化参数
    String site = config.getInitParameter("Site");
    // 输出初始化参数
    System.out.println("网站名称: " + site);
}

JSP 过滤器实例

以下是 Servlet 过滤器的实例,将输出网站名称和地址。本实例让您对 Servlet 过滤器有基本的了解,您可以使用相同的概念编写更复杂的过滤器应用程序:

//导入必需的 java 库
import javax.servlet.*;
import java.util.*;
//实现 Filter 类
public class LogFilter implements Filter {
    public void init(FilterConfig config) throws ServletException {
        // 获取初始化参数
        String site = config.getInitParameter("Site");
        // 输出初始化参数
        System.out.println("网站名称: " + site);
    }
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException {
        // 输出站点名称
        System.out.println("站点网址:http://www.runoob.com");
        // 把请求传回过滤链
        chain.doFilter(request,response);
    }
    public void destroy( ){
        /* 在 Filter 实例被 Web 容器从服务移除之前调用 */
    }
}

DisplayHeader.java 文件代码如下:

//导入必需的 java 库
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/DisplayHeader")
//扩展 HttpServlet 类
public class DisplayHeader extends HttpServlet {
    // 处理 GET 方法请求的方法
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        // 设置响应内容类型
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String title = "HTTP Header 请求实例 - 菜鸟教程实例";
        String docType =
            " \n";
            out.println(docType +
            "\n" +
            "\n"+
            "\n" +
            "

" + title + "

\n" +
            "\n" +
            "\n" +
            "\n"+
            "\n");
        Enumeration headerNames = request.getHeaderNames();
        while(headerNames.hasMoreElements()) {
            String paramName = (String)headerNames.nextElement();
            out.print("\n");
            String paramValue = request.getHeader(paramName);
            out.println("\n");
        }
        out.println("
Header 名称Header 值
" + paramName + " " + paramValue + "
\n");
    }
    // 处理 POST 方法请求的方法
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

Web.xml 中的 Servlet 过滤器映射(Servlet Filter Mapping)

定义过滤器,然后映射到一个 URL 或 Servlet,这与定义 Servlet,然后映射到一个 URL 模式方式大致相同。在部署描述符文件 web.xml 中为 filter 标签创建下面的条目:




LogFilter
com.runoob.test.LogFilter

Site
菜鸟教程



LogFilter
/*



DisplayHeader

com.runoob.test.DisplayHeader


DisplayHeader

/TomcatTest/DisplayHeader

上述过滤器适用于所有的 Servlet,因为我们在配置中指定 /* 。如果您只想在少数的 Servlet 上应用过滤器,您可以指定一个特定的 Servlet 路径。

现在试着以常用的方式调用任何 Servlet,您将会看到在 Web 服务器中生成的日志。您也可以使用 Log4J 记录器来把上面的日志记录到一个单独的文件中。

接下来我们访问这个实例地址 http://localhost:8080/TomcatTest/DisplayHeader, 然后在控制台看下输出内容,如下所示:

使用多个过滤器

Web 应用程序可以根据特定的目的定义若干个不同的过滤器。假设您定义了两个过滤器 AuthenFilter 和 LogFilter。您需要创建一个如下所述的不同的映射,其余的处理与上述所讲解的大致相同:


LogFilter
com.runoob.test.LogFilter

     test-param
     Initialization Paramter



AuthenFilter
com.runoob.test.AuthenFilter

     test-param
     Initialization Paramter



LogFilter
/*


AuthenFilter
/*

过滤器的应用顺序

web.xml 中的 filter-mapping 元素的顺序决定了 Web 容器应用过滤器到 Servlet 的顺序。若要反转过滤器的顺序,您只需要在 web.xml 文件中反转 filter-mapping 元素即可。

例如,上面的实例将先应用 LogFilter,然后再应用 AuthenFilter,但是下面的实例将颠倒这个顺序:


AuthenFilter
/*


LogFilter
/*


web.xml配置各节点说明

  • 指定一个过滤器。
    • 用于为过滤器指定一个名字,该元素的内容不能为空。
    • 元素用于指定过滤器的完整的限定类名。
    • 元素用于为过滤器指定初始化参数,它的子元素指定参数的名字,指定参数的值。
    • 在过滤器中,可以使用FilterConfig接口对象来访问初始化参数。
  • 元素用于设置一个 Filter 所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet 名称和资源访问的请求路径
    • 子元素用于设置filter的注册名称。该值必须是在元素中声明过的过滤器的名字
    • 设置 filter 所拦截的请求路径(过滤器关联的URL样式)
  • 指定过滤器所拦截的Servlet名称。
  • 指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARDERROR之一,默认REQUEST。用户可以设置多个子元素用来指定 Filter 对资源的多种调用方式进行拦截。
  • 子元素可以设置的值及其意义
    • REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
    • INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
    • FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
    • ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
JSP COOKIE 处理

COOKIE 是存储在客户机的文本文件,它们保存了大量轨迹信息。在 Servlet 技术基础上,JSP 显然能够提供对 HTTP COOKIE 的支持。

通常有三个步骤来识别回头客:

  • 服务器脚本发送一系列 COOKIE 至浏览器。比如名字,年龄,ID 号码等等。
  • 浏览器在本地机中存储这些信息,以备不时之需。
  • 当下一次浏览器发送任何请求至服务器时,它会同时将这些 COOKIE 信息发送给服务器,然后服务器使用这些信息来识别用户或者干些其它事情。

本章节将会传授您如何去设置或重设 COOKIE 的方法,还有如何访问它们及如何删除它们。

JSP COOKIE 处理需要对中文进行编码与解码,方法如下:

String str = java.net.URLEncoder.encode("中文", "UTF-8"); //编码
String str = java.net.URLDecoder.decode("编码后的字符串","UTF-8"); // 解码


COOKIE 剖析

COOKIE 通常在 HTTP 信息头中设置(虽然 Javascript 能够直接在浏览器中设置 COOKIE)。在 JSP 中,设置一个 COOKIE 需要发送如下的信息头给服务器:

HTTP/1.1 200 OK
Date: Fri, 04 Feb 2015 21:03:38 GMT
Server: Apache/1.3.9 (UNIX) PHP/4.0b3
Set-COOKIE: name=runoob; expires=Friday, 04-Feb-17 22:03:38 GMT;
path=/; domain=runoob.com
Connection: close
Content-Type: text/html

正如您所见,Set-COOKIE 信息头包含一个键值对,一个 GMT(格林尼治标准)时间,一个路径,一个域名。键值对会被编码为URL。有效期域是个指令,告诉浏览器在什么时候之后就可以清除这个 COOKIE。

如果浏览器被配置成可存储 COOKIE,那么它将会保存这些信息直到过期。如果用户访问的任何页面匹配了 COOKIE 中的路径和域名,那么浏览器将会重新将这个 COOKIE 发回给服务器。浏览器端的信息头长得就像下面这样:

GET / HTTP/1.0
Connection: Keep-Alive
User-Agent: Mozilla/4.6 (X11; I; Linux 2.2.6-15apmac ppc)
Host: zink.demon.co.uk:1126
Accept: image/gif, */*
Accept-Encoding: gzip
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8
COOKIE: name=xyz

JSP 脚本通过 request 对象中的 getCOOKIEs() 方法来访问这些 COOKIE,这个方法会返回一个 COOKIE 对象的数组。


Servlet COOKIE 方法

下表列出了 COOKIE 对象中常用的方法:

序号方法 & 描述
1public void setDomain(String pattern)

 

设置 COOKIE 的域名,比如 runoob.com
2public String getDomain()

 

获取 COOKIE 的域名,比如 runoob.com
3public void setMaxAge(int expiry)

 

设置 COOKIE 有效期,以秒为单位,默认有效期为当前session的存活时间
4public int getMaxAge()

 

获取 COOKIE 有效期,以秒为单位,默认为-1 ,表明COOKIE会活到浏览器关闭为止
5public String getName()

 

返回 COOKIE 的名称,名称创建后将不能被修改
6public void setValue(String newValue)

 

设置 COOKIE 的值
7public String getValue()

 

获取COOKIE的值
8public void setPath(String uri)

 

设置 COOKIE 的路径,默认为当前页面目录下的所有 URL,还有此目录下的所有子目录
9public String getPath()

 

获取 COOKIE 的路径
10public void setSecure(boolean flag)

 

指明 COOKIE 是否要加密传输
11public void setComment(String purpose)

 

设置注释描述 COOKIE 的目的。当浏览器将 COOKIE 展现给用户时,注释将会变得非常有用
12public String getComment()

 

返回描述 COOKIE 目的的注释,若没有则返回 null

使用 JSP 设置 COOKIE

使用 JSP 设置 COOKIE 包含三个步骤:

(1)创建一个 COOKIE 对象: 调用 COOKIE 的构造函数,使用一个 COOKIE 名称和值做参数,它们都是字符串。

COOKIE COOKIE = new COOKIE("key","value");

请务必牢记,名称和值中都不能包含空格或者如下的字符:

[ ] ( ) = , " / ? @ : ;

(2) 设置有效期:调用 setMaxAge() 函数表明 COOKIE 在多长时间(以秒为单位)内有效。下面的操作将有效期设为了 24 小时。

COOKIE.setMaxAge(60*60*24);

(3) 将 COOKIE 发送至 HTTP 响应头中:调用 response.addCOOKIE() 函数来向 HTTP 响应头中添加 COOKIE。

response.addCOOKIE(COOKIE);


实例演示

main.jsp 文件代码如下所示:

<%@ page language="java" cOntentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.net.*" %>
<%
// 编码,解决中文乱码
String str = URLEncoder.encode(request.getParameter("name"),"utf-8");
// 设置 name 和 url COOKIE
COOKIE name = new COOKIE("name",
         str);
COOKIE url = new COOKIE("url",
             request.getParameter("url"));
// 设置COOKIE过期时间为24小时。
name.setMaxAge(60*60*24);
url.setMaxAge(60*60*24);
// 在响应头部添加COOKIE
response.addCOOKIE( name );
response.addCOOKIE( url );
%>





设置 COOKIE



  • 网站名:
    <%= request.getParameter("name")%>


  • 网址:
    <%= request.getParameter("url")%>




以下是一个简单的 HTML 表单通过 GET 方法将客户端数据提交到 main.jsp 文件中,并设置 COOKIE:









站点名:


网址:



将以上 HTML 代码保存到 test.htm 文件中。

将该文件放置于当前 jsp 项目的 WebContent 目录下(与 main.jsp 同一个目录)。

通过访问 http://localhost:8080/testjsp/test.html 提交表单数据到 main.jsp 文件,演示 Gif 图如下所示:

试着输入 "站点名" 和 "网址",然后点击提交按钮,它将会在您的屏幕中显示 "站点名" 和 "网址",并且设置 "站点名" 和 "网址" 的两个 COOKIE。


使用 JSP 读取 COOKIE

想要读取 COOKIE,您就需要调用 request.getCOOKIEs() 方法来获得一个 javax.servlet.http.COOKIE 对象的数组,然后遍历这个数组,使用 getName() 方法和 getValue() 方法来获取每一个 COOKIE 的名称和值。

让我们来读取上个例子中的COOKIE, 以下为 COOKIE.jsp 文件代码:

<%@ page language="java" cOntentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.net.*" %>







<%
COOKIE COOKIE = null;
COOKIE[] COOKIEs = null;
// 获取 COOKIEs 的数据,是一个数组
COOKIEs = request.getCOOKIEs();
if( COOKIEs != null ){
out.println("

查找 COOKIE 名与值

");
for (int i = 0; i COOKIE = COOKIEs[i];

out.print("参数名 : " + COOKIE.getName());
out.print("
");
out.print("参数值: " + URLDecoder.decode(COOKIE.getValue(), "utf-8") +"
");
out.print("------------------------------------
");
}
}else{
out.println("

没有发现 COOKIE

");
}
%>

浏览器访问后,输出结果为:


使用 JSP 删除 COOKIE

删除 COOKIE 非常简单。如果您想要删除一个 COOKIE,按照下面给的步骤来做就行了:

  • 获取一个已经存在的 COOKIE 然后存储在 COOKIE 对象中。
  • 将 COOKIE 的有效期设置为 0。
  • 将这个 COOKIE 重新添加进响应头中。

实例演示

下面的程序删除一个名为 "name" 的 COOKIE,当您第二次运行 COOKIE.jsp时,name 将会为 null。

<%@ page language="java" cOntentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.net.*" %>







<%
COOKIE COOKIE = null;
COOKIE[] COOKIEs = null;
// 获取当前域名下的COOKIEs,是一个数组
COOKIEs = request.getCOOKIEs();
if( COOKIEs != null ){
     out.println("

查找 COOKIE 名与值

");
for (int i = 0; i COOKIE = COOKIEs[i];
if((COOKIE.getName( )).compareTo("name") == 0 ){
COOKIE.setMaxAge(0);
response.addCOOKIE(COOKIE);
out.print("删除 COOKIE: " +
COOKIE.getName( ) + "
");
}
out.print("参数名 : " + COOKIE.getName());
out.print("
");
out.print("参数值: " + URLDecoder.decode(COOKIE.getValue(), "utf-8") +"
");
out.print("------------------------------------
");
}
}else{
     out.println("

没有发现 COOKIE

");
}
%>

通过浏览器访问,输出结果为:

 

再次访问 http://localhost:8080/testjsp/COOKIE.jsp,将会得到如下结果:

 

可以看到名为 "name" 的 COOKIE 已经不见了。

您也可以手动在浏览器中删除 COOKIE。IE 浏览器通过点击 Tools 菜单项,然后选择 Internet Options,点击 Delete COOKIEs,就能删除所有 COOKIE 。

JSP Session

HTTP是无状态协议,这意味着每次客户端检索网页时,都要单独打开一个服务器连接,因此服务器不会记录下先前客户端请求的任何信息。

有三种方法来维持客户端与服务器的会话:


COOKIEs

网络服务器可以指定一个唯一的session ID作为COOKIE来代表每个客户端,用来识别这个客户端接下来的请求。

这可能不是一种有效的方式,因为很多时候浏览器并不一定支持COOKIE,所以我们不建议使用这种方法来维持会话。


隐藏表单域

一个网络服务器可以发送一个隐藏的HTML表单域和一个唯一的session ID,就像下面这样:

这个条目意味着,当表单被提交时,指定的名称和值将会自动包含在GET或POST数据中。每当浏览器发送一个请求,session_id的值就可以用来保存不同浏览器的轨迹。

这种方式可能是一种有效的方式,但点击标签中的超链接时不会产生表单提交事件,因此隐藏表单域也不支持通用会话跟踪。


重写URL

您可以在每个URL后面添加一些额外的数据来区分会话,服务器能够根据这些数据来关联session标识符。

举例来说,http://w3cschool.cc/file.htm;sessiOnid=12345, session标识符为sessiOnid=12345,服务器可以用这个数据来识别客户端。

相比而言,重写URL是更好的方式来,就算浏览器不支持COOKIEs也能工作,但缺点是您必须为每个URL动态指定session ID,就算这是个简单的HTML页面。


session对象

除了以上几种方法外,JSP利用servlet提供的HttpSession接口来识别一个用户,存储这个用户的所有访问信息。

默认情况下,JSP允许会话跟踪,一个新的HttpSession对象将会自动地为新的客户端实例化。禁止会话跟踪需要显式地关掉它,通过将page指令中session属性值设为false来实现,就像下面这样:

<%@ page session="false" %>

JSP引擎将隐含的session对象暴露给开发者。由于提供了session对象,开发者就可以方便地存储或检索数据。

下表列出了session对象的一些重要方法:

S.N.方法 & 描述
1public Object getAttribute(String name)

 

返回session对象中与指定名称绑定的对象,如果不存在则返回null
2public Enumeration getAttributeNames()

 

返回session对象中所有的对象名称
3public long getCreationTime()

 

返回session对象被创建的时间, 以毫秒为单位,从1970年1月1号凌晨开始算起
4public String getId()

 

返回session对象的ID
5public long getLastAccessedTime()

 

返回客户端最后访问的时间,以毫秒为单位,从1970年1月1号凌晨开始算起
6public int getMaxInactiveInterval()

 

返回最大时间间隔,以秒为单位,servlet 容器将会在这段时间内保持会话打开
7public void invalidate()

 

将session无效化,解绑任何与该session绑定的对象
8public boolean isNew()

 

返回是否为一个新的客户端,或者客户端是否拒绝加入session
9public void removeAttribute(String name)

 

移除session中指定名称的对象
10public void setAttribute(String name, Object value) 

 

使用指定的名称和值来产生一个对象并绑定到session中
11public void setMaxInactiveInterval(int interval)

 

用来指定时间,以秒为单位,servlet容器将会在这段时间内保持会话有效

JSP Session应用

这个例子描述了如何使用HttpSession对象来获取创建时间和最后一次访问时间。我们将会为request对象关联一个新的session对象,如果这个对象尚未存在的话。

<%@ page language="java" cOntentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.io.*,java.util.*" %>
<%
// 获取session创建时间
Date createTime = new Date(session.getCreationTime());
// 获取最后访问页面的时间
Date lastAccessTime = new Date(session.getLastAccessedTime());
String title = "再次访问菜鸟教程实例";
Integer visitCount = new Integer(0);
String visitCountKey = new String("visitCount");
String userIDKey = new String("userID");
String userID = new String("ABCD");
// 检测网页是否有新的访问用户
if (session.isNew()){
title = "访问菜鸟教程实例";
session.setAttribute(userIDKey, userID);
session.setAttribute(visitCountKey, visitCount);
} else {
     visitCount = (Integer)session.getAttribute(visitCountKey);
     visitCount += 1;
     userID = (String)session.getAttribute(userIDKey);
     session.setAttribute(visitCountKey, visitCount);
}
%>





Session 跟踪



























Session 信息
id <% out.print( session.getId()); %>
创建时间 <% out.print(createTime); %>
最后访问时间 <% out.print(lastAccessTime); %>
用户 ID <% out.print(userID); %>
访问次数 <% out.print(visitCount); %>


试着访问 http://localhost:8080/testjsp/main.jsp ,第一次运行时将会得到如下结果:

再次访问,将会得到如下结果:


删除Session数据

当处理完一个用户的会话数据后,您可以有如下选择:

  • 移除一个特定的属性:

    调用public void removeAttribute(String name)  方法来移除指定的属性。

  • 删除整个会话:

    调用public void invalidate() 方法来使整个session无效。

  • 设置会话有效期:

    调用 public void setMaxInactiveInterval(int interval)  方法来设置session超时。

  • 登出用户:

    支持servlet2.4版本的服务器,可以调用 logout()方法来登出用户,并且使所有相关的session无效。

  • 配置web.xml文件:

    如果使用的是Tomcat,可以向下面这样配置web.xml文件:


15

超时以分钟为单位,Tomcat中的默认的超时时间是30分钟。

Servlet中的getMaxInactiveInterval( ) 方法以秒为单位返回超时时间。如果在web.xml中配置的是15分钟,则getMaxInactiveInterval( ) 方法将会返回900。

JSP 文件上传

JSP 可以与 HTML form 标签一起使用,来允许用户上传文件到服务器。上传的文件可以是文本文件或图像文件或任何文档。

本章节我们使用 Servlet 来处理文件上传,使用到的文件有:

  • upload.jsp : 文件上传表单。
  • message.jsp : 上传成功后跳转页面。
  • UploadServlet.java : 上传处理 Servlet。
  • 需要引入的 jar 文件:commons-fileupload-1.3.2、commons-io-2.5.jar。

结构图如下所示:

接下来我们详细介绍。


创建一个文件上传表单

下面的 HTML 代码创建了一个文件上传表单。以下几点需要注意:

  • 表单 method 属性应该设置为 POST 方法,不能使用 GET 方法。
  • 表单 enctype 属性应该设置为 multipart/form-data.
  • 表单 action 属性应该设置为在后端服务器上处理文件上传的 Servlet 文件。下面的实例使用了 UploadServlet Servlet 来上传文件。
  • 上传单个文件,您应该使用单个带有属性 type="file" 的 标签。为了允许多个文件上传,请包含多个 name 属性值不同的 input 标签。输入标签具有不同的名称属性的值。浏览器会为每个 input 标签关联一个浏览按钮。

upload.jsp 文件代码如下:

<%@ page language="java" cOntentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
"http://www.w3.org/TR/html4/loose.dtd">






文件上传实例 - 菜鸟教程



    选择一个文件:
    
    


    


编写后台 Servlet

以下是 UploadServlet 的源代码,同于处理文件上传,在这之前我们先确保依赖包已经引入到项目的 WEB-INF/lib 目录下:

  • 下面的实例依赖于 FileUpload,所以一定要确保在您的 classpath 中有最新版本的 commons-fileupload.x.x.jar 文件。可以从 http://commons.apache.org/proper/commons-fileupload/ 下载。
  • FileUpload 依赖于 Commons IO,所以一定要确保在您的 classpath 中有最新版本的 commons-io-x.x.jar 文件。可以从 http://commons.apache.org/proper/commons-io/ 下载。

你可以直接下载本站提供的两个依赖包:

  • commons-fileupload-1.3.2.jar
  • commons-io-2.5.jar

UploadServlet 的源代码 如下所示:

package com.runoob.test;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

/**
* Servlet implementation class UploadServlet
*/
@WebServlet("/UploadServlet")
public class UploadServlet extends HttpServlet {
private static final long serialVersiOnUID= 1L;

// 上传文件存储目录
private static final String UPLOAD_DIRECTORY = "upload";

// 上传配置
private static final int MEMORY_THRESHOLD = 1024 * 1024 * 3; // 3MB
private static final int MAX_FILE_SIZE = 1024 * 1024 * 40; // 40MB
private static final int MAX_REQUEST_SIZE = 1024 * 1024 * 50; // 50MB

/**
* 上传数据及保存文件
*/
protected void doPost(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
        // 检测是否为多媒体上传
        if (!ServletFileUpload.isMultipartContent(request)) {
         // 如果不是则停止
         PrintWriter writer = response.getWriter();
         writer.println("Error: 表单必须包含 enctype=multipart/form-data");
         writer.flush();
         return;
        }

// 配置上传参数
DiskFileItemFactory factory = new DiskFileItemFactory();
// 设置内存临界值 - 超过后将产生临时文件并存储于临时目录中
factory.setSizeThreshold(MEMORY_THRESHOLD);
// 设置临时存储目录
factory.setRepository(new File(System.getProperty("java.io.tmpdir")));

ServletFileUpload upload = new ServletFileUpload(factory);

// 设置最大文件上传值
upload.setFileSizeMax(MAX_FILE_SIZE);

// 设置最大请求值 (包含文件和表单数据)
upload.setSizeMax(MAX_REQUEST_SIZE);

// 中文处理
upload.setHeaderEncoding("UTF-8");
// 构造临时路径来存储上传的文件
// 这个路径相对当前应用的目录
String uploadPath = getServletContext().getRealPath("/") + File.separator + UPLOAD_DIRECTORY;


// 如果目录不存在则创建
File uploadDir = new File(uploadPath);
if (!uploadDir.exists()) {
uploadDir.mkdir();
}

try {
// 解析请求的内容提取文件数据
@SuppressWarnings("unchecked")
List formItems = upload.parseRequest(request);

if (formItems != null && formItems.size() > 0) {
// 迭代表单数据
for (FileItem item : formItems) {
// 处理不在表单中的字段
if (!item.isFormField()) {
String fileName = new File(item.getName()).getName();
String filePath = uploadPath + File.separator + fileName;
File storeFile = new File(filePath);
// 在控制台输出文件的上传路径
System.out.println(filePath);
// 保存文件到硬盘
item.write(storeFile);
request.setAttribute("message",
"文件上传成功!");
}
}
}
} catch (Exception ex) {
request.setAttribute("message",
"错误信息: " + ex.getMessage());
}
// 跳转到 message.jsp
getServletContext().getRequestDispatcher("/message.jsp").forward(
request, response);
}
}

message.jsp 文件代码如下:

<%@ page language="java" cOntentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
"http://www.w3.org/TR/html4/loose.dtd">







${message}




编译和运行 Servlet

编译上面的 Servlet UploadServlet,并在 web.xml 文件中创建所需的条目,如下所示:


xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">

UploadServlet
UploadServlet
com.runoob.test.UploadServlet



UploadServlet
/TomcatTest/UploadServlet

现在尝试使用您在上面创建的 HTML 表单来上传文件。当您在浏览器中访问:http://localhost:8080/TomcatTest/upload.jsp ,演示如下所示:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


推荐阅读
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 阿里云虚拟主机安装多个织梦系统的方法
    本文介绍了在阿里云虚拟主机上安装多个织梦系统的方法。通过创建不同名称的文件夹并将不同的域名解析到对应的目录,可以实现多个系统的安装。在安装过程中需要注意修改数据库前缀,并在系统设置中还原数据库。同时还介绍了阿里云虚拟主机二级域名绑定二级目录和域名重定向的用法。 ... [详细]
  • 如何提高PHP编程技能及推荐高级教程
    本文介绍了如何提高PHP编程技能的方法,推荐了一些高级教程。学习任何一种编程语言都需要长期的坚持和不懈的努力,本文提醒读者要有足够的耐心和时间投入。通过实践操作学习,可以更好地理解和掌握PHP语言的特异性,特别是单引号和双引号的用法。同时,本文也指出了只走马观花看整体而不深入学习的学习方式无法真正掌握这门语言,建议读者要从整体来考虑局部,培养大局观。最后,本文提醒读者完成一个像模像样的网站需要付出更多的努力和实践。 ... [详细]
  • MVC设计模式的介绍和演化过程
    本文介绍了MVC设计模式的基本概念和原理,以及在实际项目中的演化过程。通过分离视图、模型和控制器,实现了代码的解耦和重用,提高了项目的可维护性和可扩展性。详细讲解了分离视图、分离模型和分离控制器的具体步骤和规则,以及它们在项目中的应用。同时,还介绍了基础模型的封装和控制器的命名规则。该文章适合对MVC设计模式感兴趣的读者阅读和学习。 ... [详细]
  • 本文介绍了一个免费的asp.net控件,该控件具备数据显示、录入、更新、删除等功能。它比datagrid更易用、更实用,同时具备多种功能,例如属性设置、数据排序、字段类型格式化显示、密码字段支持、图像字段上传和生成缩略图等。此外,它还提供了数据验证、日期选择器、数字选择器等功能,以及防止注入攻击、非本页提交和自动分页技术等安全性和性能优化功能。最后,该控件还支持字段值合计和数据导出功能。总之,该控件功能强大且免费,适用于asp.net开发。 ... [详细]
  • Java和JavaScript是什么关系?java跟javaScript都是编程语言,只是java跟javaScript没有什么太大关系,一个是脚本语言(前端语言),一个是面向对象 ... [详细]
  • .NetCoreWebApi生成Swagger接口文档的使用方法
    本文介绍了使用.NetCoreWebApi生成Swagger接口文档的方法,并详细说明了Swagger的定义和功能。通过使用Swagger,可以实现接口和服务的可视化,方便测试人员进行接口测试。同时,还提供了Github链接和具体的步骤,包括创建WebApi工程、引入swagger的包、配置XML文档文件和跨域处理。通过本文,读者可以了解到如何使用Swagger生成接口文档,并加深对Swagger的理解。 ... [详细]
  • 【重识云原生】第四章云网络4.8.3.2节——Open vSwitch工作原理详解
    2OpenvSwitch架构2.1OVS整体架构ovs-vswitchd:守护程序,实现交换功能,和Linux内核兼容模块一起,实现基于流的交换flow-basedswitchin ... [详细]
  • 渗透测试基础bypass绕过阻挡我们的WAF(下)
    渗透测试基础-bypass ... [详细]
  • 本文介绍了在Python3中如何使用选择文件对话框的格式打开和保存图片的方法。通过使用tkinter库中的filedialog模块的asksaveasfilename和askopenfilename函数,可以方便地选择要打开或保存的图片文件,并进行相关操作。具体的代码示例和操作步骤也被提供。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • PHP输出缓冲控制Output Control系列函数详解【PHP】
    后端开发|php教程PHP,输出缓冲,Output,Control后端开发-php教程概述全景网页源码,vscode如何打开c,ubuntu强制解锁,sts启动tomcat慢,sq ... [详细]
author-avatar
jueduiliu
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有