WEB_13【servlet】

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ccnuacmhdu/article/details/81227282

特此说明:本文参考传智播客、黑马程序员视频讲座 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

servlet简介

servlet(Server Applet)是运行在服务端的java小程序,是sun公司提供的一套规范(接口),用来处理客户端请求、响应给浏览器的动态资源。servlet实质就是java代码,通过java的API动态的向客户端输出内容。

servlet规范:包含三个技术点

  • 1)servlet技术
  • 2)filter技术(过滤器)
  • 3)listener技术(监听器)

servlet快速入门

通过在浏览器中输入访问地址,实现在控制台打印启动情况。操作步骤如下:

  • 新建一个Dynamic Web Project
  • 书写Servlet接口的实现类及service方法(默认会执行这个方法)
  • 书写web.xml配置文件

这里写图片描述
这里写图片描述

FirstServlet.java

package com.ccnuacmhdu.servlet;

import java.io.IOException;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class FirstServlet implements Servlet{

    public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
        System.out.println("FirstServlet starting...");

    }

    public void destroy() {
        // TODO Auto-generated method stub

    }

    public ServletConfig getServletConfig() {
        // TODO Auto-generated method stub
        return null;
    }

    public String getServletInfo() {
        // TODO Auto-generated method stub
        return null;
    }

    public void init(ServletConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }



}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>WEB13</display-name>

  <servlet>
    <servlet-name>FirstServlet</servlet-name>
    <servlet-class>com.ccnuacmhdu.servlet.FirstServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>FirstServlet</servlet-name>
    <url-pattern>/FirstServlet</url-pattern>
  </servlet-mapping>

  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

【实验结果】
这里写图片描述
这里写图片描述

【遇到的问题及解决方案】

书写Servlet接口实现类时,报红错,没有导入Servlet相关包的提示?

答:不要导入包,Tomcat自身就有相关的包,应该配置一个Tomcat服务器,选中工程—右键–Build Path–Configure Build Path–Libraries–Add Library–Server Runtime–Tomcat

Tomcat服务器启动老是失败?

答:换一个Tomcat服务器试试即可

Servlet的API(生命周期)

servlet接口包含的方法

书写一个Servlet接口的实现类,既可引入其方法,可以看到这些

    public void destroy() {
        // TODO Auto-generated method stub

    }

    public ServletConfig getServletConfig() {
        // TODO Auto-generated method stub
        return null;
    }

    public String getServletInfo() {
        // TODO Auto-generated method stub
        return null;
    }

    public void init(ServletConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }

    public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
        // TODO Auto-generated method stub

    }

测试每个方法何时执行的时候,要从服务器开始启动开始来测!可以在每个方法中在控制台打印一些信息,来进行测试

  • 1)init(ServletConfig config)
    servlet对象创建的时候执行
    ServletConfig :该servlet对象的配置信息,可以通过调用这个对象的方法拿到Servlet的一些配置信息
  • 2)service(ServletRequest request,ServletResponse response)
    每次请求都会执行
  • 3)destroy()
    servlet销毁的时候执行

Servlet的生命周期

  • 1)Servlet何时创建 :默认(注意这里说的是默认,另外可以通过一些配置,让服务器在启动的同时就创建)第一次访问servlet时创建该对象
  • 2)Servlet何时销毁 :服务器关闭servlet就销毁了
  • 3)每次访问必然执行的方法: service(ServletRequest req, ServletResponse res)方法

由上面可知,默认情况下,第一次通过浏览器访问的时候服务器创建Servlet对象,通过对象来调用init方法(仅执行一次),service方法(每次访问都会执行)。注意init方法、service方法等都不是静态方法,必须通过对象来调用,Servlet对象是Tomcat服务器创建的。

Servlet访问的大致过程

这里写图片描述
这里写图片描述

Servlet配置

  • 书写配置文件时候,各个配置信息的先后顺序也要注意,顺序变动,可能会报错
  • 注意全局web.xml,Tomcat服务器下的conf文件夹下的web.xml是一个全局配置文件,对Tomcat下的所有工程都适用,如果自己写的工程里面的配置信息和这个全局的web.xml配置信息有重合部分,则自己的会覆盖掉全局的。

基本配置

 <!-- Servlet类的配置 -->
  <servlet>
    <servlet-name>FirstServlet</servlet-name>
    <servlet-class>com.ccnuacmhdu.servlet.FirstServlet</servlet-class>
  </servlet>
  <!-- Servlet虚拟路径配置 -->
  <servlet-mapping>
    <servlet-name>FirstServlet</servlet-name>
    <url-pattern>/FirstServlet</url-pattern>
  </servlet-mapping>

