Servlet的总结与解释(定义,生命周期,JSP,线程安全)

servlet是web三大组件之一.是最重要组件

  1. servlet是什么? 可以干什么?
  2. Servlet接口与HttpServlet
  3. servlet的生命周期
  4. servlet的常见配置
  5. Servlet如何接收数据,响应数据?
  6. JSP是什么? 为什么要有JSP?
  7. servlet是线程安全的吗? 不是的话,解决方案是什么?

1.servlet是什么? 可以干什么?

Servlet是web应用中的java程序,它可以对用户的请求进行处理,并做出响应.

 

2.当然Servlet从狭义上讲它是一个接口,里面规定了一些api.广义上讲指实现servlet接口的类.我们一般说的都是广义上的.

public interface Servlet {

public void init(ServletConfig config) throws ServletException;

public ServletConfig getServletConfig();

public void service(ServletRequest req, ServletResponse res)throws ServletException, IOException;

public String getServletInfo();

    public void destroy();

}

上面的这个servlet接口,要实现的方法太多,而且有些内容重复.tomcat就帮我们写好了一个很好的实现类 HttpServlet,我们只要继承它就可以.

public class TestServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

    public TestServlet() {
        super();      
    }

public void init(ServletConfig config) throws ServletException {
//服务器启动后,客户端第一次访问时执行
}

public void destroy() {
//服务器关闭时执行
}

protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//每访问一次,就会调用一次
//属于web层业务逻辑
}
}

上面的代码,简单提及到servlet的生命周期,下一节仔细讲一下.

当然如果,我们不需要初始化等与业务逻辑无关的方法,那么只覆盖父类的 doGet()  doPost() 就可以.也就是eclipse中默认创建servlet中的方法

public class HelloServlet extends HttpServlet {

private static final long serialVersionUID = 1L;
    public HelloServlet() {
        super();
    }
protected void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.getWriter().append("Served at: ").append(request.getContextPath());

}

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

 

 

3.servlet的生命周期

Servlet的生命周期,看下图

  1. 当有客户向服务器发出请求后,服务器通过映射文件(web.xml或注解),找到servlet.对它进行编译并执行init(),就是初始化操作.
  2. 服务器创建servlet是以单例模式创建的.所以上图中,thread A和thread B会访问同一个servlet.这样在减少资源使用的情况下,同时可能造成线程安全问题.(这个问题会在文章后面细说)
  3. 服务器会帮我们创建 http的request和response.帮助我们获取客户端信息,更方便的响应客户请求
  4. 有了servlet对象,request和response之后,就可以执行service()了.service()中有会调用service层中的方法,以完成整个逻辑.
  5. 最后,在服务器关闭时.JVM帮我们回收servlet对象.

 

下面这个图,是我访问百度,通过chrome浏览器可以看到的一部分http请求与响应.当然这些信息都是可以通过,service()中request得到的

4.servlet的常见配置

Eclipse中 2.5 版本之前,都是使用web.xml来配置的.之后采用注解方式配置.当然两者各有利弊.在xml中配置,对于需要时不时修改一下的配置是合适的.而注解方式更适合,配置完成后基本不做修改的配置.这里不细讲了.感兴趣可以自行百度w3School

5.Servlet如何接收数据,响应数据?

在tomcat中,会把用户的http请求内容,处理成一个request对象.同时创建一个response对象用于响应用户.

至于具体是如何创建的request的对象.我并没有看过具体的源码.在这里仅仅做一个简单的推测.在tomcat接收到http请求,这个请求会把请求行,请求头,请求体里的内容一段一段的解析.做一些复杂的字符串处理.然后再将各种信息整合分类.

Ajax:往往用于异步传输数据,请求没有变化,响应时,不需要请求转发或者重定向.一般是把数据转换为JSON字符串,然后传给客户端.记得服务器响应时,要设置好response.setContentType("application/json;charset=utf-8")

 

6.JSP是什么? 为什么要有JSP?

JSP是一种特殊的servlet.每个JSP都对应一个java对象.具体的代码可以打开tomcat.以我的为例,该目录下可以看到具体的代码

C:\Tomcat 8.0\webapps\work\Catalina\localhost\mycrm\org\apache\jsp

 

我们可以看到每个jsp都对应着一个.class和.java文件.打开.java文件之后

public final class top_jsp extends org.apache.jasper.runtime.HttpJspBase

    implements org.apache.jasper.runtime.JspSourceDependent {}

里面有类似与servlet的init,destroy,service方法.在service()中,可以看到

 

从这里可以引出,为什么要有JSP?

在没有JSP 之前,人们只能想上图那样,一行一行的将html的代码输出.这是一件很枯燥且丧心病狂的一件事.导致了很多人接受不了.没办法,sun就推出了jsp.

以前说在JSP中内嵌java代码,后来才知道,是在java中嵌入html代码.当然了,JSP的表达方式和html非常相似.而且还可以动态生成代码.方便多了.而且之后也推出了想JSTL,EL,更加使JSP中的Java代码变得少了.

另外:JSP有9个内置对象.为什么能有呢?因为它在service()中创建了9个对象.就当然可以在JSP页面中使用了.

 

7.servlet是线程安全的吗? 不是的话,解决方案是什么?

在 Web 应用程序中,一个 Servlet 在一个时刻可能被多个用户同时访问。这时 Web 容器将为每个用户创建一个线程来执行 Servlet。如果 Servlet 不涉及共享资源的问题,不必关心多线程问题。但如果 Servlet 需要共享资源,需要保证 Servlet 是线程安全的。

也就是说:servlet在有共享资源下,很可能出现线程安全问题!

我知道的解决方法有3种

  1. 不使用可变的共享变量.可以使用final修饰的变量.但是一般的成员变量,就不能使用了.这从根本上解决了问题.但是呢,没有了共享变量,在方法中可能要多次创建相同的对象.造成资源的浪费.
  2. 使用synchronized 来对共享变量的操作进行加锁.这样会大大降低并发性.
  3. 继承单线程接口,这个根本不可能使用.单线程的话,就可以当单机游戏玩了.

 

当然,现在的框架都解决了servlet的线程安全问题.那个就更复杂了.一言半语讲不清的.

才疏学浅,若有不当之处,请指出,共同学习!

 

参考资源

http://www.runoob.com/servlet/

 

猜你喜欢

转载自blog.csdn.net/qq_34120430/article/details/83826823
今日推荐