【JavaWeb·4】Servlet详解

Servlet

引言

1、什么是Servlet?

  • 两个单词的组合 :服务器代码片段
    • server :服务器|服务端
    • Applet:代码片段
      2、Servlet的作用?

通过 程序 生成动态页面

3、Servlet程序的好处

可以通过程序 动态生成页面 页面实现动态效果后, 可以减少存储资源,人力资源的浪费。

在这里插入图片描述

Servlet的实现方式

1、Servlet标准:Servlet 接口,JavaEE规范

(1)servlet接口位于:javax.servlet.Servlet包中。
(2)接口的位置:tomcat/lib/servlet-api.jar包中。

2、Servlet的三种实现方式

  • 借助接口Servlet(位于javax.servlet)

    class 类名 implements Servlet{}

    • 需要实现接口中的5个方法
    • 与http协议无关
  • 借助抽象类GenericServlet{}

    class 类名 extends GeneriServlet{}

    • 只需要实现一个service方法
    • 但是和http协议无关
  • 借助抽象类HttpServlet

    class 类名 extends HttpServlet{}

    • 需要覆盖service方法,用于接收用户的请求和处理的结果响应给客户端
    • 和http协议相关

第一个servlet程序

功能:显示当前系统时间

开发步骤:

1、将servlet-api.jar导入到当前的module中

2、定义Servlet类:继承HttpServlet

public class FirstServlet extends HttpServlet {
    @Override
    public void service(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
        Date now = new Date();
        //1、设置响应的类型
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        //2、获取响应的输出流
        PrintWriter out = resp.getWriter();
        //3、利用响应输出流,将结果响应给客户端
        out.println("<html><head><title>first</title></head><body>");
        out.println(now);
        out.println("</body></html>");
    }
}

3、书写配置文件
在这里插入图片描述4、部署module:部署到服务器

5、启动服务器

6、在浏览器上访问

http://ip:端口号/module名/url-pattern
http://localhost:8080/servlet_day1/first

7、注意:处理响应乱码问题

需要在获取响应的输出流前面加上设置响应编码格式
response.setCharacterEncoding("utf-8")

常见异常

404

请求资源无效

(1)url地址栏的地址写错,特别是web应用名和url-pattern
(2)检查控制台是否有异常信息
(3)项目结构可能存在问题

405

service写错了

(1)检查servlet重点service方法是声明是否正确
(2)service方法中,不能调用父类的方法:super.service(参数);删除

500

服务端错误

(1)Java源代码运行过程中出现异常
(2)检查异常堆栈信息确定到错误行
(3)确认web.xml重点<servlet>包名.类名</servlet>是否正确
(4)jdk版本和tomcat版本不一致

运行正常,在浏览器提示下载或是另存为

检查是否设置响应类型的参数
response.setContentType("text/html")

servlet修改后没有编号

servlet代码修改,tomcat需要重启才能生效。

网络资源路径

在这里插入图片描述##

url-pattern访问三方式

1、直接通过浏览器访问

在浏览器的地址栏上输入:
http://ip:端口号/module名/url-pattern

2、通过超链接的形式访问url-pattern资源

<a href="/module名/url-pattern"
<a href="/first_servlet/first">查看当前系统时间</a>

3、通过form表单访问url-pattern

<form action="/module名/url-pattern method="post">
	<input type="submit" value="提交">
</form>

接受请求参数及带参发送

1、接收请求参数

String 变量 = request.getParameter("参数名字");

如果是post请求方式,为了防止出现中文乱码,需要在接收请求参数的前面

request.setCharacterEncoding("utf-8");

2、三种带参数的请求方式

(1)以form表单 (带请求参数)

<form action="/web应用名/url-pattern" method="get|post">
	<input type="" name="">根据每个input发name获取参数对应value值
</form>
a.第一种请求方式为:post
	I.以数据包的形式进行发送参数
	II.格式:http://ip:端口号/web应用名/url-pattern
	III.解决post请求乱码,只需要在获取请求参数的前面加
	request.setCharacterEncoding("utf-8");
b.第二种请求方式为:get

(2) 超连接请求带参数

<a href="/web应用名/url-pattern?参数名1=值&参数名2=值">热点文字</a>
  • 超链接请求带参数是一种get请求方式
  • 实际开发时:利用超链接请求带参数不会有大量数据,通常有修改或是删除id或者查一个的id
<a href="/servlet_day1/param?id=1">删除</a>

