栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

实训日志(Servlet的概念和使用)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力
Servlet

文章目录
  • Servlet
    • 一、概述
    • 二、集成Tomcat
      • 2.1 创建Web项目
      • 2.2 配置tomcat
      • 2.3 测试
    • 三、Servlet的三种实现方式
      • 3.1 实现原生的Servlet接口
      • 3.2 继承GenericServlet
      • 3.3 继承HttpServlet
    • 四、Servlet的两种配置方式
      • 4.1 xml配置文件
      • 4.2 @webservlet注解的配置方式
    • 五、案例:在前端页面展示所有数据
    • 六、转发和重定向
      • 6.1转发
      • 6.2 重定向
      • 6.3 get和post的区别
    • 七、生命周期
    • 八、Cookie和Session
      • 8.1 Cookie
        • 8.1.1 添加Cookie
        • 8.1.2 获取Cookie
        • 8.1.3 修改Cookie
        • 8.1.4 Cookie优缺点
      • 8.2 Session
        • 8.2.1 原理
        • 8.2.2 Session使用
        • 8.2.3 Session和request的区别
        • 8.2.4 验证码
    • 九、ServletContext
      • 9.1 概述
      • 9.2 获取对象
      • 9.3 作用
      • 9.4 特点
      • 9.5 案例:记录程序的访问次数
    • 十、过滤器
      • 10.1 实现
      • 10.2 配置
      • 10.3 过滤器链和优先级
        • 10.3.1 过滤器链
        • 10.3.2 优先级
        • 10.3.3 实例(处理乱码)
      • 10.4 案例

一、概述

Servlet:Server Applet,是服务器端的一个程序(代码、功能实现),可交互式的处理客户端发送到服务器端的请求,并完成响应操作,实现前后端的交互。

  • 动态网页技术:Servlet、Jsp(el, jstl)、第三方框架(SSM,SSH)。
  • 静态网页技术:HTML、CSS。
二、集成Tomcat 2.1 创建Web项目

IDEA2022为例

  • 首先创建一个新的普通项目

  • 右键项目—>添加框架支持—>选中Web项目
    (这里已经创建过了所以没有显示)
2.2 配置tomcat

使用版本为Tomcat 8.5.41

  • 点击右上角启动项目旁边的编辑配置,选中已安装的tomcat,设置可保持默认。

  • 点击部署添加启动时部署

  • 导入Servlet.jar包

    在WEB-INF下创建lib包,将apache-tomcat-8.5.41.zip添加到库

  • 可能遇到的问题

    • tomcat版本过高会出现可能会出现404 NOT FOUND此时可以下降tomcat的版本。

    • 其他问题可上网查找,一般可解决大部分问题。

    • 
      
2.3 测试
  • 点击运行,运行成功会弹出网页。

三、Servlet的三种实现方式 3.1 实现原生的Servlet接口
	package lhnservetest;

import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;


@WebServlet("/demo1")
public class ServletTest implements Servlet {

    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("初始化方法");
    }

    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("处理业务核心方法");

    }

    @Override
    public String getServletInfo() {
        System.out.println("获取servlet的信息");
        return null;
    }

    @Override
    public void destroy() {
        System.out.println("销毁");

    }
}

3.2 继承GenericServlet
  • 使得servlet的编写更加简单,它提供了生命周期的init方法和destory方法的简单实现;如果需要写servlet时,只需重写抽象的service方法即可。
  • GenericServlet是Servlet的接口类。
  • 缺点:不区分请求类型
package lhnservetest;

import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;



@WebServlet("/demo2")
public class GenricServlet extends GenericServlet {
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("只需重写servlet方法即可");

    }
}

3.3 继承HttpServlet
  • HttpServlet是继承GenericServlet,在其基础上对service功能进行了拓展提升。

  • 为符合http的协议的开发规范,对service方法进行了重构,产生了两个新方法:

    doGet() 和 doPost()

    • doGet():支持HTTP的GET请求。
    • doPost():支持HTTP的POST请求。
  • HttpServletRequest、HttpServletResponse

package lhnservetest;

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


@WebServlet(name="/demo1",urlPatterns = "/demoHttpServlet",loadOnStartup = -1)
public class HttpServlet extends javax.servlet.http.HttpServlet {

    @Override
    public void init() throws ServletException {
        System.out.println("初始化servlet");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("统一处理请求");

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //不管请求的方式是get还是post,处理请求都在doGet中处理
        doGet(req,resp);
    }
}

四、Servlet的两种配置方式 4.1 xml配置文件

在servlet2.5以前使用



    
    
        
        demo1
        
        lhnservetest.HttpServlet
        
        1
    

    
    
        
        demo1
        
        /demoHttpServlet
    




4.2 @webservlet注解的配置方式

