Servlet

Servlet学习笔记

、使用 JavaEE 版的 Eclipse 开发动态的 WEB 工程(JavaWEB 项目)
  1. 把开发选项切换到 JavaEE
  2. 可以在 Window -> Show View 中找到 Package Explorer, 并把其拖拽到开发区的左边
  3. 在 Servers 面板中新建 Tomcat 服务器. 一定要关联到 Tomcat 安装的根目录
  4. 新建一个 Dynamic Web Project. 其中 Target Runtime 需选择 Tomcat6.0
  5. 开发 Java WEB 应用
  6. 可以通过 run on server 来运行 WEB 项目.

二、 Servlet 的 HelloWorld

  1. 创建一个 Servlet 接口的实现类.

    public class HelloServlet implements Servlet{}
    
  2. web.xml 文件中配置和映射这个 Servlet

    <!-- 配置和映射 Servlet -->
    
    <servlet>
        <!-- Servlet 注册的名字 -->
        <servlet-name>helloServlet</servlet-name>
        <!-- Servlet 的全类名 -->
        <servletclass>
        </servlet-class>
    </servlet>
    
    <servlet-mapping>
        <!-- 和某一个 servlet 节点的 serlvet-name 子节点的文本节点一致 -->
        <servlet-name>helloServlet</servlet-name>
        <!-- 映射具体的访问路径: / 代表当前 WEB 应用的根目录. -->
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    

三、Servlet 容器: 运行 Servlet、JSP、Filter 等的软件环境.

  • 可以来创建 Servlet, 并调用 Servlet 的相关生命周期方法.

  • JSP, Filter, Listener, Tag …

四、Servlet 生命周期的方法: 以下方法都由 Serlvet 容器负责调用.

  • 构造器: 只被调用一次. 只有第一次请求 Servlet 时, 创建 Servlet 的实例. 调用构造器. (这说明 Serlvet 的单实例的!)
  • init 方法: 只被调用一次. 在创建好实例后立即被调用. 用于初始化当前 Servlet.
  • service: 被多次调用. 每次请求都会调用 service 方法. 实际用于响应请求的.
  • destroy: 只被调用一次. 在当前 Servlet 所在的 WEB 应用被卸载前调用. 用于释放当前 Servlet 所占用的资源.

五、load-on-startup 参数:

配置在 servlet 节点中:

    <servlet>
        <!-- Servlet 注册的名字 -->
        <servlet-name>secondServlet</servlet-name>
        <!-- Servlet 的全类名 -->
        <servletclass>
        </servlet-class>
        <!-- 可以指定 Servlet 被创建的时机 -->
        <load-on-startup>2</load-on-startup>
    </servlet>

load-on-startup: 可以指定 Serlvet 被创建的时机. 若为负数, 则在第一次请求时被创建.若为 0 或正数, 则在当前 WEB 应用被Serlvet 容器加载时创建实例, 且数组越小越早被创建.

