美文网首页
Servlet札记

Servlet札记

作者: 一只96年的程序猿 | 来源:发表于2018-08-15 16:08 被阅读0次

    Servlet概述

    Servlet是由SUN公司提供的动态web资源开发技术, 本质上是一段java程序, 这段java程序无法独立运行, 必须放在Servlet容器(比如: tomcat服务器)中, 由容器调用才可以执行!

    [toc]


    • 简单开发一个Servlet程序

    1.开发步骤

    (1).写一个类,实现一个Servlet接口,并添加未实现 的方法

    (2).将编译后类,放在WEB应用中,并在WEB应用web.xml文件中配置Servlet对外访问的虚拟路径,将WEB应用部署到虚拟主机中即可

    2.开发过程

    (1)需求

    浏览器向服务器发送一个请求, 访问FirstServlet, FirstServlet将表示当前时间的字符串发送浏览器

    (2)创建一个FirstServlet.java文件

    (3)编写FirstServlet类

    • 实现Servlet接口(或继承Servlet接口的子类),并添加未实现的方法(java_ee_api文档)
    • 实现Servlet中提供的处理请求方法service方法, 将表示当前时间的字符串响应给浏览器
    • 添加servlet类的包路径和导入依赖包
    package com.zn.servlet;
    import java.io.*;
    import java.util.*;
    import javax.servlet.*;
    
    public class FirstServlet extends GenericServlet{
        public void service(ServletRequest req, ServletResponse res) 
        throws ServletException, java.io.IOException{
            String datastr = new Date().toLocaleString();;
            res.getWriter().write(datastr);
        }
        
    }
    

    (4)编译FirstServlet类

    在cmd窗口通过命令编译出现报错信息:

    E:\>javac FirstServlet.java
    FirstServlet.java:4: 错误: 程序包javax.servlet不存在
    import javax.servlet.*;
    ^
    FirstServlet.java:6: 错误: 找不到符号
    public class FirstServlet extends GenericServlet{
                                      ^
    

    原因是 javax.servlet这个包不存在, 所有下面出现了很多找不到符号错误.
    在tomcat服务器的lib目录下有servlet的jar包, 可以设置包路径:

    设置包路径
    E:\>set classpath=...\apache-tomcat-7.0.53\lib\servlet-api.jar
    

    再次编译

    /*带包编译:
                进入到FirstServlet.java所在路径
                命令: javac -d . FirstServlet.java 
                其中: -d是带包编译
                     点(.)表示编译后的class存放在当前目录下*/
    
    E:\>javac -d . FirstServlet.java
    

    (5)将FirstServlet类放在WEB应用中, 并在web.xml文件中配置Servlet对外访问的虚拟路径

    • 将编译好的class文件(包括包路径)放在web应用的classes目录下
    • 在WEB应用的web.xml文件中配置servlet对外访问的虚拟路径:
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
      version="3.0"
      metadata-complete="true">
    
      <welcome-file-list>
        <welcome-file>login.html</welcome-file>
      </welcome-file-list>
     
      <!-- servlet settings -->
      <servlet>
          <servlet-name>FirstServlet</servlet-name>
          <servlet-class>com.zn.servlet.FirstServlet</servlet-class>
        </servlet>
        <servlet-mapping>
          <servlet-name>FirstServlet</servlet-name>
          <url-pattern>/FirstServlet</url-pattern>
        </servlet-mapping>
    
    </web-app>
    

    (7)将WEB应用部署到虚拟主机中, 启动服务器, 通过浏览器访问FirstServlet

    • Servlet继承结构

    Servlet继承结构
    Servlet接口 – 通用的Servlet接口,提供了一个Servlet应该具有的功能 
        | 
        |-- GenericServlet类, 实现了Servlet接口
            并实现了其中的大部分的方法,但是service方法没有实现, 
                |
                |-- HttpServlet类,实现了service方法
                    在service方法中, 判断请求方式
                    根据不同的请求方式xxx调用不同doXxx
                       |
                       |-- XxxServlet类, 在开发中,     
                           继承HttpServlet, 
                           并覆盖doGet和doPost方法, 
                           来处理GET请求和POST请求
    
    • Servlet调用过程

    开发一个Servlet, 放在WEB应用中, 并将WEB应用部署在服务器中, 启动服务器, 通过浏览器访问Servlet, 可以访问到Servlet处理的结果, 这个Servlet是如何被调用的, Servlet又是如何执行的?


    Servlet调用过程.png

    1.Servlet生命周期

    Servlet在第一次被访问时创建Servlet实例, 创建之后服务器会立即调用init方法进行初始化的操作

    创建之后, Servlet实例会一直驻留在服务器的内存中, 为后续的请求服务. 只要有请求来访问这个Servlet, 服务器就会调用service方法来处理请求, 直到服务器关闭, 或者WEB应用被移出容器

    随着WEB应用的销毁, Servlet实例也会跟着销毁, 在销毁之前服务器会调用destroy方法进行善后的处理

    • Servlet开发细节

    1.Servlet虚拟路径的配置

    Servlet在web.xml文件中虚拟路径的配置方式可以有两种方式:

    (1) 直接写一个路径

    后期需要通过 /FirstServlet这个路径来访问该Servlet

     <!-- servlet settings -->
      <servlet>
          <servlet-name>FirstServlet</servlet-name>
          <servlet-class>com.zn.servlet.FirstServlet</servlet-class>
      </servlet>
        <servlet-mapping>
          <servlet-name>FirstServlet</servlet-name>
          <url-pattern>/FirstServlet</url-pattern>
        </servlet-mapping>
      
    

    (2) 还可以使用星号(*)匹配符来配置一个路径,配置的方式有两中:

    • 以斜杠(/)开头,以斜杠星(/*)结尾

      /* , /a/* ...
    • 以星点后缀(*.后缀)的形式

      *.html , *.abc, *do...

    使用星号匹配符可以使得路径的访问变得更加灵活, 但是也可能会导致一个url会被多个mapping所匹配。路径的优先级规则是什么?

    (1)哪一个更接近(更精准、更像)哪一个起作用

    (2)*.后缀的优先级永远最低.

    • Request

    代表HTTP请求的对象。浏览器向服务器发送一个请求,服务器在调用Servlet的service方法处理请求之前,会创建代表Http请求的request对象,将所有的请求信息封装在request对象中。

    1.Request的继承结构

    ServletRequest -通用的Request接口,提供一个Request对象应该具有的功能
        |
        |-- HttpServletRequest接口 - 
            继承了ServletRequest接口, 
            在父接口的基础上, 
            HttpServletRequest增加了一些和Http协议相关的方法
    

    2.Request对象提供的功能

    (1)获取客户端基本信息、获取请求头信息
    /** Request获取客户机的基本信息、获取请求头信息
     * @author: zn
     * @time: 2018年8月16日,上午10:13:20
     */
    public class RequestDemo1 extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            //1.getRemoteAddr() -- 获取ip地址
            String ip = request.getRemoteAddr();
            System.out.println("ip:"+ip);
            
            //2.getContxtPath() --获取web应用虚拟路径
            String path = request.getContextPath();
            System.out.println("path:"+path);
            
            //3.getHader() --获取请求头信息
            String host = request.getHeader("host");
            System.out.println("host:"+host);
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    
    }
    
    (2)获取请求参数
    header 1 header 2
    getParameter(String name) 通过请求参数的名字获取对应的参数值
    getParameterValues(String name)
    getParameterMap()
    getParameterNames()
    请求参数乱码问题

    在通过request对象获取请求参数时, 如果参数中有中文数据, 在获取时就会出现乱码, 其原因是由于浏览器发送参数时(编码时)使用的码表 和 服务器在结束数据时(解码时)使用的码表不一致造成的.


    请求参数乱码

    解决方案:让编码时使用的码表和解码时使用的码表保持一致即可

    • 手动编解码解决乱码,通用,适应POST和GET

    (1)根据获取的乱码字符串,反向编码得回正确的二进制数据(iso8859-1)
    (2) 将二进制数组查询utf-8码表转成字符串, 得回正确的数据

    • 如果请求方式是POST,可以通过request提供的方法解决

    (1)request.setCharacterEncoding(“utf-8”);//这行代码是通知服务器使用utf-8来接收请求

    (2)必须放在任何获取参数代码之前,否则无法生效

    (3)GET提交的参数在请求行中的请求资源路径后面拼接着, 不在请求实体内容中,所有这行代码对GET提交产生的乱码不会起作用!

    /** 通过Request获取请求参数
     * @author: zn
     * @time: 2018年8月16日,上午10:33:44
     */
    public class RequestDemo2 extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            /**
             * 通知服务器使用UTF-8接收请求实体内容中的数据,对POST提交的乱码起作用
             */
            request.setCharacterEncoding("utf-8");
            
            //获取用户名
            String username = request.getParameter("username");
            //获取用户昵称
            String nickname = request.getParameter("nickname");
            System.out.println("username:"+username+"\nnickname:"+nickname);
            
            //获取爱好
            String[] likes = request.getParameterValues("like");
            System.out.println("likes"+Arrays.toString(likes));
            
            //================= GET乱码解决 =======================//
            byte[] bytes = username.getBytes("iso8859-1");
            username = new String(bytes,"utf-8");
            System.out.println("GET-> username:"+username);
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            doGet(request, response);
        }
    
    }
    ![请求转发](https://img.haomeiwen.com/i4495072/928577dda76eb86e.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    
    (3)实现请求转发
    • 请求重定向:实现资源的跳转

    • 请求转发:实现资源的跳转,并且是服务器

    相关文章

      网友评论

          本文标题:Servlet札记

          本文链接:https://www.haomeiwen.com/subject/mbywbftx.html