在servlet3.0以后才可用

  • 注解常用属性
    • name servlet: 名称
    • value: 配置servlet的访问路径,可配置多个
    • urlPatterns: 配置servlet的访问路径,可配置多个,不可用和value同时使用
    • loadOnStartup:优先级
@WebServlet(name="/demo1",urlPatterns = "/demoHttpServlet",loadOnStartup = 1)
@WebServlet("/demo3")
  • url-pattern规则

    • 精确匹配:/具体的名称;/demo1 只有在访问路径名完全一样时才会访问到。
    • 后缀匹配: @WebServlet("/showAllStuServlet") public class ShowAllStuServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { StuServiceImpl stuService=new StuServiceImpl(); //通过服务获取全部数据 Liststus=stuService.showALLStu(); //向前端页面发送数据 //直接展示一个html页面 resp.setContentType("text/html;charset=UTF-8"); resp.getWriter().print("n" + "n" + "n" + " n" + " Titlen" + "n" + "n" + " n" + "n" + " n" + " n" + " n" + " n" + " n" + " n" + " n" + " n" + "n" + " "); for(Stu stu:stus){//拼接获取的数据到表头下 resp.getWriter().append(" n" + " n" + " n" + " n" + " n" + " "); } resp.getWriter().append(" n" + "n" + "
      IDUserNamePassWordSex
      "+stu.getId()+""+stu.getUsername()+""+stu.getPassword()+""+stu.getSex()+"
      n" + "n" + ""); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }

      效果:

      六、转发和重定向
      • 现有的问题:
        • 一个servlet既做了数据解析,又做了展示页面的功能,违背了功能单一性。
        • 一个servlet只做数据解析和响应。
        • 一个servlet只做页面响应。

      那么两个servlet之间如何相互访问。

      6.1转发

      定义:一次请求,经过多次资源访问,跳转了多次,但是地址栏不发生改变。

      • 转发发生在服务器端,将请求发送给服务器端的其他资源,以共同完成一次请求的过程。

        req.getRequestDispatcher("showPageServlet?username=李浩楠").forward(req,resp);//放的是URL路径,req即为request作用域
        

      数据传递

      • forward:代表一次请求,是服务器内部进行跳转,可以共享request作用域中的所有数据。

        • request作用域:拥有存储数据的空间,在一次请求的过程中的任何位置都可以获取。

        • 可以传递任意类型的数据。

        • 存数据:

          request.setAttribute(key,value);
          
        • 取数据:

          req.getAttribute(key,value);
          

      特点

      • 转发是服务器行为。
      • 转发时游览器只发起一次请求。
      • 转发游览器地址栏内容不变。
      • 转发多次跳转之间传递的数据不会丢失。
      • 转发只能将请求发送给同一个web组件中的资源。
      6.2 重定向
      • 发生在客户端,客户端将请求发送给服务器之后,服务器响应给客户端一个新的请求地址,客户端再次发起一个请求。

        resp.sendRedirect("showPageServlet");
        

      数据传递

      • response:没有作用域,两次请求之间的数据无法共享。
      • 传递数据:通过URL路径拼接的方式传递数据(“showPageServlet?uername=123&password=123”)
      • 获取数据:req.getParameter();

      特点

      • 重定向是客户端行为。
      • 重定向至少发起了两次请求。
      • 重定向地址栏发生改变。
      • 重定向多次请求之间无法传递数据。
      • 重定向可以指向任意资源,包括当前应用程序中的资源,也包括同一站点上的其他资源,以及其他站点的资源。
      6.3 get和post的区别
      • get
        • get提交的数据会放在URL之后,以?分割,参数之间以&符号连接。
        • get以明文方式传递数据,数据量小,不安全。
        • 效率高,游览器默认的访问方式为GET。
        • 对应的Servlet方法为doGet();
      • post
        • post方法将提交的数据Http请求中。
        • 密文传递数据,进行一次加密(md5等),数据量大,安全。
        • 效率相对于GET低。
        • 对应的Servlet方法为doPost();
      七、生命周期

      servlet生命周期的四个阶段

      1. 实例化:当用户第一次访问servlet时,由容器调用servlet的构造方法创建一个具体的servlet对象;也可以在容器启动后立即创建实例对象,通过代码设置属性值为1;

        注意:只执行一次

      2. 初始化:调用init()方法,通过ServletConfig类进行初始化。

      3. 服务:调用service方法(例如HttpServlet中的doget()和dopost());

      4. 销毁:destory()方法;只执行一次。

      流程

      客户端发起请求—>容器(tomcat)解析请求—>创建servlet实例—>调用init()方法来进行初始化—>调用service()方法解析请求—>输出响应—>响应请求—>销毁servlet

      八、Cookie和Session 8.1 Cookie
      • Cookie是在游览器访问web服务器某个资源时,由web服务器在HTTP响应头中附带传送的一小段数据。
      • 一旦某个游览器存储了某个Cookie,在之后访问对应的web服务时,都应在HTTP请求头中携带此Cookie,把Cookie回传给服务器。
      • 一个Cookie由标识该信息的名称(name)和值(value)组成。
      8.1.1 添加Cookie
      package test;
      
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.Cookie;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      
      
      @WebServlet("/addCookie")
      public class CookieTestServlet extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              //创建Cookie对象
              Cookie cookie=new Cookie("20220701","java实训");
              //设置过期时间 三种取值 >0 有效期,单位:秒  ;=0 游览器关闭失效; <0 内存存储,默认-1
              cookie.setMaxAge(3600);
              //设置访问路径
              cookie.setPath("/");
              resp.addCookie(cookie);
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doGet(req,resp);
          }
      }
      
      
      8.1.2 获取Cookie
      package test;
      
      import javax.servlet.ServletException;
      import javax.servlet.http.Cookie;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      
      
      @WebServlet("/getCookie")
      public class GetCookieServlet extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              //获取请求中携带的cookie
              Cookie[]cookies=req.getCookies();
      
              for(Cookie cookie:cookies){
                  //检索cookie getName()获取cookie名称, getValue()获取cookie值
                  if(cookie.getName().equals("20220701")){
                      System.out.println("20220701:"+cookie.getValue());
                      break;
                  }
              }
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doGet(req,resp);
          }
      }
      
      
      8.1.3 修改Cookie

      只需保证Cookie的名和路径一致即可

      package test;
      
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.Cookie;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      
      
      @WebServlet("/updateCookie")
      public class UpdateCookieServlet extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              Cookie cookie=new Cookie("20220701","峡~谷~~之~~巅,爱慕未批,mvp~~15.4的鳄鱼");
              cookie.setPath("/");
              cookie.setMaxAge(-1);
              resp.addCookie(cookie);
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
             doGet(req,resp);
          }
      }
      
      
      8.1.4 Cookie优缺点
      • 优点
        • 可以配置到期规则。
        • 简单:一个基于文本的轻量型结构,只包含键值对。
        • 数据持久性:cookie默认在过期之前一直保存在客户端的游览器上
      • 缺点
        • 大小受到限制,4K-8k
        • 用户可设置成禁用。
        • 潜在的安全风险,cookie可以被篡改。
      8.2 Session

      Session记录用户的状态。session指的是在一段时间内,单个客户端与服务器之间的一连串相互交互的过程。

      在一个Session中,客户端可能会发起多次请求,可以访问一个资源,或者多个资源,session对象不变

      8.2.1 原理
      • 服务器会为每一个会话分配一个session对象。
      • 同一个游览器不管发起多少此请求,只要游览器没有关闭,都属于同一个会话。
      • 首次使用session时,服务器会自动创建session,并创建Cookie保存SessionID发送回客户端。
      8.2.2 Session使用
      • 作用域:拥有存储数据的空间,范围是一次会话有效。

        • 一次会话是同一个游览器发送的多次请求。一旦游览器关闭,则会话结束。

        • 可以将数据存入Session作用域中,在作用域中的任何位置都可以获取。

        • 可以传递任意类型的值。

          package test;
          
          import javax.servlet.ServletException;
          import javax.servlet.annotation.WebServlet;
          import javax.servlet.http.HttpServlet;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          import javax.servlet.http.HttpSession;
          import java.io.IOException;
          
          
          @WebServlet("/testsession")
          public class TestSessionServlet extends HttpServlet {
              @Override
              protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                  //获取Session对象
                  HttpSession session=req.getSession();
                  //存值
                  session.setAttribute("username","李浩楠");
                  //取值
                  String username=(String) session.getAttribute("username");
                  //移除作用域中的值
                  session.removeAttribute("username");
          
              }
          
              @Override
              protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
                  doGet(req,resp);
              }
          }
          
          
      8.2.3 Session和request的区别
      • request是一次请求有效,请求改变,则request改变。

      • session是一次会话有效,游览器改变,则session改变。

        • tomcat中可设定session的过期时间
            
                30
            
        
      8.2.4 验证码

      生成验证码通过ValidateCode.jar包来实现

      package servlet;
      
      import cn.dsna.util.images.ValidateCode;
      
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      
      
      @WebServlet("/https://blog.csdn.net/MR_lihaonan/article/details/createCode")
      public class CreateCodeServlet extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              //生成验证码的类
            ValidateCode validateCode= new ValidateCode(200,30,4,10);
            //获取生成的验证码
            String code=validateCode.getCode();
            System.out.println("生成的验证码:"+code);
            //存入session
              req.getSession().setAttribute("code",code);
              //把生成的验证码图片返回给前端,输出到前端
              validateCode.write(resp.getOutputStream());
      
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doGet(req,resp);
          }
      }
      
      

      html页面

      
      
      
          
          Title
      
      
      
            
      用户名: 密码: 验证码:

      验证码输入是否正确

      package servlet;
      
      import javax.servlet.ServletException;
      import javax.servlet.ServletOutputStream;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      
      
      @WebServlet("/verifyCodeServlet")
      public class VerifyCodeServlet extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              //前端传递的code
              String code=req.getParameter("code");
              //生成的code码
              String mgrcode=(String) req.getSession().getAttribute("code");
              //判断验证码是否正确,STRING内容是否相同,不区分大小写
              // code.equalsIgnoreCase(mgrcode)不区分大小写的比较方法
              // code.isEmpty()判空操作
              if(code.equalsIgnoreCase(mgrcode)&&!code.isEmpty()){
                  System.out.println("验证通过!");
              }else {
                  System.out.println("验证失败!");
              }
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doGet(req,resp);
          }
      }
      
      

      效果:

      九、ServletContext 9.1 概述
      • 全局对象,拥有作用域,对应Tomcat中的一个web应用。
      • 当web服务器启动时,会自动的为每一个web应用分配一个共享的内存空间。
      • servletContext 在web服务器启动时创建,服务器关闭时销毁。
      9.2 获取对象
      1. GenericServlet提供了一个方法getServletContext();(注:推荐使用)
      2. HttpServlet提供了一个方法getServletContext();(注:推荐使用)
      3. HttpSession对象提供了一个方法getServletContext();(做了解)
      9.3 作用
           //如何获取tomcat中web应用的真实路径
              ServletContext servletContext=req.getServletContext();
              String realPath=req.getServletContext().getRealPath("\img");
              System.out.println(realPath)
      
        //获取应用程序名称
              System.out.println(servletContext.getContextPath());
              System.out.println(req.getContextPath());
      
      • 存储数据:servletContext.setAttribute(key,value);
      • 获取数据:servletContext.getAttribute(key);
      • 移除数据:servletContext.removeAttribute(key);
      9.4 特点
      • 唯一性:一个应用程序只对应一个servletContext。
      • 生命周期:只要应用不关闭或者应用不卸载,servletContext对象一直存在。
      9.5 案例:记录程序的访问次数
      package day0702;
      
      import javax.servlet.ServletContext;
      import javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      
      
      @WebServlet("/countServlet")
      public class CountServlet extends HttpServlet {
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              //获取servletContext对象
              ServletContext application =req.getServletContext();
              //每次访问此servlet时,作用域中的某个值自增
      
              
              Integer count=( Integer)application.getAttribute("count");
      
              //当第一次访问时,count不存在
              if(count==null){
                  count=1;
      //            application.setAttribute("count",count);
              }
              else{
                  count++;
              }
              //返回前端页面
              resp.setContentType("text/html;charset=UTF-8");
              application.setAttribute("count",count);
              resp.getWriter().write("servlet的访问次数为:"+count);
          }
      
          @Override
          protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
              doGet(req, resp);
          }
      }
      
      
      十、过滤器

      Filter

      • 概念:是处于客户端和服务器之间的一道过滤技术。
      • 作用:执行地位在servlet之前,客户端发送请求时,会经过filter,再到达目标的servlet,响应时,再次反向执行filer,之后到达客户端。
      • 可以解决多个servlet之间代码冗余的问题。例:前端编码设置
      10.1 实现
      • 编写java类实现filter接口
      • 在doFilter中写拦截逻辑
      package entity.filter;
      
      import com.alibaba.druid.proxy.jdbc.DataSourceProxy;
      
      import javax.servlet.*;
      import javax.servlet.annotation.WebServlet;
      import javax.servlet.annotation.WebFilter;
      import java.io.IOException;
      import java.util.logging.LogRecord;
      
      
      @WebFilter("
      public class EncodingFilter implements Filter {
          @Override
          public void init(FilterConfig filterConfig) throws ServletException {
              Filter.super.init(filterConfig);
          }
      
          @Override
          public void destroy() {
              Filter.super.destroy();
          }
      
          @Override
          public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
      
              servletRequest.setCharacterEncoding("UTF-8");
              servletResponse.setContentType("text/html;charset=UTF-8");
              filterChain.doFilter(servletRequest,servletResponse);
          }
      }
      
      
      10.4 案例
      1. 登录:验证码、验证是否已经登录。

      2. 注册:验证两次输入的密码一致。

      3. 展示信息:展示所有用户的信息。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1005637.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号