web开发 servlet

 

Servlet

javax.servlet.Servlet接口

servlet 是运行在服务器端的servlet容器中,需要继承javax.servlet.Servlet接口。

可以在这里查看servlet的文档:

http://tomcat.apache.org/tomcat-7.0-doc/servletapi/index.html

这个接口有5个方法:

如下:

 void

destroy()
          Called by the servlet container to indicate to a servlet that the servlet is being taken out of service.

 ServletConfig

getServletConfig()
          Returns a
ServletConfig object, which contains initialization and startup parameters for this servlet.

 java.lang.String

getServletInfo()
          Returns information about the servlet, such as author, version, and copyright.

 void

init(ServletConfig config)
          Called by the servlet container to indicate to a servlet that the servlet is being placed into service.

 void

service(ServletRequest req,ServletResponse res)
          Called by the servlet container to allow the servlet to respond to a request.

 

init 方法

Servlet 实例化后会调用init方法,可以向其传递一个servletConfig对象,这个对象包括了servlet的配置信息。还可以通过ServletConfig对象获取ServletContext对象,来与servlet进行通信。

service方法:

service 方法处理客户的请求,在调用service之前,必须生成 ServletRequestServletResponse对象,前者包含了请求信息,后者包括了响应信息。

destroy方法:

当检测到一个servlet 应该从容器中移除的时候,容器就会调用该servletdestroy方法。在destroy一般做资源清理工作,比如释放数据库连接,容器会等待service中的方法执行完或者超时了再执行destroy方法。

getServletConfig方法

返回初始化时候传递给servlet的配置信息ServletConfig对象

getServletInfo 方法

返回该servlet的信息,比如作者,版权等。

ServletRequest

ServletRequest 包含了所有传递给 servlet的参数,

可以在这里查看其文档:

http://tomcat.apache.org/tomcat-7.0-doc/servletapi/javax/servlet/ServletRequest.html

ServletResponse

ServletResponse 包含了所有servlet传递给客户端的信息

可以在这里查看其文档:

http://tomcat.apache.org/tomcat-7.0-doc/servletapi/javax/servlet/ServletResponse.html

Servlet的实现

如果直接使用servlet,是很痛苦的事情,javax包中已经有了对servlet的实现。

他们的关系如下图:

 

GenericServlet

GenericServlet 提供了一个不依赖于协议的sevlet通用实现,它也实现了ServletConfig接口和init和destory的简单生命周期,另外它实现了log功能。

文档在:

http://tomcat.apache.org/tomcat-7.0-doc/servletapi/javax/servlet/GenericServlet.html

HttpServlet

HttpServlet 顾名思义,就是支持http协议的servlet,它是GenericServlet的子类,如图所示。

protected  void

doDelete(HttpServletRequest req,HttpServletResponse resp)
          Called by the server (via the service method) to allow a servlet to handle a DELETE request.

protected  void

doGet(HttpServletRequest req,HttpServletResponse resp)
          Called by the server (via the service method) to allow a servlet to handle a GET request.

protected  void

doHead(HttpServletRequest req,HttpServletResponse resp)
          Receives an HTTP HEAD request from the protected service method and handles the request.

protected  void

doOptions(HttpServletRequest req,HttpServletResponse resp)
          Called by the server (via the service method) to allow a servlet to handle a OPTIONS request.

protected  void

doPost(HttpServletRequest req,HttpServletResponse resp)
          Called by the server (via the service method) to allow a servlet to handle a POST request.

protected  void

doPut(HttpServletRequest req,HttpServletResponse resp)
          Called by the server (via the service method) to allow a servlet to handle a PUT request.

protected  void

doTrace(HttpServletRequest req,HttpServletResponse resp)
          Called by the server (via the service method) to allow a servlet to handle a TRACE request.

protected  long

getLastModified(HttpServletRequest req)
          Returns the time the HttpServletRequest object was last modified, in milliseconds since midnight January 1, 1970 GMT.

protected  void

service(HttpServletRequest req,HttpServletResponse resp)
          Receives standard HTTP requests from the public service method and dispatches them to the doMethod methods defined in this class.

 void

service(ServletRequest req,ServletResponse res)
          Dispatches client requests to the protected service method.

 

Http方法加了

doGet  doPost  doPut dohead等几个方法,这几个方法都接受ServletRequest req,ServletResponse res这两个参数。并且重载了两个service方法,

其中doGet  doPost等方法的参数第二个service方法的参数是一样的。而且抛出的异常都是ServletException

我们一般使用的时候不用去修改service,只需要覆盖doXXX方法即可。因为调用过程是这样的:

当一个请求进入servlet 首先调用:

 void

service(ServletRequest req,ServletResponse res)
          Dispatches client requests to the protected service method.

方法,然后从req中使用getMethod()方法取得请求的类型XXX,再根据XXX调用doXXX方法。所以覆盖doXXX方法即可。

文档在:

http://tomcat.apache.org/tomcat-7.0-doc/servletapi/javax/servlet/http/HttpServlet.html

 

HttpServletRequest 

http://tomcat.apache.org/tomcat-7.0-doc/servletapi/javax/servlet/http/HttpServletRequest.html

