JavaWeb学习笔记-Servlet03

JavaWeb学习笔记-Servlet03

4/3/2020


第八节:请求转发

请求转发介绍和使用

问题:

一次请求的处理需要多个Servlet的联动操作,第一个Servlet需要用到其他的Servlet已经声明的逻辑处理代码,这时候怎么办?

解决:

使用请求转发
解释:其实就是在一个Servlet中调用其他的Servlet。
使用req.getRequestDispatcher("转发的路径").forward(req, res);

请求转发的特点

  1. 降低Servlet之间的代码冗余
  2. 一次请求转发内的Servlet共享此次请求的request和response对象
  3. 浏览器地址信息不改变,一次请求

request的作用域

一次请求转发内的Servlet
作用:request可以作为数据流转的载体
使用:request下有setAttribute()/getAttribute()两个方法,用来设置自定义的属性传入。
我们在转发的Servlet中设置request的setAttribute()然后再转发,那么被转发的Servlet可以使用getAttribute()来得到设置的自定义属性。
req.setAttrbute("str","密码错误!")
小问题:在接收自定义属性的时候默认是Object类型,我们需要强转成String,还是那个问题,强转本身不存在问题但是如果str自定义属性不纯在那么得到的结果是null强转就会报空指针。
解决:很简单做判断就好了,使用三目运算来解决
String str = req.getAttribute("str") == null ? "" : req.getAttribute("str")

重定向

请求转发的小问题

请求转发有一个特点就是浏览器地址不变,那么每次刷新就又走了一遍转发流程,如果是比较重要的服务,如银行转账,就会出现问题。
问题的解决:重定向

使用

使用方式很简单
res.sendRedirect("重定向路径");
特点
两次请求:当前Servlet处理完问题后剩下的问题需要另一个Servlet处理,现在只告诉浏览器一个新的Servlet的地址就好了,浏览器只需要再发起一次请求和服务器建立连接,这时候浏览器地址也会发生变化,处理掉了请求转发的小问题。
新的小问题:但是也带来了新的问题,重定向是发起了新的请求连接,那么就不共享request对象了,两个Servlet之间就无法进行交互。
解决:使用cookie和session

第九节:cookie和session

介绍和特点:

问题:不同的请求使用相同的请求数据,但是请求只要结束数据就被销毁了,替他请求需要将公共的数据重新书写发送。
解决:使用Cookie技术
特点
浏览器端的数据存储技术
哪些数据需要被存储是在服务器端进行声明,以响应的方式告诉浏览器进行存储
不适合大量数据的存储
作用:实现了不同请求之间数据共享的问题

代码实现Cookie

创建两个Servlet,Servlet1中请求响应一个a和b,Servlet2中请求响应一个b和c。b就是重复的数据了,使用Cookie存储。在Servlet2中只请求一个c,b获取a里面请求过的。

Servlet1

public class MyServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置请求编码格式
        req.setCharacterEncoding("utf-8");
        // 设置响应编码格式
        resp.setContentType("text/html;charset=utf-8");
        // 获取请求信息
        String a = req.getParameter("a");
        String b = req.getParameter("b");
        // 处理请求信息
        System.out.println(a + ":" + b);
        // 响应处理结果
        // 创建Cookie数据
        Cookie ck = new Cookie("b", b);
        // 响应Cookie数据
        resp.addCookie(ck);
        // 直接响应
        resp.getWriter().write("我是MyServlet1,处理完毕。");
        // 请求转发
        // 重定向
    }
}

Servlet2

public class MyServlet2 extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置请求编码格式
        req.setCharacterEncoding("utf-8");
        // 设置响应编码格式
        resp.setContentType("text/html;charset=utf-8");
        // 获取请求信息
        // String b = req.getParameter("b");
        // 获取Cookie数据
        String b = null;
        Cookie[] cookies = req.getCookies();
        for (Cookie ck : cookies) {
            if ("b".equals(ck.getName())) {
                b = ck.getValue();
            }
        }
        String c = req.getParameter("c");
        // 处理请求信息
        System.out.println(b + ":" + c);
        // 响应处理结果
        // 直接响应
        resp.getWriter().write("我是MyServlet2,处理完毕。");
        // 请求转发
        // 重定向
    }
}

使用方法总结:

存储

  1. 创建Cookie类的对象,构造器传两个参数,相当于键值对
  2. 使用resp里面的addCoodie()方法再响应是添加Cookie数据

获取

  1. 使用req下的getCookies()方法获取Cookies数组
  2. 遍历数组得到想要的键值对

Cookie的有效期和有效路径设置

小问题

  1. 设置的Cookie关闭浏览器就会消失
  2. 设置的Cookie不论是什么请求都会附带上

