2013年3月23日星期六

Servlet获取表单提交的内容

获取表单对象的值
工程名:ServletStudy
表单文件:login.jsp
Servlet文件:LoginServlet.java
配置文件:web.xml

下面对是这几个文件的代码:
login.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
   
    <title>My JSP 'login.jsp' starting page</title>
   
   <meta http-equiv="pragma" content="no-cache">
   <meta http-equiv="cache-control" content="no-cache">
   <meta http-equiv="expires" content="0">   
   <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
   <meta http-equiv="description" content="This is my page">
   <!--
   <link rel="stylesheet" type="text/css" href="styles.css">
   -->

  </head>

  <body>
   <form action="/ServletStudy/LoginServlet">
      userName:&nbsp;<input name="userName" type="text"/><br/>
      password: &nbsp;<input name="password" type="password"/><br/>
     
      <input type="submit" value="submit"/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<input type="reset" value="reset"/>
   </form>
  </body>
</html>

LoginServlet.java
package com;

import java.io.IOException;
import java.io.PrintWriter;

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

@SuppressWarnings("serial")
public class LoginServlet extends HttpServlet
{
  
   protected void doGet(HttpServletRequest req,HttpServletResponse resp)
      throws ServletException, IOException
      {
        String username = req.getParameter("userName");
        String password = req.getParameter("password");
     
        resp.setContentType("text/html");
       
        PrintWriter out = resp.getWriter();
       
        out.println("<html><head><title>Login Result</title></head");
       
        out.println("<body> username:"+username+"<br>");
       
        out.println("password:"+password+"<br></body></html>");
       
        out.flush();
      }

}

web.xml
在二级标签中添加以下代码:
<servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>com.LoginServlet</servlet-class>
  </servlet>
<servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/LoginServlet</url-pattern>
  </servlet-mapping>

说明:
1.<form>标签中的action 值为 web.xml中的<url-pattern></url-pattern>中的值。再加上Servlet类名,如这里的是
/ServletStudy/LoginServlet
提交的方式默认为get方式,本例中即是以get方式提交的,这里没有对中文问题进行处理。但建议一般使用post方式提交表单。
2. String username = req.getParameter("userName");
这里的参数值“userName”要与<input name="userName" type="text"/>中的name属性值相同

下面是使用doPost提交方式,关键部分代码为:
protected void doPost(HttpServletRequest req,HttpServletResponse resp)
   throws ServletException, IOException
   {
      req.setCharacterEncoding("utf-8");
      String username = req.getParameter("userName");
      String password = req.getParameter("password");
  
      resp.setContentType("text/html");
      resp.setCharacterEncoding("utf-8"); //设置返回给客户端的文本格式,可解决文字编码格式不统一的问题
      PrintWriter out = resp.getWriter();   
      out.println("<html><head><title>Login Result</title></head");
      out.println("<body> username:"+username+"<br>"); 
      out.println("password:"+password+"<br></body></html>");
      out.flush();
   }

若使用doPost方式响应客户,则要将<form>表单中的method的值改为post

servlet编写和配置

在实际的开发中,我们经常需定义一种自己的请求,比如对所有“/test.do”的请求都要被拦截进行统一处理,那么可以自己编写一个servlet来拦截这种请求。
     编写servlet的时候,需要继承类 javax.servlet.http.HttpServlet(需要下载servlet.jar包)。我们可能经常使用的方法如下:
     init(ServletConfig config) : servlet的初始化方法
     service : servlet处理请求的总入口,然后根据不同的请求方式分别调用不同的方法,Get时调用doGet;Post方式时调用doPost。
     doGet  : 处理提交方式为Get的请求
     doPost : 处理提交方式为Post的请求
     destroy: 销毁servlet时调用的方式,servlet是单例的模式,所以只有关闭应用服务器(如:Tomcat)时才会关闭。

 对于处理不同的请求,我们可以在doPost方法中调用doGet方法,在doGet方法中对请求进行统一处理。我们面试中经常会被问到 doGet和doPost的区别,通过本文你可以看出两者的区别。Get方式传递的参数最大好像是225个字符,但是Post方式采用body来传递的, 没有长度限制的。

一、servlet代码示例

/**
 *
 */
package com.test.javax.servlet;
import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * @author rey
 *
 */
