您的位置:首页 > 其它

Servlet学习

2016-06-06 14:10 176 查看

1介绍:

servlet 是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。

Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。

2引入包:

最新的servlet已经升级到3.0版本了。在应用过程中,通过maven引入即可。

<dependency>

            <groupId>javax.servlet</groupId>

            <artifactId>javax.servlet-api</artifactId>

            <version>3.1.0</version>

</dependency>

3 生命周期:

Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:

Servlet 通过调用 init () 方法进行初始化。
Servlet 调用 service() 方法来处理客户端的请求。
Servlet 通过调用 destroy() 方法终止(结束)。
最后,Servlet 是由 JVM 的垃圾回收器进行垃圾回收的。

在web容器中,servlet是属于单例型,即只创建一次。
在初始时调用init方法:public void init(ServletConfig config) throws ServletException; 此时通过ServletConfig读取相关配置参数。

初始化中也分为几种情况:

Servlet容器启动时自动装载某些Servlet,实现它只需要在web.XML文件中的<Servlet></Servlet>之间添加如下代码:
<loadon-startup>
</loadon-startup>。

在Servlet容器启动后,客户首次向Servlet发送请求
Servlet类文件被更新后,重新装载Servlet
Servlet被装载后,Servlet容器创建一个Servlet实例并且调用Servlet的init()方法进行初始化。在Servlet的整个生命周期内,init()方法只被调用一次。

每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务(servlet是单一的)。进入service方法执行: public void service(ServletRequest req, ServletResponse res)    throws ServletException, IOException; 如果是HttpServlet类,通过对请求的类型是GET还是POST等,再进入对应的方法:

@Override

    public void service(ServletRequest req, ServletResponse res)

        throws ServletException, IOException

    {

        HttpServletRequest  request;

        HttpServletResponse response;

        

        if (!(req instanceof HttpServletRequest &&

                res instanceof HttpServletResponse)) {

            throw new ServletException("non-HTTP request or response");

        }

        request = (HttpServletRequest) req;

        response = (HttpServletResponse) res;

        service(request, response);

    }

注意,传入参数ServletRequest req, ServletResponse res  在转换成HttpServletRequest,HttpServletResponse后,调用此类型的servi
4000
ce方法。我们再看下这个方式的实现内容:

 protected void service(HttpServletRequest req, HttpServletResponse resp)

        throws ServletException, IOException

    {

        String method = req.getMethod();

        if (method.equals(METHOD_GET)) {

            long lastModified = getLastModified(req);

            if (lastModified == -1) {

                // servlet doesn't support if-modified-since, no reason

                // to go through further expensive logic

                doGet(req, resp);

            } else {

                long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);

                if (ifModifiedSince < lastModified) {

                    // If the servlet mod time is later, call doGet()

                    // Round down to the nearest second for a proper compare

                    // A ifModifiedSince of -1 will always be less

                    maybeSetLastModified(resp, lastModified);

                    doGet(req, resp);

                } else {

                    resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);

                }

            }

        } else if (method.equals(METHOD_HEAD)) {

            long lastModified = getLastModified(req);

            maybeSetLastModified(resp, lastModified);

            doHead(req, resp);

        } else if (method.equals(METHOD_POST)) {

            doPost(req, resp);

            

        } else if (method.equals(METHOD_PUT)) {

            doPut(req, resp);

            

        } else if (method.equals(METHOD_DELETE)) {

            doDelete(req, resp);

            

        } else if (method.equals(METHOD_OPTIONS)) {

            doOptions(req,resp);

            

        } else if (method.equals(METHOD_TRACE)) {

            doTrace(req,resp);

            

        } else {

            //

            // Note that this means NO servlet supports whatever

            // method was requested, anywhere on this server.

            //

            String errMsg = lStrings.getString("http.method_not_implemented");

            Object[] errArgs = new Object[1];

            errArgs[0] = method;

            errMsg = MessageFormat.format(errMsg, errArgs);

            

            resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);

        }

    }

可以看出,此方法中会根据请求的方法类型,再进入各个方法的实现。所以在实践过程中,我们一般创建自己的servlet方法,继承HttpServlet,重新定义doPost/doGet方法即可。

最后一个就是destroy方法了,destroy方法在容器移除servlet 时执行,同样只执行一次。这个方法会在所有的线程的service()方法执行完成或者超时后执行,调用这个方法后,容器不会再调用这个servlet的方法,也就是说容器不再把请求发送给这个servlet。这个方法给servlet释放占用的资源的机会,列如释放内存、文件句柄、线程等。

4 使用:

实际应用中,基本上有3类:直接实现Servlet接口、继承GenericServlet类、或继承HttpServlet类。其中一般servlet推荐使用Genericservlet,如果是在web中使用HttpServlet,它提供针对http的特殊实现的。

import java.io.IOException;

