zoukankan      html  css  js  c++  java
  • Servlet

    Servlet

    Servletsun公司提供的一种用于开发动态web资源的技术

    为了方便web服务器对动态web资源的管理,sun公司在其api中定义了一个Servlet接口

    服务器针对接口进行调用,我们编写的应用程序针对接口进行实现

     

    习惯性地,我们把实现了Servlet接口的java类统称为Servlet

    1. javaweb 学什么

    用 java 语言开发动态的web资源,接下来就是介绍如何开发动态的web资源

    对于java程序员而言,所谓动态web资源就是可以运行在服务器上的java程序

    2. 实现服务器管理java程序

    开发人员写好一个java,到底有哪些方法tomcat服务器是不可能知道的

    tomcat服务器需要执行我们编写的java类就需要知道我们的java类有哪些方法,然后在适当的时间调用这些方法所以我们在写的java程序要想运行在服务器上就必须要实现一个特殊的接口 Servlet.java

     

    interface Servlet { ... }

    Servlet 接口中就定义了可以被tomcat服务器调用的java方法

    通常来讲,我们将实现了Servlet接口的java类称之为 Servlet

     

    编写好的Servlet需要web.xml文件中做配置才能供外界访问

     

    3. 实现第一个Servlet程序

    3.1  写一个java类实现Servlet接口

    package cn.itcast.servlet;

     

    import java.io.*;

    import javax.servlet.*;

     

    public class HelloWorldServlet extends GenericServlet

    {

     

    // 实现 service 方法

    public void service(ServletRequest request,ServletResponse response)

    throws ServletException,java.io.IOException  {

     

    // 向浏览器输出一句话

    PrintWriter out = response.getWriter();

    out.write("hello world!!!");

     

    }

     

    public void init()throws ServletException {

    // 初始化 servlet 时被调用

    System.out.println("init()");

    }

     

    public void destroy() {

    // 摧毁 servlet 时被调用

    System.out.println("destroy()");

    }

    }

     

     

    3.2.  导入 servlet jar

    set classpath=%classpath%;D:apache-tomcat-6.0.20libservlet-api.jar 3.3. 编译带包的类

    javac -d . HelloWorldServlet.java

    3.4. 将包拷贝至 day05/WEB-INF/classes 目录下  --> 发布 web 工程

     

    3.5. 在 web.xml 文件中做映射

    <!-- servlet映射 -->

    <!-- servlet元素用于给一个类起别名 -->

    <servlet>

    <servlet-name>HelloWorldServlet</servlet-name>

    <servlet-class>cn.itcast.servlet.HelloWorldServlet</servlet-class>

    </servlet>

    <!-- servlet-mapping元素用于将一个Servlet映射到url -->

    <!—url必须以/开头,表示当前web应用即上下文路径 -->

    <servlet-mapping>

    <servlet-name>HelloWorldServlet</servlet-name>

    <url-pattern>/HelloWorldServlet</url-pattern>

    </servlet-mapping>

     

    注意: servlet 对象一旦创建就会驻留在内存中,为所有的请求服务,什么时候销毁

    直到服务器关闭时或web应用被移除才销毁

     

    3.6. Servlet 执行流程图

     

     

    4. 用 eclipse 工具开发 Servlet

     4.1. 建一个 web project

     4.2. src下建包,创建一个java类实现Servlet接口

     4.3  在 WebrootWEB-INFweb.xml 做 servlet 映射

    4.4  配置 tomcat 服务器

    window--> preferences --> tomcat6.x

    4.5  web工程发布至tomcat 服务器

    发布的web应用名称可以配置: web工程右键 选properties-->myeclipse-->web

    默认情况使用工程名作为发布后的web应用名

     

    4.6 启动tomcat服务器运行程序

     

    5. HttpServlet对象

    一般来讲我们开发一个Servlet会去继承 HttpServlet

    在 eclipse 下开发Servlet 可以直接新建一个Servlet, 覆写 HttpServlet 的 doGetdoPost方法

    继承 HttpServlet 的原因是: HttpServlet实现了service方法,将ServletRequstServletResponse

    强转为子类 HttpServletRequestHttpServletResponse,让我们用起来更加方便,同时,在service方法中,它判断了请求方式,根据请求方式来调用 doGet 和 doPost

     

     Servlet 细节

    1. * 号统配符

    一个Servlet可以映射为多个路径

    在映射 Servlet 路径时可以使用‘/*’ 或 ‘*.扩展名’ 的形式

    注意两者不能同时使用

    /* 具有较高的优先级

     

    2. load-on-startup 元素

    <servlet>元素下可以配置< load-on-startup>子元素,

    配置方式如下:

    <load-on-startup>1</load-on-startup>

    如果一个Servlet配置了该项,web容器会在web应用被加载时就初始化该Servlet,数字越小则越先初始化

     

    3. tomcatconfweb.xml

    服务器下所有web 应用中的web.xml 都会自动继承该文件中所有的配置

    http://localhost:8080/day05/a.html     a.html是资源名

    上面的url访问的urlweb.xml文件中并没有配置

    此时会去访问缺省的Servlet,在tomcatconfweb.xml文件中就配置了一个缺省的DefaultServlet  DefaultServlet帮我们去web应用下读取 a.html 文件,并打给浏览器,如果没有发送 404 页面

    也就说,我们通过ie访问服务器访问的都是 Servlet

     

    4. Servlet线程安全问题

    解决Servlet线程安全问题: 加上同步的锁(lock)

     

     实现SingleThreadModel接口的Servlet

    服务器会做判断,当有请求过来,如果Servlet对象忙着呢,服务器会再创建一个Servlet对象为用户

    提供服务,如果Servlet闲置,就直接提供服务

    这样的方式实际上是回避了线程安全问题, 单线程访问Servlet, 这样的方式不可取

     ServletConfig 对象

     

    作用 : 封装 Servlet 初始化参数

    1. 可以在 web.xml 文件中 Servlet 元素下 为Servlet配置初始化参数

    <init-param>

         <param-name>name</param-name>

         <param-value>aaaa</param-value>

    </init-param>

    2. web 容器在初始化Servlet时,会将初始化参数封装到一个 ServletConfig 对象中,传给init方法

    3. 我们在Servlet 中覆写 init方法,就可以获得ServletConfig

    4. 父类 GenericServlet 中定义了一个成员变量用于记住此对象,并提供了 getServletConfig 方法

    我们可以直接调用此方法 获得 config 对象

    5. 再调用 getInitParameter(name) 方法获得想要配置项

    // 指定编码

    // 获得ServletConfig 对象

    ServletConfig config = getServletConfig();

    String encoding = config.getInitParameter("encoding");

    System.out.println("encoding=" + encoding);

    ServletContext 对象

     

    1. ServletContext对象代表整个web应用

    2. ServletContext对象是一个域对象(可以存储数据的对象)

    ServletContext对象的内部维护了一个map集合, keyString类型 valueObject类型

    class ServletContext {

    private Map<String, Object> map ; 

    }

    通常来讲,我们会将全局的数据存入 ServletContext 域对象

    3. ServletContext 作为域对象, 多个Servlet 可以共享数据

    Servlet6

    // 1. 获得ServletContext 对象

    ServletContext context = getServletContext();

    // 2. 存入域

    context.setAttribute(“name”, “zhangsan”);

    Servlet7

    // 获得 context 域, getAttribute

    String name = (String) getServletContext().getAttribute("name");

    4.获取web应用的初始化参数

    getContext().getInitParameter(“name”);

    5. 统计一个web应用的访问量

       在 context 域中维护一个count变量

      访问Servlet时,取出变量 加1

    6. 实现请求转发

    实现请求转发需要用到 转发对象 RequestDispatcher 

    有一个 forward 方法能转发请求

    7. 如何读取工程中的文件

    7.1.  读取web工程下的资源文件

    // 获得绝对路径

          String realPath = ServletContext.getRealPath(相对web应用的路径);

    注意URL url =  ServletContext.getResource();  weburl

    // 获得与文件关联的流

    InputStream in=

     ServletContext.getResourceAsStream(“WEB-INF/classes/config.properties”;

    7.2   读取java工程下的文件

    // 不能相对虚拟机目录 不能用绝对路径

      // 只能类加载的方式读

    // 获得 流

    ClassLoader classLoader = Demo.class.getClassLoader();

    InputStream in = classLoader.getResourceAsStream("a.txt");

    // 获得绝对路径

    URL url = Demo.class.getClassLoader().getResource("a.txt");

    String path = url.getPath();

    类加载方式缺点

    1) 不能读取类路径以外文件

    2)  由于需要加载到内存,不能读大文件

    web工程中如果用类加载的方式读

    类加载实际上读取的是内存中加载的文件,此时将读不到硬盘上资源文件的修改

    解决办法Demo.class.getClassLoader().getResource("a.txt").getPath()

    通过绝对路径去读硬盘上的文件  避开内存的文件

    Servlet缓存

     

    HttpServlet 的 Service方法中的代码

    // 调用方法

    long lastModified = getLastModified(req);

    // 如果为 -1 ,就直接放行,给最新的

                if (lastModified == -1) {

                    doGet(req, resp);

    }

    // 方法返回不是-1  else {

    // 读取IE发送的头If-Modified-Since

                    long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);

    // 拿着客户端的时间头和方法的返回值比较

                    if (ifModifiedSince < (lastModified / 1000 * 1000)) {

                        // If the servlet mod time is later, call doGet()

                        // Round down to the nearest second for a proper compare

                        // A ifModifiedSince of -1 will always be less

    // 方法的返回值大于ie发送过来的时间头

    // 重新向浏览器发送了一个时间头

                        maybeSetLastModified(resp, lastModified);

    // 放行, 发送页面

                        doGet(req, resp);

                    } else {

    // 方法的返回值没有大于ie发送过来的时间头

    // 发送 304 状态码,让用户去读缓存

                        resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);

                    }

                }

     

  • 相关阅读:
    ArcGIS添加鹰眼
    C#设计模式--工厂方法
    C#设计模式--简单工厂
    C# 单例模式(转)
    事务的 原子性、一致性、隔离性、持久性
    asp.net 常用的3中身份验证
    angular localStorage使用方法
    angular.js升序降序过滤器
    ionic中$ionicPopover和$ionicModal
    ionic的弹出框$ionicPopover
  • 原文地址:https://www.cnblogs.com/qq809306794/p/3183215.html
Copyright © 2011-2022 走看看