六、关于 serlvet-mapping:

  1. 同一个Servlet可以被映射到多个URL上,即多个<servlet-mapping>元素的<servlet-name>子元素的设置值可以是同一个Servlet的注册名。

  2. 在Servlet映射到的URL中也可以使用 * 通配符,但是只能有两种固定的格式:
    一种格式是“*.扩展名”,另一种格式是以正斜杠(/)开头并以“/*”结尾。

    <servlet-mapping>
        <servlet-name>secondServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    

    OR

    <servlet-mapping>
        <servlet-name>secondServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
    

    注意: 以下的既带 / 又带扩展名的不合法.

    <servlet-mapping>
        <servlet-name>secondServlet</servlet-name>
        <url-pattern>/*.action</url-pattern>
    </servlet-mapping>
    

七、ServletConfig: 封装了 Serlvet 的配置信息, 并且可以获取 ServletContext 对象

ServletConfig代表当前Servlet在web.xml中的配置信息。
在Servlet接口中init方法参数就是ServletConfig,在Servlet创建出来时,init方法立即被容器调用,由容器传入ServletConfig对象。
在GenericServlet中,实现了这个方法,将ServletConfig设置成了类的成员变量,并提供了getServletConfig方法,获取该对象。
我们的Servlet都间接继承子GenericServlet,所以可以在自己的Servlet中直接调用getServletConfig方法获取这个对象。
在web.xml中的标签中可以配置零个或多个标签,用来为当前Servlet配置一些自定义的参数–称为Serlvet的初始化参数。

ServletConfig接口中定义了以下方法:
◆ getInitParameter(String name):根据给定的初始化参数,返回匹配的初始化参数值。
◆ getInitParameterNames():返回一个Enumeration对象,该对象包含了所有存放在web.xml中元素子元素中的所有的初始化参数名。
◆ getServletContext():返回一个servletContext()对象,
◆ getServltName():返回servlet的名字,即web.xml中的相对应的servlet的子元素的值。如果没有配置这个子元素,则返回servlet类的全局限定名。
Example:

actionServlet
org.apache.struts.action.ActionServlet

first
netfish


last
blog


actionServlet
*.do

如上,红色标记处为初始化参数,相当于servlet共享参数。
在servlet中:
public class BlogServlet extends HttpServlet {
String first = this.getInitParameter(“first”);
String last = this.getInitParameter(“last”);
System.out.println(“第一个参数:” + first + “第二个参数:” + last);
}
注:HttpServlet类继承了GenericServlet类,而GenericServlet类实现了ServletConfig接口,因此在HttpServlet类和GenericServlet类及子类中都可以直接调用ServletConfig接口中的方法。

八、 ServletContext

ServletContext是servlet与servlet容器之间的直接通信的接口。Servlet容器在启动一个Webapp时,会为它创建一个ServletContext对象,即servlet上下文环境。每个webapp都有唯一的ServletContext对象。同一个webapp的所有servlet对象共享一个ServeltContext,servlet对象可以通过ServletContext来访问容器中的各种资源。
ServletContext接口提供的方法分为以下几种类型:
用于在Webapp范围内存取共享数据的方法。
注:webapp范围具有以下两层含义:
(1) 表示有webapp的生命周期构成的时间段。
(2) 表示在webapp的生命周期内所有web组件的集合。
◆ setAttribute(String name, java.lang.Object object):以键值对的形式,把一个java对象和一个属性名绑定,并存放到ServletContext中,参数name指定属性名,参数Object表示共享数据。
◆ getAttribute(String name):根据参数给定的属性名,返回一个Object类型的对象。
◆ getAttributeNames():返回一个Enumeration对象,该对象包含了所有存放在ServletContext中的属性名。
◆ removeAttribute(String name):根据参数指定的属性名,从servletContext对象中删除匹配的属性。
访问当前Webapp的资源
◆ getContextpath():返回当前webapp的URL入口。
◆ getInitParameter(String name):返回webapp配置文件中匹配的初始化参数值。在web.xml中元素中子元素表示Webapp应用范围内的初始参数。
◆ getInitParameterNames():返回一个Enumeration对象,该对象包含了所有存放在web.xml中元素中子元素的初始化参数名。
◆ getServletContextName():返回webapp名称。即元素中子元素的值。
◆ getRequestDispatcher(String path):返回一个用于向其他web组件转发请求的RequestDispatcher对象。
访问servlet容器的相关信息
◆ getContext(String uripath):根据参数指定的url,返回当前servlet容器中其他web应用的servletContext()对象。
访问web容器的相关信息
◆ getMajorVersion():返回servlet容器支持的java servlet API 的主版本号。
◆ getMinorVersion():返回servlet容器支持的java Servlet API的次版本号。
◆ getServerInfo():返回servlet容器的名字和版本。
访问服务器端的文件系统资源
◆ getRealPath(String path):根据参数指定的虚拟路径,返回文件系统中的一个真实的路径。
◆ getResource(String path):返回一个映射到参数指定的路径的url。
◆ getResourceAsStream(String path):返回一个用于读取参数指定的文件的输入流。(把文件读到输入流中去)
◆ getMimeType(String file):返回参数指定的文件的MIME类型。
输出日志
◆ log(String msg):向servlet的日志文件中写日志。
◆ log(String message, java.lang.Throwable throwable):向servlet的日志文件中写错误日志,以及异常的堆栈信息。
ServletContext对象获得几种方式:
javax.servlet.http.HttpSession.getServletContext()
javax.servlet.jsp.PageContext.getServletContext()
javax.servlet.ServletConfig.getServletContext()
以上是servlet2.5版本及以前的获取方法。
servlet3.0中新增方法:
javax.servlet.ServletRequest.getServletContext()

ServletContext和ServletConfig二者区别
从作用范围来说,ServletConfig作用于某个特定的Servlet,即从该Servlet实例化,那么就开始有效,但是该Servlet之外的其他Servlet不能访问;ServletContext作用于某个webapp,即在一个webapp中相当于一个全局对象,在Servlet容器启动时就已经加载,对于不同的webapp,有不同的ServletContext。
其次,来看一下二者参数的使用。如果一个参数为整个webapp所用,那么就配置为ServletContext参数,如下所示:

ContextParam
hello, this is ServletContext param.

如果一个参数仅为一个Servlet所用,那么就应该配置为ServletConfig参数,如下所示:

servlet名称
servlet全局限定名

ServletParam
hello, this is ServletConfig param.


最后,说明一下参数的获取。访问ServletConfig参数,取得ServletConfig对象后,调用getInitParameter()方法;访问ServletContext对象,只要调用现有的ServletConfig对象的getServletContext()即可,然后同样调用getInitParamter()方法就能获取参数。例如对于上面的参数,可以通过如下方法获取各自参数。
public class GetParam extends HttpServlet {
ServletConfig config;
public void init(ServletConfig config) {
this.config=config;
}
public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
String servletparam=(String)config.getInitParameter(“ServletParam”);
System.out.println(servletparam);
String contextparam = (String)config.getServletContext().getInitParameter(“ContextParam”);
System.out.println(contextparam);
}
public void destroy() {
}
}

九、GET 请求和 POST 请求:

  1. 使用GET方式传递参数:
    ①.在浏览器地址栏中输入某个URL地址或单击网页上的一个超链接时,浏览器发出的HTTP请求消息的请求方式为GET。
    ②. 如果网页中的<form>表单元素的 method 属性被设置为了“GET”,浏览器提交这个FORM表单时生成的HTTP请求消息的请求方式也为GET。
    ③. 使用GET请求方式给WEB服务器传递参数的格式:

    http://localhost:8080/counter.jsp?name=lc&password=123
    

    ④. 使用GET方式传送的数据量一般限制在 1KB 以下。

  2. 使用 POST 方式传递参数:
    ①. POST 请求方式主要用于向 WEB 服务器端程序提交 FORM 表单中的数据: form 表单的 method 置为 POST
    ②. POST 方式将各个表单字段元素及其数据作为 HTTP 消息的实体内容发送给 WEB 服务器,传送的数据量要比使用GET方式传送的数据量大得多。

        POST /counter.jsp HTTP/1.1
        referer: http://localhost:8080/Register.html
        content-type: application/x-www-form-urlencoded
        host: localhost:8080
        content-length: 43
    

    ?name=zhangsan&password=123 –请求体中传递参数.

十、如何在 Serlvet 中获取请求信息:

  1. Servlet 的 service() 方法用于应答请求: 因为每次请求都会调用 service() 方法

    public void service(ServletRequest request, ServletResponse response)
    throws ServletException, IOException
    
    • ServletRequest: 封装了请求信息. 可以从中获取到任何的请求信息.
    • ServletResponse: 封装了响应信息, 如果想给用户什么响应, 具体可以使用该接口的方法实现.

    这两个接口的实现类都由服务器实现, 并在服务器调用 service 方法时自动传入参数.

  2. ServletRequest: 封装了请求信息. 可以从中获取到任何的请求信息.

    ①. 获取请求参数:

    • String getParameter(String name): 根据请求参数的名字, 返回参数值. 若请求参数有多个值(例如 checkbox), 该方法只能获取到第一个提交的值.
    • String[] getParameterValues(String name): 根据请求参数的名字, 返回请求参数对应的字符串数组.
    • Enumeration getParameterNames(): 返回一个Enumeration对象, 类似于ServletConfig(或ServletContext) 的getInitParameterNames() 方法.
    • Map getParameterMap(): 返回请求参数的键值对: key: 参数名, value: 参数值, String 数组类型.

    ②. 获取请求的 URI:

    HttpServletRequest hr = (HttpServletRequest) request;
    
    String requestURI = hr.getRequestURI();
    System.out.println(requestURI); //  /day_29/loginServlet
    

    ③. 获取请求方式:

    String method = hr.getMethod();
    System.out.println(method); //GET
    

    ④. 若是一个 GET 请求, 获取请求参数对应的那个字符串, 即 ? 后的那个字符串.

    String queryString = hr.getQueryString();
    System.out.println(queryString); //user=atguigu&password=123456&interesting=game&interesting=party&interesting=shopping
    

    ⑤. 获取请求的 Serlvet 的映射路径

    String servletPath = hr.getServletPath();
    System.out.println(servletPath);  //  /loginServlet
    

    ⑥. 和 attribute 相关的几个方法: 见JSP学习章节

  3. HttpServletRequest: 是 SerlvetRequest 的子接口. 针对于 HTTP 请求所定义. 里边包含了大量获取 HTTP 请求相关的方法.

  4. ServletResponse: 封装了响应信息, 如果想给用户什么响应, 具体可以使用该接口的方法实现.

    ①getWriter(): 返回 PrintWriter 对象. 调用该对象的 print() 方法, 将把 print() 中的参数直接打印
    到客户的浏览器上.

    ②设置响应的内容类型:

    response.setContentType("application/msword");
    

    ③void sendRedirect(String location): 请求的重定向. (此方法为 HttpServletResponse 中定义.)

十一、GenericServlet

  1. 是一个 Serlvet. 是 Servlet 接口和 ServletConfig 接口的实现类. 但是一个抽象类. 其中的 service 方法为抽象方法
  2. 如果新建的 Servlet 程序直接继承 GenericSerlvet 会使开发更简洁.
  3. 具体实现:
    ① 在 GenericServlet 中声明了一个 SerlvetConfig 类型的成员变量, 在 init(ServletConfig) 方法中对其进行了初始化
    ② 利用 servletConfig 成员变量的方法实现了 ServletConfig 接口的方法
    ③ 还定义了一个 init() 方法, 在 init(SerlvetConfig) 方法中对其进行调用, 子类可以直接覆盖 init() 在其中实现对 Servlet 的初始化.
    ④ 不建议直接覆盖 init(ServletConfig config), 因为如果忘记编写 super.init(config); 而还是用了 SerlvetConfig 接口的方法,则会出现空指针异常.
    ⑤新建的 init(){} 并非 Serlvet 的生命周期方法. 而 init(ServletConfig) 是生命周期相关的方法.

    public abstract class GenericServlet implements Servlet, ServletConfig {
    
    /** 以下方法为 Servlet 接口的方法 **/
    @Override
    public void destroy() {}
    
    @Override
    public ServletConfig getServletConfig() {
        return servletConfig;
    }
    
    @Override
    public String getServletInfo() {
        return null;
    }
    
    private ServletConfig servletConfig;
    
    @Override
    public void init(ServletConfig arg0) throws ServletException {
        this.servletConfig = arg0;
        init();
    }
    
    public void init() throws ServletException{}
    
    @Override
    public abstract void service(ServletRequest arg0, ServletResponse arg1)
            throws ServletException, IOException;
    
    /** 以下方法为 ServletConfig 接口的方法 **/
    @Override
    public String getInitParameter(String arg0) {
        return servletConfig.getInitParameter(arg0);
    }
    
    @Override
    public Enumeration getInitParameterNames() {
        return servletConfig.getInitParameterNames();
    }
    
    @Override
    public ServletContext getServletContext() {
        return servletConfig.getServletContext();
    }
    
    @Override
    public String getServletName() {
        return servletConfig.getServletName();
    }
    
    }
    