public class TestServlet extends HttpServlet {
 /**
  * 构造函数
  */
 public TestServlet() {
  super();
  System.out.println("TestServlet的构造函数...");
 }
 /*
  * (non-Javadoc)
  *
  * @see
  * javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest
  * , javax.servlet.http.HttpServletResponse)
  */
 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
   throws ServletException, IOException {
  System.out.println("doGet 开始...");
  //super.doGet(req, resp);  //不能调用父类中的方法
  resp.getWriter().write("Hello doGet!");
  resp.flushBuffer();
  System.out.println("doGet 结束...");
 }
 /*
  * (non-Javadoc)
  *
  * @see
  * javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest
  * , javax.servlet.http.HttpServletResponse)
  */
 @Override
 protected void doPost(HttpServletRequest req, HttpServletResponse resp)
   throws ServletException, IOException {
  System.out.println("doPost 开始...");
  //super.doPost(req, resp);  //不能调用父类中的方法
  resp.getWriter().write("Hello doPost!");
  resp.flushBuffer();
  System.out.println("doPost 结束...");
 }
 /*
  * (non-Javadoc)
  *
  * @see javax.servlet.http.HttpServlet#service(javax.servlet.ServletRequest,
  * javax.servlet.ServletResponse)
  */
 @Override
 public void service(ServletRequest _request, ServletResponse _response)
   throws ServletException, IOException {
  System.out.println("service 开始...");
  super.service(_request, _response);
  _response.getWriter().write("Hello service!");
  System.out.println("service 结束...");
 }
 /*
  * (non-Javadoc)
  *
  * @see javax.servlet.GenericServlet#destroy()
  */
 @Override
 public void destroy() {
  System.out.println("开始销毁servlet[destroy]...");
  super.destroy();
 }
 /*
  * (non-Javadoc)
  *
  * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig)
  */
 @Override
 public void init(ServletConfig config) throws ServletException {
  super.init(config);
  System.out.println("开始初始化 TestServlet...");
 }
}
二、servlet配置
<!-- start servlet begin -->
 <servlet>
  <servlet-name>TestServlet</servlet-name>
  <servlet-class>com.test.javax.servlet.TestServlet</servlet-class>
 </servlet>
 <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/test.do</url-pattern>
    </servlet-mapping>
<!-- start servlet end -->

三、测试html代码
<html>
<head>
 <title>测试servlet</title>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
 <form name="frm_data" id="frm_data" method="POST" action="./test.do">
  <input type="hidden" name="UserName" value="wuguowei">
  <input type="hidden" name="UserPassword" value="123455">
  <input type="hidden" name="Chinese" value="1中国2">
  <input type="submit" value="提交">
 </form>
</body>
</html>

四、测试结果
  1)Post方式结果:
       service 开始...
       doPost 开始...
       doPost 结束...
       service 结束...
  2)Get方式结果:
       service 开始...
       doGet 开始...
       doGet 结束...
       service 结束...

编写Servlet的三种方法

有谁说了编写Servlet必须继承自HttpServlet类,必须实现doGet()或者doPost() ,难道实现Servlet接口就不行了吗?
其实编写Servlet主要有三种方法,一是实现Servlet接口,二是继承抽象类GenericServlet,三是继承HttpServlet类。下面分别用这三种方法去实现Servlet:
(一)要从实现Servlet接口来编写Servlet是比较麻烦的,因为必须实现Servlet接口中的所有方法,Servlet接口主要定义了五个方法,它们分别为:
(1)void init(ServletConfig config) throws ServletException
(2)ServletConfig getServletConfig()
(3)void service(ServletRequest req,ervletResponse res) throws ServletException,IOException
(4)String getServletInfo()
(5)void destroy()
下面用实现Servlet接口的方法编写Servlet:
  1. import javax.servlet.*;  
  2. import java.io.*;  
  3. public class TestServlet implements Servlet{  
  4.     public void init(ServletConfig config) throws ServletException{  
  5.         System.out.println("init");  
  6.         }  
  7.     public ServletConfig getServletConfig(){  
  8.         reture null;  
  9.         }  
  10.     public void service(ServletRequest req,ServletResponse res)   
  11.         throws ServletException,IOException{  
  12.             //这里可以实现请求后要做的内容  
  13.             PrintWriter out = response.getWriter();  
  14.       out.println("Hello World!");  
  15.  
  16.             }  
  17.     public String getServletInfo(){  
  18.         return null;  
  19.         }  
  20.     public void destroy(){  
  21.         System.out.println("destory");  
  22.         }  
  23.     }  
