JavaEE 学习整理笔记: Servlet 介绍

Servlet

=============

Servlet是一种托管于Servlet容器的Web组件,可以动态生成内容。Web客户端使用请求/响应模式与Servlet交互。
Servlet容器负责Servlet的声明周期,接受请求与发送响应,并执行这一过程中所需要的编码/解码。
响应处理的过程是由Servlet完成的,Servlet容器只是负责发送Servlet处理后的响应。

WebServlet

Servlet 类是使用@WebServlet注解并继承javax.servlet.http.HttpServlet类的POJO类。例如:代码段一

    @WebServlet(urlPatterns={"/demo", "/example"}, 
        initParams={ @webInitParam(name="servlet", value="Demo") } )
    public class FirstServlet extends javax.servlet.http.HttpServlet {

        protect void doGET(HttpServletRequest request, HttpServletResponse response){
            // do something...
        }

        // doPost...
        // doDelete...
        // ...
    }   

HttpServlet接口为每个Http请求:GET、POST、PUT、DELETE、HEAD、OPTIONS和TRACE的处理,都提供了一个do***的方法。通常情况下,我们只需要关心GET和POST的请求处理。如果项目采用RESTful风格的话,可能会额外的关注别的处理方法。
- HttpServletRequest 捕获Web客户端的请求,并可以从中取得请求相关的信息以及客户端的信息。
- HttpServletResponse 向Web客户端返回请求处理响应,开发人员负责填充HttpServletResponse,然后Servlet容器将捕获HTTP头信息或消息体信息发送给客户端。

定制Servlet的默认行为

如代码段一中所见的,我们可以使用@WebInitParam注解来为一个Servlet指定初始化参数。同时,我们也可以通过覆盖javax.servlet.Servlet接口中的生命周期各阶段调用方法init、service和destroy等来定制Servlet的默认行为。例如:通常情况下,我们会将一个数据库连接的初始化代码放置在init方法中,然后将释放代码放置在destroy方法中。

web.xml文件

注解是Servlet2.5版本后引入的新特性,在此之前我们都是使用web.xml文件对Servlet进行配置的,当然在Servlet3.0中也是支持web.xml配置的,并且如果我们在web.xml中配置了Servlet的话,该配置将会覆盖Servlet上的注解,也即是: web.xml中配置的Servlet的值优先级高于Servlet类文件中的注解值 。web.xml配置文件示例:

<!-- Servlet 配置-->  
<servlet>  
  <!-- 指定Servlet的名字,主要是为了之后再配置文件中配置URL映射时使用-->  
  <servlet-name>demo</servlet-name>  
  <!-- Servlet 的类全类限定名-->
  <servlet-class>com.wenchain.servlet.DemoServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>demo</servlet-name>  
  <!-- Servlet 负责处理的映射地址-->
  <url-pattern>/demo</url-pattern>
</servlet-mapping> 
<!-- 一个Servlet可以匹配多个URL映射地址-->
<servlet-mapping>  
  <servlet-name>demo</servlet-name>
  <url-pattern>/example</url-pattern>
</servlet-mapping> 

在注解方式配置Servlet产生之后,web.xml就不再是必须要存在的配置文件了,但是,在某些情况下web.xml文件依然是必须要的。例如: 指定Servlet的顺序就只能在web.xml文件中配置完成
如果我们在web.xml文件中配置了metadata-complete元素并将其值设置为true,那么类中定义的注解将会被忽略。例如:

<web-app metadata-complete="true">
 // ...
</web-app>

Servlet的存在形式

通常情况下,Servlet被打包在.war文件中。多个Servlet可以被打包在一起,并且共享一个Servlet上下文(Servlet Context)。Servlet上下文类ServletContext中提供了关于Servlet运行环境的详细信息,用于与容器通信。

关于ServletContext的初步认识

如何获取ServletContext

  • 我们可以从HttpServletRequest中获得ServletContext实例:
    protect void doGet(HttpServletRequest request, HttpServletResponse response){
        ServletContext sc = request.getServletContext();
    }

使用场景:
场景一:
我们在某些Web应用中,我们可能需要对用户进行跟踪,以方便记录用户的一些操作数据,例如购物网站。这个时我们通常使用Cookie+Session结合使用的方案。Servlet发送一个名为JSESSIONID的HTTP Cookie到客户端。为了防止该cookie被暴露给客户端脚本代码,进而导致服务器需要承担可能出现的恶意脚本攻击,这时我们需要将该cookie设置为HttpOnly的。为了实现这一方案,我们需要对Cookie进行配置,可能的代码

SessionCookieConfig scconfig = request.getServletContext().getSesssionCookieConfig();
scconfig.setHttpOnly(true);

关于session与cookie的详细讲解,在另外一篇博文中有详细介绍

场景二:
通常情况下,我们对于一个请求的处理过程,涉及到的Servlet往往不止一个。例如:Servlet A 处理完一个请求后还需要将该请求发送给另外一个Servlet B进行进一步的处理。这个时候就需要使用请求转发(forward)。我们使用RequestDispatcher来将请求转发到不同的资源(Servlet)中。
获取RequestDispatcher实例的方法有两种: HttpServletRequest.getRequestDispatcher方法和ServletContext.getRequestDispatcher方法 。这两种获取方式分别对应不同的应用场景。

@WebServlet("/example")
public class ExamlpeServlet extends HttpServlet{
    protect void doGet(HttpServletRequest request, HttpServletResponse response){
        // 这里demo指代的Servlet部署在与 ExampleServlet 相同的上下文中
        request.getRequestDispatcher("demo").forward(request, response);
    } 
}

如果需要转发到不同上下文的Servlet中,就需要使用ServletContext.getContext方法获得不同的上下文的ServletContext实例,进一步从中获取RequestDispatcher实例来转发请求到对应的上下文中

更多的ServletContext使用及介绍在另外一篇学习笔记中进行记录。之后将转为博文上传。

你可能感兴趣的:(java,Web,servlet,ee)