HttpServletResponse 

http://tomcat.apache.org/tomcat-7.0-doc/servletapi/javax/servlet/http/HttpServletResponse.html

实例

hello world

eclipse javaEE下面建立一个dynamic web project。取名servletJspLearn

WEB-INFO

下面建立clases lib 文件夹,建立 web.xml文件。

classes 放编译好的.class文件。

lib放需要的库文件

welcome.jspjsp文件。

新建helloworld.java servlet

package junjun.chapter6;

 

import java.io.IOException;

import java.io.PrintWriter;

 

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

 

public class helloworld extends HttpServlet {

         protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

                   System.out.println(request.getServletContext().getContextPath());

                   PrintWriter p = response.getWriter();

                   p.println("hello world");

                  p.close();

         }

         protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

                   // TODO Auto-generated method stub

         }

}


 

 

web.xml中进行配置 servlet

 

 

<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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_3_0.xsd" version="3.0">

  <servlet>

    <servlet-name>helloworld</servlet-name>

    <servlet-class>junjun.chapter6.helloworld</servlet-class>

  </servlet>

  <servlet-mapping>

    <servlet-name>helloworld</servlet-name>

    <url-pattern>/hello</url-pattern>

  </servlet-mapping>

</web-app>


其中 <servlet>定义一个servlet :包括名字(servlet-name)报名.类名(servlet-class)

其中<servlet-mapping>定义了一个路径与一个servlet的映射关系

 

下面就可以使用

http://localhost:8080/servletJspLearn/hello访问这个servlet

 

 

打印请求信息

/**
 * 打印 请求信息
 * @author andyWebsense
 *
 */
public class OutputInfo extends HttpServlet
{
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException
	{
		response.setContentType("text/html;charset=gb2312");
			
		PrintWriter p = response.getWriter();
		p.println("<html><head><title> Info table </title></head>");
		p.println("<body>");
		p.println("<table border = 1 align = center>");
		p.println("<caption>headers the server received </caption>");
		p.println("<tr><th>header name</th><th>header value<th></th></tr>");
		
		// 打印 请求报头信息
	    Enumeration<String> headers = request.getHeaderNames();
		while(headers.hasMoreElements())
		{
			String name = headers.nextElement();
			String value = request.getHeader(name);
			p.println("<tr><td>"+name+"</td><td>"+value+"</td></tr>");
		}
		// 获取客户端ip
		p.println("<tr><td>"+"remove ip"+"</td><td>"+request.getRemoteAddr()+"</td></tr>");
		// 获取客户端端口
		p.println("<tr><td>"+"remote port"+"</td><td>"+request.getRemotePort()+"</td></tr>");
		// 获取服务器ip
		p.println("<tr><td>"+"local ip"+"</td><td>"+request.getLocalAddr()+"</td></tr>");
		// 获取服务器端口
		p.println("<tr><td>"+"local port"+"</td><td>"+request.getLocalPort()+"</td></tr>");
		
		p.println("</table></body></html>");
		p.close();	
	}
}


 

Servlet 登陆

注意redirect的使用

public class LoginServlet extends HttpServlet 
{
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException
	{
		resp.setContentType("text/html;charset=gb2312");
		String name = req.getParameter("user");
		String password = req.getParameter("password");
		
		if (name!=null && password!=null 
			&& name.equalsIgnoreCase("zhangsan") && password.equals("1234"))
		{
			//sendRedirect 将用户的请求重定向到 success.jsp中
			//该方法通过修改HTTP协议的HEADER部分(设置状态代码302,命令浏览器发重新发送请求),对浏览器下达重定向指令的,
			//让浏览器对在location中指定的URL提出请求,使浏览器显示重定向网页的内容
			resp.sendRedirect("success.jsp"); 
		}
		else
		{
			resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "服务器忙,请稍后登陆");
		}
		
		resp.flushBuffer();		
	}
}


 

success.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>login success</title>
</head>
<body>
<f:view>
	welcome here
</f:view>
</body>
</html>


 

 

 

servlet的生命周期

servlet的生命周期是由servlet容器来管理的。

1、加载与实例化

当容器启动时候或者检测到需要实例化Servlet来相应 request请求的时候,由容器创建一servlet,容器是使用反射来创建servlet的,所以不要提供带参数的servlet

 

2、初始化

调用servletinit方法进行初始化,servlet可以使用容器提供的ServletConfigweb应用程序的配置信息(web.xml)中获取初始化信息。如果发生异常,使用ServletException或者UnavailableException通知容器。

 

3、服务

调用service方法进行请求处理。从ServletRequest获取请求信息,通过ServletResponse设置返回信息,如果发生错误,抛出ServletException或者UnavailableException,如果UnavailableException只是该servlet永久不可用,调用destroy方法,注销这个servlet,如果有请求返回404,资源不可用。如果UnavailableException只是该servlet暂时不可用,返回503服务器忙。

 

4、服务终止

当容器检测到一个servlet需要从时候,调用destroy方法。

下面是这个过程的时序图

 

servlet上下文ServletContext