import javax.servlet.ServletConfig;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.annotation.WebInitParam;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;

@WebServlet(name="annotationServlet", urlPatterns={"*.an"}, initParams={

        @WebInitParam(name="openFlag", value="true")

})

public class AnnotationServlet extends HttpServlet {

    

    private boolean openFlag = false;

    

    private int count = 0;

    

    /**

     * @Fields serialVersionUID : TODO

     */

    private static final long serialVersionUID = 1L;

    @Override

    protected void service(HttpServletRequest req, HttpServletResponse resp)

            throws ServletException, IOException {

        count ++;

        

        System.out.println("AnnotationServlet --- service  openFlag = " + openFlag + " count = " + count+"; AnnotationServlet hashcode:" + this.getServletInfo().hashCode());

        

        super.service(req, resp);

    }

    @Override

    public void destroy() {

        System.out.println("AnnotationServlet --- destroy");

        super.destroy();

    }

    

    

    @Override

    public void init(ServletConfig config) throws ServletException {

        // TODO Auto-generated method stub

        super.init(config);

        

        String openFlag = config.getInitParameter("openFlag");

        this.openFlag = StringUtils.equals(openFlag, "true");

        

        System.out.println("AnnotationServlet --- init" +"; AnnotationServlet hashcode:" + this.getServletInfo().hashCode());

    }

}

---------------------------------------------------------------

import java.io.IOException;

import javax.servlet.ServletConfig;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class LoadOnStartUpServlet extends HttpServlet {

    /**

     * @Fields serialVersionUID : TODO

     */

    private static final long serialVersionUID = 1L;

    

    private int count = 0;

    @Override

    protected void service(HttpServletRequest req, HttpServletResponse resp)

            throws ServletException, IOException {

        

        System.out.println("LoadOnStartUpServlet---service :  count="+count+";LoadOnStartUpServlet hashcode:" + this.getServletInfo().hashCode());

        

        super.service(req, resp);

    }

    @Override

    public void destroy() {

        System.out.println("LoadOnStartUpServlet---destroy");

        super.destroy();

    }

    @Override

    public void init(ServletConfig config) throws ServletException {

        System.out.println("LoadOnStartUpServlet---init" +"; LoadOnStartUpServlet hashcode:" + this.getServletInfo().hashCode());

        super.init(config);

    }

}

--------------------------------------------------------------------------------------

import java.io.IOException;

import javax.servlet.ServletConfig;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class XmlServlet extends HttpServlet {

    /**

     * @Fields serialVersionUID : TODO

     */

    private static final long serialVersionUID = 1L;

    

    private int count = 0;

    @Override

    protected void service(HttpServletRequest req, HttpServletResponse resp)

            throws ServletException, IOException {

        

        System.out.println("XmlServlet---service :  count="+count+"; XmlServlet hashcode:" + this.getServletInfo().hashCode());

        

        super.service(req, resp);

    }

    @Override

    public void destroy() {

        System.out.println("XmlServlet---destroy");

        super.destroy();

    }

    @Override

    public void init(ServletConfig config) throws ServletException {

        System.out.println("XmlServlet---init"+"; XmlServlet hashcode:" + this.getServletInfo().hashCode());

        super.init(config);

    }

}

web.xml配置:

 <servlet>

           <servlet-name>loadOnStartUpServlet</servlet-name>

           <servlet-class>com.zcl.servlet.LoadOnStartUpServlet</servlet-class>

           <load-on-startup>2</load-on-startup>

       </servlet>

       

       <servlet>

           <servlet-name>xmlServlet</servlet-name>

           <servlet-class>com.zcl.servlet.XmlServlet</servlet-class>

       </servlet>

<servlet-mapping>

           <servlet-name>xmlServlet</servlet-name>

           <url-pattern>*.xs</url-pattern>

       </servlet-mapping>

       

       <servlet-mapping>

           <servlet-name>loadOnStartUpServlet</servlet-name>

           <url-pattern>*.lon</url-pattern>

       </servlet-mapping>

以上定义了3个自定义的servlet,一个是web容器启动时就记载的loadOnStartUpServlet;一个是有请求过来时才创建的xmlServlet;一个也是有请求过来才创建的,但是使用注解方式的AnnotationServlet(在servlet3.*时提供的注解方式)。

运行时就可以看到他们的生命周期的过程。

5 异常处理:

当一个 Servlet 抛出一个异常时,Web 容器在使用了 exception-type 元素的 web.xml 中搜索与抛出异常类型相匹配的配置。

您必须在 web.xml 中使用 error-page 元素来指定对特定异常 或 HTTP状态码 作出相应的 Servlet 调用。

<error-page>

           <error-code>405</error-code>

           <location>/error.jsp</location>

</error-page>

       

<error-page>

           <exception-type>java.lang.Throwable</exception-type>

           <location>/error.jsp</location>

</error-page>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: