Servlet
一个可以处理HTTP请求的标准Java类,增强服务器端功能.
1、 生命周期
a) init():服务器初始化Servlet,只在第一次请求时被初始化一次,只存在一个实例,所以不建议在Servlet中设置成员变量;
b) service():Servlet对象调用该方法响应客户端的请求。在该过程中会通过判断用户的请求方式来具体应用doGet/doPost方法处理请求;
c) destory():销毁Servlet对象。
2、 Servlet
packagecom.test.rqq;
importjava.io.IOException;
importjava.io.PrintWriter;
importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
publicclass ServletTest01 extends HttpServlet {
publicvoid doGet(HttpServletRequest request, HttpServletResponseresponse)
throws ServletException,IOException {
doPost(request, response);
}
publicvoid doPost(HttpServletRequest request, HttpServletResponseresponse)
throws ServletException,IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE HTML PUBLIC\"-//W3C//DTD HTML4.01 Transitional//EN\">");
out.println("<HTML>");
out.println("<HEAD><TITLE>AServlet</TITLE></HEAD>");
out.println("<BODY>");
out.print("This is ");
out.print(this.getClass());
out.println(", using the POSTmethod");
out.println("</BODY>");
out.println("</HTML>");
out.flush();
out.close();
}
}
3、 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<description>This is the description of my J2EEcomponent</description>
<display-name>This is the display name of my J2EEcomponent</display-name>
<servlet-name>ServletTest01</servlet-name>
<servlet-class>com.test.rqq.ServletTest01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletTest01</servlet-name>
<url-pattern>/servlet/ServletTest01</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
4、 Servlet对象关系图
5、 Servlet接口
public void init(ServletConfig config) throwsServletException;
被Servlet容器调用,将Servlet放置在该容器的服务中。实例化Servlet的过程中只被调用一次。Config是一个包含了Servlet的配置信息和初始化参数的ServletConfig对象变量。
public ServletConfig getServletConfig();
返回的ServletConfig就是初始化该Servlet时的实参。
public void service(ServletRequest req, ServletResponseres) throws ServletException, IOException;
被Servlet容器响应请求时调用。只能够在init方法执行成功后调用。Servlet具有同时处理多个请求的多线程特性,同步访问文件,网络连接,又或者Servlet类和实例变量等共享资源时必须考虑清楚。
public String getServletInfo();
返回一个包含作者、版本和版权等Servlet自身基本信息的字符串。
public void destroy();
当Servlet需要从服务中移除时被Servlet容器调用。该方法只在调用service方法的诸多线程退出或者Servlet生命周期结束后调用。
6、 ServletConfig接口
被用于Servlet容器初始化Servlet期间向其传递Servlet的配置信息。
public String getInitParameter(String name);
返回指定名称为name的初始化参数的值,若该参数不存在则返回null。
public Enumeration getInitParameterNames();
返回一个封装了Servlet所有初始化参数名称的Enumeration对象。若该Servlet不具有初始化参数则返回一个空的Enumeration对象
public String getServletName();
返回当前Servlet实例的名字。
public ServletContext getServletContext();
返回一个当前运行的ServletContext的引用。
7、 HttpServlet抽象类
一个用来创建适合网络站点满足HTTP协议的抽象类。它的子类必须重写doGet、
doPost、doPut、doDelete、init和destroy、getServletInfo中的至少一个方法。
8、 ServletRequest接口
为Servlet提供客户端请求信息的对象。
public void setCharacterEncoding(Stringenv) throws UnsupportedEncodingException;
重写请求体中字符编码格式的名字。该方法必须在读取请求参数或者使用getReader()方法读取之前。如果方法参数指定的编码无效,则抛出异常。
public String getCharacterEncoding();
返回用于请求体中字符编码的格式的名字。如果请求中没有指定,则返回null。
public String getParameter(String name);
将请求参数值作为一个字符串返回,若请求参数不存在返回null。使用这个方法之前应该明确该参数具有唯一的值。如果可能有多余一个的值,应该使用getParameterValues(String s)方法。
publicEnumeration getParameterNames();
返回一个封装了请求中所有参数名的字符串的Enumeration对象。如果该请求没有参数,该方法返回一个空的Enumeration对象。
publicString[] getParameterValues(String name);
返回指定请求参数名参数的所有值组成的字符串数组,若该参数名不存在,返回null。
publicRequestDispatcher getRequestDispatcher(Stringpath);
返回一个可以将请求转发给指定path的请求分发器。地址字符串path必须以“/”开头。
publicMap getParameterMap();
返回当前请求的所有参数组成的Map对象。
publicString getProtocol();
返回在form protocol/major Version.minorVersion使用的请求的协议的名字和版本。
publicString getScheme();
返回组成当前请求的配置名,例如:http,https或ftp。
publicString getServerName();
返回接收当前请求的服务器的主机名。
publicint getServerPost();
返回接收当前请求的服务器的端口号。
publicvoid setAttribute(String name, Object o);
在请求中存储一个属性。请求之间的属性被重新安排。这个方法经常联合RequestDispatcher使用。
publicvoid removeAttribute(String name);
从当前请求中移除一个属性。
publicObject getAttribute(String name);
返回一个Object类型的指定属性名的属性值,如果没有给定名称的属性存在,则返回null。
publicEnumeration getAttributeNames();
返回一个包含了请求中所有有效属性名的Enumeration对象。如果请求中没有有效的属性,则返回一个空的Enumeration对象。
publicString getRealPath(String path);
已废弃。作为2.1版本的JavaServlet API,使用ServletContext.getRealPath(Strings) 替代。
publicString getRemoteAddr();
返回发送当前请求的客户端IP地址。
publicString getRemoteHost();
返回发送请求的客户端全部限定名。
publicEnumeration getLocales();
返回一个封装了现场对象标识的Enumeration对象。
publicboolean isSecure();
返回一个boolean类型的标志,如果请求通过一个安全通道形成,例如HTTPS。
publicint getContentLength();
通过输入流依照字节返回请求体中有效长度。如果长度未知,则返回-1.
publicString getContentType();
返回请求体的MIME格式,如果格式未知,返回null。
publicServletInputStream getInputStream() throws IOException;
通过ServletInputStream以二进制数据格式重新得到请求体。
publicBufferedReader getReader() throws IOException;
通过BufferedReader以字符数据格式重新获取请求体。
9、 HttpServletRequest接口
public String getMethod();
返回建立请求的方式名称。例如:GET/POST/PUT。
public String getContextPath();
返回指明上下文的请求URI的一部分。上下文路径总是在请求URI的最前面,该路径由“/”开头,但不以“/”结束。
实质就是:“/”+ Web应用(工程)名,如:/test
public StringBuffer getRequestURL();
http://127.0.0.1:8000/test/servlet/ServletTest01
public String getRequestURI();
/test/servlet/ServletTest01
public String getServletPath();
/servlet/ServletTest01
public HttpSession getSession(boolean create);
返回与当前请求相关联的会话对象。如果没有当前Session并且create参数为true,返回一个新的会话。如果create参数为false并且当前请求没有有效会话,返回null。
publicHttpSession getSession();
返回与当前请求相关联的会话对象。如果请求没有Session,建立一个。
publicString getRequestedSessionId();
返回来自客户端的会话ID。在实际应用中这个ID并不一定是目前的会话ID。例如:如果当前请求的会话过期,并且服务器重新建立一个新的会话,该方法返回新建立会话的ID。如果当前请求没有指定的会话ID,返回null。
publicboolean isRequestedSessionIdValid();
检查当前请求的会话ID是否依然有效。
publicEnumeration getHeaderNames();
返回一个封装了所有当前请求所包含的请求头名字的Enumeration对象。如果该请求没有请求头,返回一个空的Enumeration对象。
public StringgetHeader(String name);
返回一个指定名字的请求头信息的值。如果当前请求头不包含该指定名称,该方法返回null。
public EnumerationgetHeaders(String name);
返回一个封装了指定名字的请求头信息的所有值的Enumeration对象。
public intgetIntHeader(String name);
返回指定名称的请求头信息的int类型的值。如果当前请求头信息不包含该名称,该方法返回-1。如果该请求头的值不能够转换成int类型,该方法返回一个NumberFormatException。
10、forward和sendReadirect的区别
a) RequestDispatcher.forward方法只能将请求转发给同一个Web应用中的组件;而HttpServletResponse.sendRedirect方法不仅可以重定向到当前应用程序中的其他资源,还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点上的资源。如果传递给sendRedirect方法的相对URL以“/”开头,它是相对于整个Web站点的根目录;如果创建RequestDispatcher对象时指定的相对URL以“/”开头,它是相对于当前的Web应用程序的根目录;
b) sendRedirect方法重定向的访问过程结束后,浏览器地址栏中显示的URL会由初始的URL地址变成重定向的目标URL;而调用forward方法的请求转发过程结束后,浏览器地址栏保持初始的URL地址不变;
c) sendRedirect方法对浏览器的请求直接做出响应,响应的结果就是告诉浏览器去重新发出对另外一个URL的访问请求,这个过程好比有个叫“浏览器”的人写信找张三借钱,张三灰心说没有钱,让“浏览器”去找李四借,并将李四现在的通信地址告诉给了“浏览器”。然后,“浏览器”又按张三提供的通信地址给李四写信借钱,李四收到信后把钱借给了“浏览器”。可见“浏览器”一共发出了两封信并收到了两次回复,“浏览器”也知道他借到的钱来自李四;forward方法在服务器端内部将请求转发给另外一个资源,浏览器只知道发出了请求并得到了相应结果,并不知道服务器内部发生了转发行为。这个过程好比“浏览器”写信找张三借钱,张三没钱,于是张三找李四借了钱之后,将钱再汇给了“浏览器”。可见,“浏览器”只发出了一封信并收到了一次回复,他只知道从张三那里借到了钱,并不知道钱具体来自李四之手。
d) forward方法的调用者与被调用者之间共享相同的request和response对象,他们同属于一个访问请求和响应过程;而sendRedirect方法的调用者和被调用者使用各自的request对象和response对象,它们分属于两个独立的访问请求和相应过程。对于同一个Web应用程序的内部资源之间的跳转,特别是跳转之前要对请求进行一些前期预处理,如:使用setAttribute方法传递预处理结果,那就应该使用forward方法。不同应用程序之间的重定向,特别是要重定向另外一个Web站点上的资源的情况,应该使用sendRedirect;
e) 无论是forward还是sendRedirect方法,在调用它们之前,都不能有内容已经被实际输出到了客户端。如果缓冲区中已经有了一些内容,这些内容将被从缓冲区清除。
11、sendRedirect和forward的使用
packagecom.test.rqq;
importjava.io.IOException;
importjavax.servlet.ServletException;
importjavax.servlet.http.HttpServlet;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
publicclass ServletTest01 extends HttpServlet {
publicvoiddoGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException,IOException {
doPost(request,response);
}
publicvoiddoPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException,IOException {
System.out.println(getServletContext().getContextPath());// /test
System.out.println(request.getRequestURI());// /test/servlet/ServletTest01
System.out.println(request.getRequestURL());// http://localhost:8000/test/servlet/ServletTest01
System.out.println(request.getServletPath());// /servlet/ServletTest01
// request.getRequestDispatcher("/servlet/ServletTest02").forward(request,response);
// request.getRequestDispatcher("/index.jsp").forward(request,response);
/*
* 可以看到RequestDispatcher中以"/"开头的URL是以Web应用为根路径
*/
// response.sendRedirect("/test/servlet/ServletTest02");
response.sendRedirect(getServletContext().getContextPath()+ "/index.jsp");
/*
* 可以看到sendRedirect中以"/"开头的URL是以站点为根路径
*/
}
}