十二、HttpServlet:

  1. 是一个 Servlet, 继承自 GenericServlet. 针对于 HTTP 协议所定制.

  2. 在 service() 方法中直接把 ServletReuqest 和 ServletResponse 转为 HttpServletRequest 和 HttpServletResponse.
    并调用了重载的 service(HttpServletRequest, HttpServletResponse)

    在 service(HttpServletRequest, HttpServletResponse) 获取了请求方式: request.getMethod(). 根据请求方式有创建了
    doXxx() 方法(xxx 为具体的请求方式, 比如 doGet, doPost)

    public void service(ServletRequest req, ServletResponse res)throws ServletException, IOException {
    
        HttpServletRequest  request;
        HttpServletResponse response;
    
        try {
            request = (HttpServletRequest) req;
            response = (HttpServletResponse) res;
        } catch (ClassCastException e) {
            throw new ServletException("non-HTTP request or response");
        }
        service(request, response);
    }
    
    @Override
     public void service(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
        //1. 获取请求方式.
        String method = request.getMethod();
    
        //2. 根据请求方式再调用对应的处理方法
        if("GET".equalsIgnoreCase(method)){
            doGet(request, response);
        }else if("POST".equalsIgnoreCase(method)){
            doPost(request, response);
        }
    }
    
    public void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException{
        // TODO Auto-generated method stub
    }
    
    public void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        // TODO Auto-generated method stub
    
    }
    
  3. 实际开发中, 直接继承 HttpServlet, 并根据请求方式复写 doXxx() 方法即可.

  4. 好处: 直接由针对性的覆盖 doXxx() 方法; 直接使用 HttpServletRequest 和 HttpServletResponse, 不再需要强转.




*作业1

在 web.xml 文件中设置两个 WEB 应用的初始化参数, user, password.
定义一个 login.html, 里边定义两个请求字段: user, password. 发送请求到 loginServlet
在创建一个 LoginServlet, 在其中获取请求的 user, password. 比对其和 web.xml 文件中定义的请求参数是否一致
若一致, 响应 Hello:xxx, 若不一致, 响应 Sorry: xxx xxx 为 user.




*作业2

在 MySQL 数据库中创建一个 test_users 数据表, 添加 3 个字段: id, user, password. 并录入几条记录.

定义一个 login.html, 里边定义两个请求字段: user, password. 发送请求到 loginServlet
在创建一个 LoginServlet(需要继承自 HttpServlet, 并重写其 doPost 方法),
在其中获取请求的 user, password.

利用 JDBC 从 test_users 中查询有没有和页面输入的 user, password 对应的记录

SELECT count(id) FROM test_users WHERE user = ? AND password = ?

若有, 响应 Hello:xxx, 若没有, 响应 Sorry: xxx xxx 为 user.




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值