首页 > 其他 > 详细

Servlet学习总结

时间:2019-02-15 16:49:42      阅读:175      评论:0      收藏:0      [点我收藏+]

一、什么是Servlet?

Servlet是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态web内容。通常我们也把实现了Servlet接口的java程序,称之为Servlet。

二、Servlet的作用

客户端发送HTTP请求到服务器,服务器启动并创建一个Servlet,Servlet根据请求的类型,调用service()的doGet()、doPost()等方法,将处理后的数据传递到服务端再处理由服务器端发送的数据发送到客户端,流程如下:

技术分享图片

三、Servlet的工作流程

  1. 浏览器通过IP和端口号与Web服务器建立链接,并向Web服务器发送HTTP请求。
  2. Web服务器判断目标Servlet是否存在,首次访问创建目标Servlet,调用Servlet的init()。
  3. 创建一个用于封装HTTP消息的HttpServletRequest和HttpServletResponse的对象,调用Servlet的service()方法将请求和响应对象作为参数传进去。
  4. service()方法将响应信息写入到response中,通过servlet返回到Web容器,Web容器读取response中的Response中的响应信息,并向浏览器发送HTTP响应。 Servlet调用时序图如下: (盗了一张大神的图)技术分享图片

四、Servlet的执行细节

浏览器向服务器请求时,服务器不会直接执行我们的类,而是到web.xml里寻找路径名 ①:第一步,浏览器输入访问路径后,携带了请求行,头,体 ②:第二步,根据访问路径找到已注册的servlet名称,既图中的demo ③:第三步,根据映射找到对应的servlet名 ③:第四步,根据根据servlet名找到我们全限定类名(盗了一张大神的图)

技术分享图片技术分享图片技术分享图片技术分享图片技术分享图片

五、Servlet开发

每个servlet标签对应一个servlet-mapping或者多个servlet-mapping标签,servlet标签中的servlet-name与servlet-mapping标签中servlet-name相同,且具有唯一性。servlet-class的值,指的是包名(servlet)+类名(firstServlet)。

    <servlet>
        <servlet-name>firstServlet</servlet-name>
        <servlet-class>servlet.firstServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>firstServlet</servlet-name>
        <url-pattern>/firstServlet</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>firstServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>

 

当配置<url-pattern>/*</url-pattern>时,*为通配符映射,即所有的链接都可以匹配。当存在多个映射的时候,根据访问请求的链接有优先匹配更‘像’的映射。如当请求URL为/firstServlet会优先匹配<url-pattern>/firstServlet</url-pattern>。 <load-on-startup>1</load-on-startup>为web应用写一个InitServlet,这个servlet配置为启动时装载,为整个web应用创建必要的数据库表和数据。

六、Servlet的线程安全问题

当多个客户端并发访问同一个Servlet的时候,Web服务器会给每个客户端的请求创建一个线程,通过调用Servlet的service(),当多个客户端同时访问的时候就会出现线程安全的问题。 当参数i是局部变量的时候即定义在doGet()方法里的时候,由于每个线程都有局部变量i,所以不存在线程安全的问题。 但是当i变成了全局变量的时候,每个线程的访问都会改变i的值。

public class secondServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    int i = 1;
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        System.out.println("SECOND SERVLET DOGET");
        //int i = 1;
        i++;
        response.setContentType("text/html");
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();
        try {
            Thread.sleep(4000);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
        out.println(i);
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}

 

解决方案:1.使用SingleThreadModel接口,但是现在已经过时了。

  1. 使用synchronized,但是并发量很大的时候效率就会很差了,需要就行排队。
synchronized (this) {

            i++;
            response.setContentType("text/html");
            response.setCharacterEncoding("UTF-8");
            PrintWriter out = response.getWriter();
            try {
                Thread.sleep(4000);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
            out.println(i);
        }

 

  1. 根据上述产生线程安全的根本原因,多是由于使用了全局变量导致的,因此避免或者谨慎的使用全局变量才是根本。

参考文章:https://www.cnblogs.com/xdp-gacl/p/3760336.html

https://blog.csdn.net/u010452388/article/details/80395679

https://baike.baidu.com/item/servlet/477555?fr=aladdin

Servlet学习总结

原文:https://www.cnblogs.com/dujingxin/p/10384103.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!