(3) 在地址栏中访问url-pattern时,请求带参数

http://ip:端口号/web应用名/url-pattern?参数名=值1&参数名2=值

Servlet的生命周期

1、servlet的生命周期交由tomcat服务器管理

​ Servlet程序对应的servlet的生命周期交给tomcat服务器管理,作为开发人员不能私自的创建Servlet程序的对象,由tomcat服务器根据需求完成Servlet对象创建

注意:客户端第一次请求url-pattern资源时,tomcat创建servlet资源对应对象(只创建一个)。
在这里插入图片描述在这里插入图片描述- servlet的生命周期由server tomcat进行管理

声明周期阶段调用的方法调用时机执行次数
创建/实例化构造方法第一次请求当前url-pattern1次
初始化init()创建对象后接着初始化1次
服务/处理service()有请求即调用n次
销毁destroy()server停止1次

线程问题

  • servlet在运行时,tomcat只为该类创建1个对象(servlet为单例设计),并由这个对象负责对所有请求它的client进行处理。当多个client同时请求该servlet时,这个对象就称为多线程环境下的临界资源对象,此时必须保证该临界资源对象的正确性(线程安全)

    • 方法一:对临界资源对象操作不安全的代码,使用synchronized(效率低)
    • 方法二:尽量避免在servlet中定义成员变量
  • Servlet单例设计的优缺点

    • 缺点:多线程环境下,数据不安全
    • 优点:提高效率,减少频繁的创建对象带来的消耗,同时提高 JVM 内存空间的利用率。

JDBC+Servlet整合

​ Servlet接收到数据需要去数据库中进行数据对比或是将数据同步到数据库,利用 JDBC 完成数据库的操作,Servlet需要调用JDBC业务层中的业务方法。
在这里插入图片描述2、项目整合思路

(1) 创建新的module->引入 web application

(2) 引入 module中需要jar依赖:创建 lib 文件
    a. JDBC技术的jar:JDBC资料中提供(mysql)
    b. Servlet技术jar:tomcat--》lib包中,servlet-api.jar
    注意:将jar拷贝到 module中lib中,右键 add as libarary
    
(3) 引入 JDBCUtil相关内容,并测试连接Connection通过
    a. com.baizhi.zmj.conf :引入 配置文件
    b. com.baizhi.zmj.util:引入 JDBCUtil工具类
    c. com.baizhi.zmj.test:测试,先测试 连接
---------------以上为环境搭建,以下为项目相关----------------------    

(4) 根据项目需求,利用navicat将表创建
(5) com.baizhi.zmj.sql:将sql文件存储
(6) com.baizhi.zmj.entity:完成表对应实体类

---------------根据 项目的需求进行完成----------------------
(7) com.baizhi.zmj.dao:先接口,再实现,每一个方法都必须测试
(8) com.baizhi.zmj.service:先接口,再实现,每一个方法都必须测试
(9) com.baizhi.zmj.servlet:根据需求完成servlet程序
(10) 完成 web.xml配置文件
(11) 整合路径
(12) 部署module-》tomcat
     注意:将 jdbc需要jar需要部署到 tomcat服务上:
          左上角File->右键第6项Project Structure->左侧Artifacts->
          在右侧找到对应的 moudule将需要Lib中jar直接双击即可
(13) 启动tomcat服务器
(14) 浏览器地址输入url

跳转

引入

一个Servlet中完成两块功能:

  • 一块功能接受客户端请求参数实现对应业务
  • 一块通过响应将结果相应给客户端,没有做到各司其职,不便于后期代码维护。

解决方案:将一个Servlet拆分成两个Servlet,其中一个Servlet负责业务逻辑,另一个Servlet负责给用户展示结果。
在这里插入图片描述

两个Servlet开发步骤

(1)逻辑Servlet,通常命名为:XxxAction

​ --1. 接收客户端请求参数

​ --2.调用 JDBC 中 service 层业务方法,实现对应的业务

​ --3.根据结果展示给用户(跳转到对应的XxxView上)

(2)展示Servlet,通常常类命名为:XxxView

​ --1.设置响应类型

​ --2.获取响应输出流

​ --3.利用响应输出流将结果展示给客户端

forward跳转(请求转发)

注意:请求和 Java代码是两条线。。

RequestDispatcher rd = req.getRequestDispatcher("/资源url-pattern");
rd.forward(req,resp);