原因:没有设置Cookie信息

设置Cookie信息

  1. 设置cookie的有效期
    ck.setMaxAge(3600 * 24 * 3);
  2. 设置有效路径
    ck.setPath("/my2");

Cookie使用特点

  1. 如果不设置有效期则会默认存储在浏览器的内存里,浏览器关闭即失效
  2. 如果设置了有效期则存储到客户端的硬盘里,到期后自动销毁
  3. 如果不设置有效路径则任意项目路径的请求都会附带存储的Cookie信息
  4. 如果设置了有效路径,则只有在该路径下的请求才会附带设置的Cookie信息

Session

Session流程介绍

为了解决两次请求之间的交互。
先创建一个对象用来存储需要交互的数据,然后这个对象有一个唯一标识的ID,想要获取这个对象数据的只需要得到这个ID就可以了。使用之前介绍的Cookie技术在两个请求之间传输这个ID就可以做到两个请求之间的交互。
这个对象就是指的Session对象。

Session使用流程

传输方

  1. 创建Session对象,HttpSession session = req.getSession();
  2. 设置数据setAttribute()方法```session.setAttribute("uname","张三");

接受方

  1. 创建Session对象,HttpSession session = req.getSession();
  2. 获取数据getAttribute()方法String uname = (String) session.getAttribute("uname");
    第二步里面的强转纯在空指针问题

细节
Session内底层已经把存储Cookie和获取Cookie封装好了不用我们再去使用Cookie
创建Session对象时候如果之前有就不会再进行创建只会获取。
特点
Session解决了同一个用户不同请求的数据共享问题。
Session的作用域:浏览器不关闭,Session不失效,则同一用户的任意请求获取的都是同一个Session

Session有效期设置和强制销毁

有效期设置:
session.setMaxInactiveInterval(int n);
n的单位是秒
没设置的默认是30分钟销毁

强制销毁
session.invalidate()


6/3/2020


第十节:ServletContext

ServletContext介绍

问题:Request解决了一次请求内的数据共享问题,session解决了用户不同请求的数据共享问题,那么不同的用户的数据共享该怎么办?
解决:使用ServletContext对象
作用:解决了不同用户的数据共享问题
原理:ServletContext对象由服务器创建,一个项目只有一个对象,不管在项目的任何位置进行获取到的都是同一个对象,那么不同用户夫妻的请求获取到的也就是同一个对象了,该对象由用户共同拥有。
特点

  1. 服务器进行创建
  2. 用户共享
  3. 一个项目只有一个

生命周期:服务器启动到服务器关闭
作用域:项目内

使用:

获取ServletContext对象
使用作用域进行共享数据流转
获取web.xml中的全局配置
获取webroot下的项目资源流对象
获取webroot下资源绝对路径

使用ServletContext进行不同用户之间数据流转

  1. 获取ServletContext对象,三种方式获取的都是同一个对象
  1. this.getServletContext()
  2. this.getServletConfig().getServletContext()
  3. req.getServletContext()
  1. 设置自定义属性,就和之前设置Session或者req的属性差不多
    servletContext.setAttribute(key,value)
  2. 获取自定义属性
    servletContext.getAttribute(key)
  3. 删除自定义属性
    servletContext.removeAttribute(key)
    注意:获取的时候强转的空指针异常

使用ServletContext获取web配置文件全局属性

  1. 设置web.xml文件
<context-param>
	<param-name>flag</param-name>
	<param-value>false</param-value>
</context-param>
  1. 获取属性
    获取ServletContext对象
    servletContext.getInitParameter("flag")
    返回一个字符串

使用ServletContext获取webroot下的资源流

getResourceAsStream(url)
返回的是一个InputStream流

使用ServletContext获取webroot下的资源绝对路径

getRealPath(path)
返回的是资源的绝对路径字符串


7/3/2020


第十一节:ServletConfig对象

问题

使用ServletContext可以读取web.xml全局配置文件
每一个单独的Servlet也有独立的配置,该怎么访问呢

解决

ServletConfig对象

作用

ServletConfig是Servlet的专属配置对象,每一个Servlet都有一个ServletConfig对象,用来获取web.xml里面的配置信息。

使用

  1. 配置web.xml配置文件
<context-param>
	<param-name>flag</param-name>
	<param-value>false</param-value>
</context-param>

和全局的一样,不过要写在独立的Servlet里面
2. 获取
获取ServletConfig对象
config = this.getServletConfig()
获取配置信息
config.getInitParameter(key)
获取配置信息的枚举
config.getInitParameterNames()


Servlet基础内容完结
撒花QAQ
接下来是JSP了


Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.byfree.top/archives/servlet03