(二)继承抽象类GenericServlet编写Serlvet,这个相对比实现Servlet接口要容易一点,GenericServlet类 中只有一个抽象方法,即service(ServletRequest req, ServletResponse res),只要实现这个方法就行了,下面看例子:
  1. import javax.servlet.*;  
  2. import java.io.IOException;  
  3.  
  4. public TestGenericServlet extends GenericServlet{  
  5.     public abstract void service(ServletRequest req,ServletResponse res)  
  6.                       throws ServletException,IOException{  
  7.      PrintWriter out = response.getWriter();  
  8.      out.println("Hello World!");                       
  9.      }  
(3)继承HttpServlet类编写Servlet应该是最容易的,而且是最常见的,我们一般要编写Servlet直接继承这个类就行了,重写doGet()或者doPost()方法即可,下面看例子:
  1. import javax.servlet.http.*;  
  2. import javax.servlet.*;  
  3. import java.io.*;  
  4.  
  5. public TestHttpServlet extends HttpServlet{  
  6.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  7.         throws IOException, ServletException {  
  8.   response.setContentType("text/html;charset=gb2312");  
  9.   PrintWriter out = response.getWriter();  
  10.  
  11.   out.println("<html>");  
  12.   out.println("<head>");  
  13.   out.println("<title>HelloWorld</title>");  
  14.   out.println("</head>");  
  15.   out.println("<body bgcolor=\"white\">");  
  16.   out.println("<hr>");  
  17.   out.println("HelloWorld");  
  18.   out.println("</body></html>");  
  19.  }  
  20.  
  21.  public void doPost(HttpServletRequest request, HttpServletResponse response)  
  22.    throws IOException, ServletException {  
  23.   doGet(request, response);  
  24.  }  
  25.  
  26. }

多种Servlet接口介绍

Servlet接口:
public interface Servlet
它的生命周期由 javax.Servlet.Servlet接口定义。当你在写Servlet的时候必须直接或间接的实现这个接口。一般趋向于间接实现:通过从 javax.Servlet.GenericServlet或javax.Servlet.http.HttpServlet派生。在实现Servlet 接口时必须实现它的五个方法:
1.init():
public void init(ServletConfig config) throws ServletException
一 旦对Servlet实例化后,容器就调用此方法。容器把一个ServletConfig对象传统给此方法,这样Servlet的实例就可以把与容器相关的 配置数据保存起来供以后使用。如果此方法没有正常结束就会抛出一个ServletException。一旦抛出该异常,Servlet就不再执行,而随后 对它的调用会导致容器对它重新载入并再次运行此方法。接口规定对任何Servlet实例,此方法只能被调用一次,在任何请求传递给Servlet之前,此 方法可以在不抛出异常的情况下运行完毕。
2.service():
public void service(ServletRequest req,ServletResponse res) throws ServletException,IOException
只有成功初始化后此方法才能被调用处理用户请求。前一个参数提供访问初始请求数据的方法和字段,后一个提供Servlet构造响应的方法。
3.destroy():
public void destroy()
容器可以在任何时候终止Servlet服务。容器调用此方法前必须给service()线程足够时间来结束执行,因此接口规定当service()正在执行时destroy()不被执行。
4.getServletConfig():
public ServletConfig getServletConfig()
在 Servlet初始化时,容器传递进来一个ServletConfig对象并保存在Servlet实例中,该对象允许访问两项内容:初始化参数和 ServletContext对象,前者通常由容器在文件中指定,允许在运行时向sevrlet传递有关调度信息,后者为Servlet提供有关容器的信 息。此方法可以让Servlet在任何时候获得该对象及配置信息。
5.getServletInfo():
public String getServletInfo()
此方法返回一个String对象,该对象包含Servlet的信息,例如开发者、创建日期、描述信息等。该方法也可用于容器。
GenericServlet类
Public abstract class GenericServlet implants Servlet,ServletConfig,Serializable
此 类提供了Servlet接口的基本实现部分,其service()方法被申明为abstract,因此需要被派生。init(ServletConfig conf)方法把ServletConfig对象存储在一个private transient(私有临时)实例变量里,getServletConfig()方法返回指向本对象的指针,如果你重载此方法,将不能使用 getServletConfig来获得ServletConfig对象,如果确实想重载,记住要包含对super.config的调用。2.1版的 API提供一个重载的没有参数的init()方法。现在在init(ServletConfig)方法结束时有一个对init()的调用,尽管目前它是空 的。2.1版API里面,此类实现了ServletConfig接口,这使得开发者不用获得ServletConfig对象情况下直接调用 ServletConfig的方法,这些方法 是:getInitParameter(),getInitParameterNames(),getServletContext。此类还包含两个写日 志的方法,它们实际上调用的是ServletContext上的对应方法。log(String msg)方法将Servlet的名称和msg参数写到容器的日志中,log(String msg,Throwable cause)除了包含Servlet外还包含一个异常。
HttpServlet类
该类扩展了GenericServlet类并对Servlet接口提供了与HTTP更相关的实现。
service():
protected void service(HttpServletRequest req,HttpServletResponse res) throws ServletException,IOException
public void service(HttpServletRequest req,HttpServletResponse res)throws ServletException,IOException
该 方法作为HTTP请求的分发器,这个方法在任何时候都不能被重载。当请求到来时,service()方法决定请求的类型 (GET,POST,HEAD,OPTIONS,DELETE,PUT,TRACE),并把请求分发给相应的处理方法 (doGet(),doPost(),doHead(),doOptions(),doDelete(),doPut(),doTrace())每个do 方法具有和第一个service()相同的形式。为了响应特定类型的HTTP请求,我们必须重载相应的do方法。如果Servlet收到一个HTTP请求 而你没有重载相应的do方法,它就返回一个说明此方法对本资源不可用的标准HTTP错误。
getLatModified():
protected long getLastModified(HttpServletRequest req)
该方法返回以毫秒为单位的的自GMT时间1970年1月1日0时0分0秒依赖的最近一次修改Servlet的时间,缺省是返回一个负数表示时间未知。当处理GET请求时,调用此方法可以知道Servlet的最近修改时间,服务器就可决定是否把结果从缓存中去掉。
HttpServletRequest接口
public interface HttpServletRequest extends ServletRequest
所有实现此接口的对象(例如从Servlet容器传递的HTTP请求对象)都能让Servlet通过自己的方法访问所有请求的数据。下面是一些用来获取表单数据的基本方法。
getParameter()
public String getParameter(String key)
此方法试图将根据查询串中的关键字定位对应的参数并返回其值。如果有多个值则返回列表中的第一个值。如果请求信息中没有指定参数,则返回null。
getParametervalues():
public String[] getParametervalues(String key)
如果一个参数可以返回多个值,比如复选框集合,则可以用此方法获得对应参数的所有值。如果请求信息中没有指定参数,则返回null。
GetParameterNames():
Public Enumeration getParameterNames()
此方法返回一个Enumeration对象,包含对应请求的所有参数名字列表。
HttpServletResponse接口
public interface HttpServletResponse extends ServletResponse
Servlet容器提供一个实现该接口的对象并通过service()方法将它传递给Servlet。通过此对象及其方法,Servlet可以修改响应头并返回结果。
setContentType():
public void setContentType(String type)
在给调用者发回响应前,必须用此方法来设置HTTP响应的MIME类型。可以是任何有效的MIME类型,当给浏览器返回HTML是就是”text/html”类型。
getWriter():
public PrintWriter getWriter()throws IOException
此方法将返回PrintWriter对象,把Servlet的结果作为文本返回给调用者。PrintWriter对象自动把Java内部的UniCode编码字符转换成正确的编码以使客户端能够阅读。
getOutputStream():
public ServletOutputStream getOutputStream() throws IOException
此方法返回ServletOutputStream对象,它是java.io.OutputStream的一个子类。此对象向客户发送二进制数据。
setHeader():
public void setHeader(String name,String value)
此方法用来设置送回给客户的HTTP响应头。有一些快捷的方法用来改变某些常用的响应头,但有时也需要直接调用此方法。
编译条件
需 要从http://java.sun.com/products/Servlet/ 获得一份JSDK的拷贝,并把Servlet.jar移动到JDK安装目录下的\jre\lib\ext目录下。如果是JDK1.1,则移动到\lib 下,并在CLASSPATH中加入Servlet.jar的绝对路径。
运行条件
需要Apache Jserv,Jrun Servlet Exec,Java Web Server,Weblogic,WebSphere,Tomcat,Resin等Servlet服务器端程序。
简单范例
  1. import java.io.*;  
  2. import javax.servlet.*;  
  3. import javax.servlet.http.*;  
  4. public class HelloWorld extends HttpServlet {  
  5. public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException  
  6. {  
  7. response.setContentType("text/html");  
  8. PrintWriter out = response.getWriter();  
  9. out.println("<html>");  
  10. out.println("<body>");  
  11. out.println("<head>");  
  12. out.println("<title>Hello World!</title>");  
  13. out.println("</head>"); 
1.Servlet 工作流程
用户通过浏览器向Web服务器发送请求
http://localhost:port/path
服务器定位用户请求资源
静态资源:*.html 读取文件内容发送到客户端(HTML应该是不需要用servlet操作,因为它就是静态显示页面,而用
servlet也是产生显示页面,只是这个是含有动态信息的显示页面
动态资源:服务器加载web.xml根据Servlet名字,定位Servlet加载类(WEB-INF/classes),就是servlet类,及类库(WEB-INF/lib/*.jar),即servlet可能用到的类库


通过反射创建Servlet实例(应该服务器实例化servlet类,然后调用servlet方法完成用户的请求信息)
Servlet ser=(Servlet)(Class.forName("servlet类名")).newInstance();


我们写的Servlet一定要实现Servlet接口或继承Servlet的实现类。
ser.service(request,response);


2.Servlet 生命周期的四个阶段:
(1)容器通过反射机制创建Servlet对象,默认第一次请求时才会创建。
(2)调用Servlet对象的init()方法,初始化Servlet信息,init()方法只会在创建后被调用一次。
(3)响应请求,调用service()或是doGet(),doPost()方法来处理请求,这些方法是运行在多线程状态下的。
(4)在长时间没有被调用或是服务器关闭时,会调用destroy()方法来销毁Servlet对象。


3.Session的生命周期 默认是30分钟,自己可以手动修改
session.setMaxInactiveInterval(int interval) --设置session超时时间,以秒为单位

JSP注释

JSP注释
JSP注释用于标注在程序开发过程中的开发提示,它不会输出到客户端。
JSP注释的格式如下:
<%-- 注释内容 --%>
与JSP注释形成对比的是HTML注释,HTML注释的格式是:
<!-- 注释内容 -->
 
HTML的注释可以通过源代码查看到,但JSP的注释是无法通过源代码查看到的。这表明JSP注释不会被发送到客户端。
但有一点值得注意的是HTML注释无法阻止JAVA脚本的执行,如下:
复制代码
<!--
<%System.out.println("hello!");%>
-->
<!--
<%out.println("hello!");%>
-->
复制代码
HTML注释中的JAVA脚本会在服务器端算好,再被传送到客户端,只不过显示不出来而已。
JSP声明
JSP声明用于声明成员变量和方法。在JSP声明中声明成员变量和方法看起来很特别,似乎没有类的存在,只有方法定义和成员变量,方法和成员变量似 乎可以脱离类独立存在。实际上,JSP声明将会转换成Servlet的成员变量或成员方法,因此JSP声明依然符合Java语法。
JSP声明的语法格式如下:
<%! 声明部分 %>
打开多个浏览器,甚至可以在不同的机器上打开浏览器来刷新该页面,将发现所有客户端访问的该JSP声明中定义的值是连续的,即所有客户端共享了同一 个变量。这是因为:JSP页面会编译成一个Servlet类,每个Servlet在容器中只有唯一一个实例;在JSP中声明的变量是成员变量,成员变量只 在创建实例时初始化,该变量的值将一直保存,直到实例销毁。由此我们要时刻禁戒着这个把一个变量声明为SERLET类的成员变量,因为这某些情况下会出现意料之外的事情发生。
JSP声明中独立存在的方法和变量,只是一种假象。

JSP脚本
 JSP脚本的应用非常广泛,通常,Java代码必须通过JSP脚本嵌入HTML代码。因此,所有能在Java程序中执行的代码,都可以通过JSP脚本执行。
JSP脚本将转换成Servlet里 _ jspService方法的可执行性代码而且是放在try中。这意味着在JSP小脚本部分也可以声明变量,但在JSP脚本部分声明的变量是局部变量。
实际上不仅JSP小脚本部分会转换成_ jspService方法里的可执行性代码,JSP页面里的所有静态内容都将由_ jspService方法里输出语句来输出,这就是JSP脚本可以控制JSP页面中静态内容的原因。由于JSP脚本将转换成_ jspService方法里的可执行性代码,而Java语法不允许在方法里定义方法,所以JSP脚本里不能定义方法。

JSP表达式
JSP提供了一种输出表达式值的简单方法,输出表达式值的语法格式如下:
<%=表达式%>
 
看下面的JSP页面,该页面使用输出表达式的方式输出变量和方法返回值。

<%@ page contentType="text/html; charset=gb2312" language="java" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>输出表达式值</TITLE>
</HEAD>
<%!public int count;
  
public String info(){return "hello";}%>
<BODY>
<!-- 使用表达式输出变量值 -->
<%=count++%>
<br>
<!--使用表达式输出方法返回值 -->
<%=info()%>
</BODY>
</HTML>
注意:输出表达式语法后不能有分号

JSP的PAGE指令
page指令,通常位于JSP页面的顶端,一个JSP页面可以使用多条page指令。page指令的语法格式如下:
<%@page
[language="Java"]
[extends="package.class"]
[import="package.class│package.*,…"]
[session="true│false"]
[buffer="none│8kb│size kb"]
[autoFlush="true│false"]
[isThreadSafe="true│false"]
[info="text"]
[errorPage="relativeURL"]
[contentType="mimeType[;charset=characterSet]"│"text/html;charSet=ISO8859-1"]
[isErrorPage="true│false"]
%>

下面依次介绍page指令各属性的意义:
language
声明当前JSP页面使用的脚本语言的种类,因为页面是JSP页面,该属性的值通常都是java,该属性的默认值也是java,所以通常无须设置。
extends指定JSP页面编译所产生的Java类所继承的父类,或所实现的接口。
import:用来导入包。下面几个包是默认自动导入的,不需要显式导入。默认导入的包有:java.lang.*、javax.servlet.*、javax.servlet.jsp.*、javax.servlet.http.*。
session设定这个JSP页面是否需要HTTP Session。
buffer指定输出缓冲区的大小。输出缓冲区的JSP内部对象:out用于缓存JSP页面对客户浏览器的输出,默认值为8kb,可以设置为none,也可以设置为其他的值,单位为kb。
autoFlush当输出缓冲区即将溢出时,是否需要强制输出缓冲区的内容。设置为true时为正常输出;如果设置为false,则会在buffer溢出时产生一个异常。
info设置该JSP程序的信息,也可以看做其说明,可以通过Servlet.getServletInfo()方法获取该值。如果在JSP页面中,可直接调用getServletInfo()方法获取该值,因为JSP页面的实质就是Servlet。
errorPage指定错误处理页面。如果本页面产生了异常或者错误,而该JSP页面没有对应的处理代码,则会自动调用该指令所指定的JSP页面。因为JSP内建了异常机制支持,所以JSP可以不处理异常,即使是checked异常。
isErrorPage设置本JSP页面是否为错误处理程序。如果该页面本身已是错误处理页面,则通常无须指定errorPage属性。
contentType用于设定生成网页的文件格式和编码方式,即MIME类型和页面字符集类型,默认的MIME类型是text/html;默认的字符集类型为ISO-8859-1。

JSP的7个动作指令
动作指令与编译指令不同,编译指令是通知Servlet引擎的处理消息,而动作指令只是运行时的脚本动作。编译指令在将JSP编译成Servlet时起作用;而处理指令通常可替换成JSP脚本,是JSP脚本的标准化写法。
JSP动作指令主要有如下7个:
jsp:forward:执行页面转向,将请求的处理转发到下一个页面(既可以转发给静态的HTML页面,也可以转发到动态的JSP页面,或者转发到容器中的Servlet)。
      语法:<jsp:forward page="{relativeURL|<%=expression%>}"/>
                  or
                <jsp:forward page="{relativeURL|<%=expression%>}">
                  {<jsp:param.../>}
                </jsp:forward>
                  第二种语法用于在转发时增加额外的请求参数。增加的请求参数的值可以通过HttpServletRequest类的getParameter()方法获取。

jsp:param:用于传递参数,必须与其他支持参数的标签一起使用。param指令可以与以下3个指令结合使用:jsp:include,jsp:forward,jsp:plugin
       语法: <jsp:param name="paramName" value="paramValue"/>

jsp:include:用于动态引入一个JSP页面。
jsp:plugin:用于下载JavaBean或Applet到客户端执行。
jsp:useBean:从scope中获得JavaBean实例,如果没有该实例就创建一个JavaBean实例。
      语法:<jsp:useBean id="name" class="classname" scope="page│request│session│application" />

jsp:setProperty:设置JavaBean实例的属性值。
       语法:<jsp:setProperty name="BeanName" proterty="propertyName" value="value"/>

jsp:getProperty:获得并输出JavaBean实例的属性值。
       语法:<jsp:getProperty name="BeanName" proterty="propertyName" />