注意:forward跳转前后,为同一个request(同一个客户端请求)

数据传递

request对象可以作为一个存储空间(作用域)使用,数据以键值对的形式存入存储空间。

request是一个作用域,用于存储命名属性。

request中添加命名属性:request.setAttribute("命名属性名字",obj);
                 
request中获取命名属性:Object obj = request.getAttribute("命名属性");
                   
    注意:在 XxxAction中获取的业务结果,需要在XxxView中进行展示的时候,利用request设置命名属性   

重定向

  • 重定向连接到两个servlet分属于两个请求
  • 地址栏发生改变
  • 语法
response.sendRediract("/web应用名/url-pattern");
  • 两种跳转的区别
    在这里插入图片描述1. 登录成功 到 查所有action: 重定向
    失败 到 登录页: 重定向
  1. 添加成功 到 查所有 action: 重定向
    失败 到 添加页 : 重定向
  2. 删除成功 到 查所有 action: 重定向
  3. 修改成功 到 查所有 action: 重定向
  4. action中出现异常跳转到error.html:看需求是否有利用request传递数据的需求,有fordward,没有…
  5. 查所有action跳转到查所有view:fordward
  6. 查一个action跳转到查一个view:fordward
    在这里插入图片描述## 会话跟踪技术

http协议:短连接 无状态

(1) 超文本传输协议,在www网中数据通信必须遵循的规范
(2) 无状态的协议

会话跟踪技术

Cookie:客户端存储用户状态数据的一种手段

HttpSession:服务器存储用户状态数据的一种手段。和request一样,是一种作用域。

(1) 记录客户端浏览器过程数据
(2) 常见会话跟踪技术
    a. Cookie[了解]
    b. session【重点】
    c. URL重写技术
(3) 常见的现象:浏览记录、免登陆、购物车(简易)

Cookie

(1) Cookie由服务端(server)往客户端(client)写的一段小文本,格式:name=value
(2) 创建Cookie对象:cookie只可以写String。
    Cookie c1 = new Cookie("name1","value1");
    Cookie c2 = new Cookie("name2","value2");
(3) 往客户端写Cookie:
    response.addCookie(c1);
    response.addCookie(c2);
(4) 从客户端读取Cookie:
    Cookie[] cs = request.getCookies();
    遍历 cs数组获取每一个 Cookie 存储 c
      for(Cookie c:cs){
      	 String name = c.getName();// 获取Cookie的name
      	 String value = c.getValue();// 获取Cookie的value
      }
(5) 设置Cookie有效时间:
    a. Cookie的有效时间默认和浏览器绑定,浏览器开着,Cookie存活,浏览器关闭,则Cookie失效
    b. 设置Cookie有效时间:
       c.setMaxAge(60);// 60s 单位为秒,有效时间从Cookie创建开始计算,就和浏览器是否开关无关了。
       注意:设置Cookie有效时间必须在 response.addCookie(c); 前面
(6) 缺点:
    a. Cookie可以被客户端禁用
    b. Cookie可以被客户端删除

设置Cookie的存活时间

cookie.setMacAge(time) ——time单位是秒

  1. time为正数:存活时间
  2. time为0,表示删除当前cookie
  3. time为负数,当前cookie会从存活到浏览器关闭

根据http协议的规定,程序默认只能读取”同一个包"其他程序写出的cookie,如果需要跨包读取cookie,则需要设置path。

cookie.setPath("url");

session(会话)

  • 同一个客户端和同一个web应用(module)建立连接之后的多次请求/响应的过程被称为一个session会话。

注意:同一个客户端简单理解为:同一个电脑上同一个浏览器产品

HttpSession session = request.getSession(true);
参数:
    true:代表如果获取session对象时,存在,直接使用;不存在,创建session [建议]
    false:代表如果获取session对象时,存在,直接使用;不存在,返回null
特点
  • session和 client 一 一对应(同一个client是指同一个电脑上同时打开的同类浏览器产品 是同一client)

  • session的生命周期比request大(session比request存活久)

    I. request:一个request和它对应的response回来,request失效

    ii. session:经历多次请求/响应

session作用域【寿命】

【开始】同一个客户端(client)第一次遇到 request.getSession(true); tomcat为浏览器创建session对象(懒汉式)。
【结束】
I. 超时:tomcat默认30分钟,从第每次 访问开始计算(中间访问过,时间从新计算)手动设置存活时间:session.setMaxInactiveInterval(); 通常时间短一些,数据安全,内存及时释放。
II. 手动销毁:session.invalidate()方法
注意:如果直接关闭浏览器,session对象不会被销毁