url-pattern的三种配置方式:

  • 1)完全匹配,访问资源地址与配置资源地址必须完全一致
    <url-pattern>/FirstServlet</url-pattern>
  • 2)目录匹配。下面的例子是目录/abc/def/下面的所有资源都可以访问到 “`
    /abc/def/*

 - 3)扩展名匹配。下面的例子是只要是以扩展名.abc结束的资源都可以访问到 ```
   <url-pattern>*.abc</url-pattern> ```

服务器启动实例化Servlet配置

Servlet**默认**情况下是第一次访问时创建对象的。现在要通过配置,使得在启动服务器的时候就创建Servlet对象:<load-on-startup>3</load-on-startup>这个数越小,优先级越高。

<servlet>
    <servlet-name>FirstServlet</servlet-name>
    <servlet-class>com.ccnuacmhdu.servlet.FirstServlet</servlet-class>
    <load-on-startup>3</load-on-startup>
  </servlet>

缺省Servlet

将url-pattern配置一个/,代表该servlet是缺省的servlet。当访问资源地址所有的servlet都不匹配时 , 缺省的servlet负责处理。
其实,web应用中所有的资源的响应都是servlet负责,包括静态资源

注意在Tomcat的全局配置文件web.xml中也配置了缺省servlet:

<servlet-mapping>
        <servlet-name>default</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
<servlet>
        <servlet-name>default</servlet-name>
        <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>0</param-value>
        </init-param>
        <init-param>
            <param-name>listings</param-name>
            <param-value>false</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

欢迎页面

<welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>

当请求资源地址是上面是http://localhost:8080/WEB13/默认打开的页面是index.html如果工程WebContent下没有index.html,默认打开index.htm,以此类推。
如果工程里面写了index.html,把上面的配置信息删除,发现再次访问,也会默认打开index.html,这是为什么呢?因为在Tomcat的全局配置文件web.xml里面已经配置了:

<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>

HttpServlet类

为什么可以只写doGet方法和doPost方法?(查看源码说明这个问题)

  • 实际开发中使用的是HttpServlet类,而不是上面介绍的Servlet接口。而HttpServlet类本身继承了GenericServlet类,GenericServlet类实现了Servlet接口。可以导入Tomcat源码,在类名上Ctrl点击依次查看源码。
  • 可以直接新建一个Servlet,建好后,相应的配置信息也会在配置文件中配置好。当访问时,寻找service方法,但是HttpServlet本身没有这个方法,于是就从HttpServlet的父类以及所实现的接口不断寻找上一级,查看源代码发现在HttpServlet中可以找到service方法,再看源码,发现这个方法会调用另一个已经写好的service方法,而这个service方法里面就有doGet方法和doPost方法的调用选择。我们会重写doGet方法和doPost方法,所以在通过service调用doGet方法或doPost方法时就是在调用我们自己写的方法。
package com.ccnuacmhdu.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class SecondServlet
 */
public class SecondServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public SecondServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        response.getWriter().append("Served at: ").append(request.getContextPath());
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}

怎么自定义模板?

  • 上面有很多无用的注释,为了想直接去除所有注释,我们引入了自定义模板,可以通过自己定义模板。Windows—Preferences—Java—Editor—Templates。定义完模板之后,再输入模板名字,就能联想出来这个模板的代码啦!

实例:用户登录

使用原生JDBC
数据库:
这里写图片描述
这里写图片描述
login.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <form action="/WEB13/login" method="post">
        用户名:<input type="text" name="username"><br/>
        密码:<input type="password" name="password"><br/>
        <input type="submit" value="登录"><br/>
    </form>
</body>
</html>

LoginServlet.java

package com.ccnuacmhdu.login;

import java.io.IOException;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;

import org.apache.catalina.User;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import com.ccnuacmhdu.utils.DataSourceUtils;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;

public class LoginServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1、获得用户名和密码
        String username = request.getParameter("username");
        String password = request.getParameter("password");

         //1.注册驱动
        try {
            Class.forName("com.mysql.jdbc.Driver");
             //2.获得链接
            Connection connection=(Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/web13","root","123");
            //3.创建执行sql语句的对象
            Statement statement=(Statement) connection.createStatement();
            //4.书写SQL语句
            String sql="select * from user where "+"username='"+username+"' and password='"+password+"'";
            //5.执行SQL语句
            ResultSet resultSet=statement.executeQuery(sql);
            //6.处理结果集
            if(resultSet.next()) {
                System.out.println("恭喜您,"+username+"登录成功!");
                response.getWriter().write("success");



            }
            else {
                System.out.println("账号或密码错误!");
                response.getWriter().write("fail");
            }

            if(resultSet!=null){
                resultSet.close();
            }
            if(statement!=null) {
                statement.close();
            }
            if(connection!=null) {
                connection.close();
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }


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

        doGet(request, response);
    }

}

User.java

package com.ccnuacmhdu.domain;

public class User {
    private int id;
    private String username;
    private String password;
    private String email;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", password=" + password + ", email=" + email + "]";
    }

}

web.xml主要配置

<servlet>
    <description></description>
    <display-name>LoginServlet</display-name>
    <servlet-name>LoginServlet</servlet-name>
    <servlet-class>com.ccnuacmhdu.login.LoginServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>LoginServlet</servlet-name>
    <url-pattern>/login</url-pattern>
  </servlet-mapping>

这里写图片描述
这里写图片描述

ServletContext对象

什么是ServletContext?
ServletContext代表一个web应用的环境(上下文)对象,内部封装该web应用的信息,每个web应用只有一个。
ServletContext对象的生命周期?
创建:该WEB应用被加载(应用发布)
销毁:该WEB应用被卸载(从服务器中移除web应用或关闭服务器)
怎么获得ServletContext对象?
方法一:ServletContext servletContext = config.getServletContext();
方法二:ServletContext servletContext = this.getServletContext();

ServletContext对象的作用

(1)获取web应用全局初始化参数
在web应用中配置如下:
这里写图片描述
获取配置参数如下,发布应用到Tomcat,访问http://localhost:8080/WEB13/ContextServlet控制台打印value

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获得ServletContext对象
        ServletContext servletContext = this.getServletContext();
        //获得全局初始化参数
        String ininParameter = servletContext.getInitParameter("key");
        System.out.println(ininParameter);
    }

(2)获得web应用中任何资源的绝对路径(重要*重要重要!!!)*

package com.ccnuacmhdu.servlet;

import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ContextServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获得ServletContext对象
        ServletContext servletContext = this.getServletContext();

        //获得全局初始化参数
        String ininParameter = servletContext.getInitParameter("key");
        System.out.println(ininParameter);

        //获得绝对路径(相对于web应用,即WEB13,指的是发布到Tomcat之后的
        //a.txt不在WebContent下,不会发布到Tomcat,不能找到a.txt的路径
        String realPath_b = servletContext.getRealPath("/WEB-INF/b.txt");
        System.out.println(realPath_b);

        String realPath_c = servletContext.getRealPath("/WEB-INF/classes/c.txt");//src会发布到classes
        System.out.println(realPath_c);

        String realPath_d = servletContext.getRealPath("d.txt");
        System.out.println(realPath_d);



    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // TODO Auto-generated method stub
        doGet(request, response);
    }

}

控制台打印如下:
value
D:\apache-tomcat-7.0.52\webapps\WEB13\WEB-INF\b.txt
D:\apache-tomcat-7.0.52\webapps\WEB13\WEB-INF\classes\c.txt
D:\apache-tomcat-7.0.52\webapps\WEB13\d.txt

注意:上述获取的路径就是发布到Tomcat中的应用的路径

还可以使用类加载器进行获得绝对路径,这是传入的参数不是相对于应用的路径,而是相对于classes的路径,具体代码及结果如下:

//用类加载器获取路径,是相对于classes的路径
        String path_b = ContextServlet.class.getClassLoader().getResource("../b.txt").getPath();
        System.out.println(path_b);

        String path_c = ContextServlet.class.getClassLoader().getResource("c.txt").getPath();
        System.out.println(path_c);

        String path_d = ContextServlet.class.getClassLoader().getResource("../../d.txt").getPath();
        System.out.println(path_d);

打印结果

/D:/apache-tomcat-7.0.52/webapps/WEB13/WEB-INF/b.txt
/D:/apache-tomcat-7.0.52/webapps/WEB13/WEB-INF/classes/c.txt
/D:/apache-tomcat-7.0.52/webapps/WEB13/d.txt
(3)ServletContext是一个域对象(重要!!!)
一个应用中有一个ServletContext对象,有多个Servlet对象。把ServletContext类比成一个箱子,Servlet类比成若干个顾客,所有的Servlet都可以把东西(键值对)存到ServletContext,其他的Servlet都可以根据ServletContext里面的键拿到值。
ServletContext域对象作用范围:整个web应用(所有web资源都可以随意向ServletContext域中存取数据,数据可以共享)

域对象通用的方法:
setAttribute(String name,Object obj);
getAttribute(String name);
removeAttribute(String name);

实例:显示第几个用户登录的
在上一个用户登录实例的基础上,改进!
在LoginServlet类里增加:

@Override
    public void init() throws ServletException {
        Integer count = 0;
        this.getServletContext().setAttribute("count", count);
    }

改进:

 if(resultSet.next()) {
                ServletContext servletContext = this.getServletContext();
                Integer count = (Integer) servletContext.getAttribute("count");
                count++;
                System.out.println("恭喜您,"+username+"登录成功!,您是第"+count+"个登录的");
                response.getWriter().write("成功登录,您是第"+count+"个登录的");
                servletContext.setAttribute("count", count);

            }

重新发布工程,即可!

猜你喜欢

转载自blog.csdn.net/ccnuacmhdu/article/details/81227282