ServletContext表示一个servlet的上下文,servlet在初始化期间(调用init方法时候),向其传递ServletConfig,通过ServletConfig获取servletContextservletContext代表web服务器中一个已知的应用的根目录,例如: http://localhost:8080/servletJspLearn/login 的上下文被定定位于http://localhost:8080/servletJspLearn所有与/servletJspLearn为路径的请求都是与这个servlet关联的应用程序。

 

使用ServletContext实现页面访问统计

 

/**
 * 页面访问量统计 使用 ServletContext来保持访问次数
 * @author buptjunjun
 *
 */
public class CountServlet extends HttpServlet
{
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException
	{
		ServletContext context = this.getServletConfig().getServletContext();
		
		// 从servletContext中取出访问次数
		Integer count = (Integer) context.getAttribute("count");
		if(count == null)
			count = 1;
		else 
			count++;
		
		String user = request.getParameter("user");
		response.setContentType("text/html");
			
		PrintWriter p = response.getWriter();
		p.println("<html><head><title> "+"page visit statistics"+" </title></head>");
		p.println("<body> this page have been visited"+ count +"times </body></html>");
		p.close();
		
		// 将访问次数放入servletContext中
		context.setAttribute("count", count);
	}	
}


 

 

RequestDispacher控制转发

web应用中,一般有一个请求转发的控制器(一个servlet),它接受请求,然后将请求转发给其他的servlet,jsp或者html来处理。这就要用到RequestDispacher.

 

RequestDispacher 是由servlet容器创建,封装一个资源的路径,使用它的forwardinclude方法可以把请求转发给其他servletjsp或者html

可以在这里看它描述:

http://tomcat.apache.org/tomcat-7.0-doc/servletapi/javax/servlet/RequestDispatcher.html

Rquest定义了两个方法:

Method Summary

 void

forward(ServletRequest request,ServletResponse response)
          Forwards a request from a servlet to another resource (servlet, JSP file, or HTML file) on the server.

 void

include(ServletRequest request,ServletResponse response)
          Includes the content of a resource (servlet, JSP page, HTML file) in the response.

 

其实从字面意思就可以了解个大概意思了:

forward 是转发的意思,include是包括的意思。

forward是将请求转发给其他资源,自己就不管了,让其他资源去处理请求。

include是将其他资源包含到""的页面来。

forward 必须在响应提交到客户端之前调用,在调用forward之后,原先的没有被提交的响应将会被清除。如果响应被提交后调用,就会抛出IllegalStateException

Include 会将其他请求转发给其他servlet或者jsp等其他资源,但是这些资源的输出将并入原来的servlet中,由原来的servlet做出响应。

例如下面的例子 注意注释

 

package junjun.chapter6;

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

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

/**  * 请求转发  * @author andyWebsense  *  */ public class PortalServlet extends HttpServlet {  @Override  protected void doGet(HttpServletRequest req, HttpServletResponse resp)    throws ServletException, IOException  {   resp.setContentType("text/html;charset=gb2312");   PrintWriter p = resp.getWriter();      p.println("<html><head><title> Info table </title></head><body>");      String name = req.getParameter("user");   String password = req.getParameter("password");      if (name!=null && password!=null    && name.equalsIgnoreCase("zhangsan") && password.equals("1234"))   {        //p.println("<html><head><title> Info table </title></head><body>"); 的输出将保留     将success.jsp输出的内容插入到PortalServlet    //p.println("hello test</body></html>"); 也会输出    //最后输出时 PortalServlet的输出和success.jsp的输出只和    ServletContext context = this.getServletContext();    RequestDispatcher d = context.getRequestDispatcher("/success.jsp");    d.include(req, resp);   }   else   {    // 将请求转发到login2 servlet,对客户端的响应都由login2来处理。    //前面 p.println("<html><head><title> Info table </title></head><body>"); 的输出将会被清掉,    // p.println("hello test</body></html>"); 也不会输出    //最后输出只是login2的输出,portalServlet的输出被清除掉。    ServletContext context = this.getServletContext();    RequestDispatcher d = context.getRequestDispatcher("/login2");    d.forward(req, resp);   }      p.println("hello test</body></html>");   p.close();  }    @Override  protected void doPost(HttpServletRequest req, HttpServletResponse resp)    throws ServletException, IOException  {   this.doGet(req, resp);  } }

 

sendRedirectforward的区别

sendRedirect forward都可以将请求重定向到另一个资源。但是二者有本质的区别。

简而言之:sendRedirect是在客户端(浏览器)的重定向,forward 是在服务器端的重定向。

sendRedirect

重定向动作(调用sendRedirect方法时候)发生时候,发生重定向的servlet向客户端(浏览器)发送302,告诉浏览器要访问的资源,浏览器发起另一个请求访问该资源。如图所示,其实浏览器发送了两个请求。所以说重定向发生在客户端。

 

forward

forward不同,是在服务器端的重定向,重定向动作发生时候(调用forward方法时候),浏览器将ServletRequestServletResponse转到另一个资源,如另一个jsp,这个jsp来相应这个请求,在这个过程中,服务器与客户端的连接是没有中断的。所以是在服务器端的重定向。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值