session对应一个浏览器

当客户端请求的程序代码里申请session对象时,tomcat会首先读取浏览器上的cookie,查找JSESSIONID这个cookie。

找到:读取cookie的value,根据value在内存中找到对应的session,给用户使用。

没找到:tomcat创建新的session对象,并将session的编号id以cookie的形式写到浏览器上

session的使用
  • 设置命名属性

  • 往命名属性存储数据:session.setAttribute(“名”,值Object);

  • 从命名属性中取数据:Object obj=session.getAttribute(“名”);// 注意强制类型转换

  • 移除命名属性:session.removeAttribute(“名”);

    HttpSession开发实际应用

a. 显示用户登录信息: 
   I. 在LoginAction利用session设置命名属性,将登陆信息存储在session
          HttpSession session = request.getSession(true);
          session.setAttribute("user",user);
   II. 在 XxxView利用seesion获取命名属性:
          HttpSession session = request.getSession(true);
          User user = (User)session.getAttribute("user");
b. 强制登陆:让用户必须先登陆,再查看相关信息(为了保护数据安全性)
   I.在LoginAction利用session设置命名属性,将登陆信息存储在session 
         HttpSession session = request.getSession(true);
         session.setAttribute("user",user);
   II. 在查所有Action、View、查一个Action等添加代码:
          HttpSession session = request.getSession(true);
          Object obj=session.getAttribute("user");
          if(obj == null){
              // 强制跳转到登陆界面
              response.sendRedirect("/servlet_day2/login.html");
              return;
          }
          
c. 安全退出:
   第一种方式:将session中命名属性登陆标记清了,但是session存活
                 session.removeAttribute("user");// 只是将session中命名属性清掉
      
   第二种方式:直接将session销毁
       			 session.invalidate();// 销毁session

ServletContext

  1. 理解:tomcat启动时,会读取服务器中每个web应用的配置文件web.xml, 并将读到的内容封装到ServletContext 对象保存在内存。 ServletContext对象 和 web应用 一一对应。

    一个module对应一个ServletContext

  2. 获取ServletConext

    ServletContext application = this.getServletContext();
    
    ServletConext application = session.getServletContext();
    
    ServletContext application = super.getServletContext();
    
  3. 存取命名属性

    setAttribute("name",value);
    Object value = application.getAttribute("name");
    application.removeAttribute("name");
    
  4. 特点:寿命长(begin:tomcat启动 end:tomcat关闭)

  5. 第一个应用:可以设置全局参数:

    (1) web.xml文件中配置:
        <context-param>
            <param-name>encoding</param-name>
            <param-value>GBK</param-value>
        </context-param>
    (2) 在使用全局参数的代码中获取请求参数:
         ServletContext context=super.getServletContext();
         String value = context.getInitParameter("encoding");
         req.setCharacterEncoding(value);
    
  6. 第二个应用:作为作用域对象,设置命名属性

(1) 作用范围:
    开始:tomcat服务器启动,ServletContext创建
    结束:tomcat服务器关闭,ServletContext销毁
(2) 设置命名属性:
    context.setAttribute("属性名",值);
    Object obj=context.getAttribute("属性名");// 使用自身类型,强制类型转换
    注意:ServletConext作为作用域存储存储数据,一定慎重选择,所有用户共享数据!!!!
         
         用户登录信息 --》 session
         统计网站在线人数--》ServletContext
         查询所有信息,传递到view --> request         

Servlet三大作用域

作用域:在web程序运行过程中,用来存放数据(命名属性)的存储空间。

当服务器关闭时,如果session还在,服务器会将session相关信息存储在硬盘中,下次启动读取。如果那时session还没过期,还可以使用,存储的数据也还在。
在这里插入图片描述

过滤器

过滤器中用于定义附加代码(冗余代码)

  • arg1:ServletRequest是HttpServletRequest的父类型,实际运行过程client端发出的是HttpServletRequest,如果使用可以强转。
  • args2:ServletResponse是HttpServletResponse的父类型
  • args3:过滤器链,当预处理结束时,可以使用这个参数放请求通过,访问后续servlet
    在这里插入图片描述在这里插入图片描述当请求通过多个过滤器时,过滤按照web.xml中配置的先后的顺序进行过滤。
  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值