JSP———数据交互【2】

内置对象application

实现用户之间的数据共享

与session 对象不同的是,所有客户的 application 对象是相同的一个,即所有的客户共享这个内置的 application 对象

常用方法:

JSP———数据交互【2】

public Enumeration getAttributeNames() 该方法产生一个枚举对象,该枚举对象使用 nextElemets()遍历application 对象所含有的全部对象。

public void removeAttribue(String key)从当前 application 对象中删除关键字是 key 的对象。

public String getServletInfo()获取 Servlet 编译器的当前版本的信息。

 

 

pageContext    内置对象    代表了JSP页面编译后的内容。它封装了对其他8大内置对象的引用!,也就是说,通过pageContext可以获取到其他的8个内置对象!

<%
    
        System.out.println(pageContext.getSession());
        System.out.println(pageContext.getRequest());
        System.out.println(pageContext.getResponse());
    
        System.out.println(pageContext.getException());
    
        System.out.println(pageContext.getPage());
        System.out.println(pageContext.getServletConfig());
        System.out.println(pageContext.getServletContext());
        System.out.println(pageContext.getOut());
    
    %>

pageContext是    域对象    ,它代表着当前JSP页面(也就是page)!也就是说:pageContext域对象只在page范围内有效,超出了page范围就无效了

三个方法:

  • § setAttribute(String name,Objcet o)
  • § getAttribute(String name)
  • § removeAttribute(String name)
<% pageContext.setAttribute("name", "zhangsan"); %>
<%
   String value = (String) pageContext.getAttribute("name");
     System.out.println(value);
%>

 

注意pageContext域对象是可以访问request、session、application、page这几个域对象设置的值的

 

 

上面的pageContext默认是page范围的,但pageContext对象重载了set、get、removeAttribute这三个方法

  • getAttribute(String name,int scope)
  • setAttribute(String name,Object value,int scope)
  • removeAttribute(String name,int scope)
  • 多了一个设置域范围的一个参数,如果不指定默认就是page。当然了,pageContext把request、session、application、page这几个域对象封装着了静态变量供我们使用
    • PageContext.APPLICATION_SCOPE
    • PageContext.SESSION_SCOPE
    • PageContext.REQUEST_SCOPE
    • PageContext.PAGE_SCOPE
    • 刚才我们没有使用重载方法的时候,使用pageContext是无法获取到request域对象设置的属性的现在我们使用重载后的方法就能获取得到
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <body>
      <%
        //使用重载的方法获取request域对象的属性
String value = (String) pageContext.getAttribute("name",pageContext.REQUEST_SCOPE);
        System.out.println(value);
    %>
    
    </body>
    </html>

JSP———数据交互【2】

 

 

 

pageContext还有这么一个方法:findAttribute(String name)

该方法会查找各个域的属性,从小到大开始寻找!也就是page—>request->session->application。

<%
    //使用findAttribute查找2.jsp中request域对象的属性
   String value = (String) pageContext.findAttribute("name");
     System.out.println(value);
    %>

JSP———数据交互【2】

 

 

 

 

 

 对象的作用域

JSP———数据交互【2】

 

 JSP———数据交互【2】

page作用域:

只在本JSP页面范围有效

pageContext.setAttribute(键,值)

pageContext.getAttribute(键)

 

request作用域内的对象则是与客户端的请求绑定在一起

<%
    String name = "request";
    request.setAttribute("name",name);
    request.getRequestDispatcher("testTwo.jsp").
        forward(request, response);
%>

 

session作用域:一次会话

JSP———数据交互【2】

 

 application作用域:整个web应用程序

 JSP———数据交互【2】

 

 

 

cookie

cookie是Web服务器保存在客户端的一系列文本信息

cookie的作用

  • 对特定对象的追踪
  • 实现各种个性化服务
  • 简化登录
  • 但安全性能————容易泄露信息

 

使用:

JSP———数据交互【2】

 常用方法

 JSP———数据交互【2】

 

 

 

 

cookie与session的对比

 JSP———数据交互【2】

 

 

 JSP访问数据库

分层实现

数据访问层(DAO)

表示层(JSP) ————非空验证 提示错误信息并保留用户所填写的信息

 

 

 

JavaBean

 

一辆货车,在java端和web页面进行数据传递的载体

 

优势

  • 解决代码重复编写,减少代码冗余
  • 功能区分明确 提高了代码的维护性

分类

功能上可以分为 封装数据 封装业务

JSP———数据交互【2】

JSP 页面应当将数据的处理过程指派给一个或几个 beans 来完成,我们只需在 JSP 页面中调用这个 beans即可。不提倡大量的数据处理都用 java 程序片来完成。在 JSP 页面中调用 beans,可有效的分离的静态工作部分和动态工作部分编写 javabeans 就是编写一个 java 的类。

 

工作过程:

当服务器上某个含有 useBean 标签的 JSP 页面被加载执行时,JSP 引擎将首先根据 id 的名字,查找 JSP 引擎内置 pageContent 对象中是否含有名字 id和作用域 scope 的对象,如果这个对象存在,JSP 引擎就分配一个这样的对象给客户,这样,客户就获得了一个作用域是 scope、名字是 id 的 beans。如果在 pageContent 中没有查找到指定作用域、名字是 id 的对象,就根据 class 指定的类创建一个名字是 id 对象,即创建了一个名字是 id 的 beans,并添加到 pageContent 内置对象中,并指定该 beans 的作用域是 scope,同时 JSP 引擎分配给客户一个作用域是 scope、名字是 id 的 beans。

 

² scope 取值 page

该 beans 的有效范围是当前页面,当客户离开这个页面时,JSP 引擎取消分配给该客户的 beans。

² scope 取值 session

该 beans 的有效范围是客户的会话期间,也就是说,如果客户在多个页面中相互连接,每个页面都含有一个 useBeans 标签,这些 useBean 标签中 id 的值相同,并且 scope 的值都是 session,那么,该客户在这些页面得到的 beans 是相同的一个。如果客户在某个页面更改了这个 beans 的属性,其它页面的这个 beans 的属性也将发生同样的变化。当客户关闭浏览器时,JSP 引擎取消分配给客户的 beans。

 

² scope 取值 request

该 beans 的有效范围是 request 期间。客户在网站的 访问期间可能请求过 多个页 面,如果这些页面含有 socope 取值是request 的 useBeans 标签,那么 pageCotent 对象在每个页面分配给客户的 beans 也是互不相同的。JSP 引擎对请求作出响应之后,取消分配给客户的这个 beans。

 

² scope 取值 application

所有客户共享这个 beans,如果一个客户改变这个 beans 的某个属性的值,那么所有客户的这个 beans 的属性值都发生了变化。这个 beans 直到服务器关闭才被取消。

 

注意事项

当使用作用域是 session 的 beans 时,要保证客户端支持 Cooker.

为了使服务器的所有 web 服务目录下的 JSP 页面文件都能使用我们的 beans(假如是Circle.java),我们必须将上面编译通过生成的字节码类文件:Circle.class 拷贝到 JSP 引擎的 classes 文件夹下,即tomcat\classes 下。另外,在使用 beans 的 JSP 页面中,必须有如下的 import 指令:

<@page import= “Circle”>

 

 

特定的写法:

  • 无参的构造函数
  • 成员属性私有化
  • 封装的属性如果需要被外所操作,必须编写public类型的setter、getter方法

三个对javabean操作的标签:

(1) jsp:useBean【在JSP页面中查找javaBean对象或者实例化javaBean对象

(2) jsp:setProperty【设置javaBean的属性】

(3) jsp:getProperty【获取javaBean的属性】

 

 

 

<jsp:useBean>标签用于在指定的域范围内查找指定名称的JavaBean对象

(1)存在则直接返回该JavaBean对象的引用

(2)不存在则实例化一个新的JavaBean对象并将它以指定的名称存储到指定的域范围中

语法:

<jsp:useBean id="实例化对象的名称" class="类的全名" scope="bean 有效范围"/>

或者

<jsp:useBean id="实例化对象的名称" class="类的全名" scope="bean 有效范围">

</jsp:useBean>

举例:

  <body>
    <jsp:useBean id="tom" class="Person" scope="page"/>
    <%
        tom.setName("tom");
        System.out.println(tom.getName());
    %>   
 </body>

person类必须存在一个           空参构造         才能使用<jsp:useBean>标签不然不行

 

上例等价于:

<body>
     <%
        //new出对象
        Person tom = new Person();
        tom.setName("tom");
        System.out.println(tom.getName());
    %>
</body>

 

 

 

jsp:setProperty  该标签可以设置 beans 的属性值

 

setProperty标签可以通过 3 种方式设置 beans的属性值。

(1)将 beans的属性值设置为一个表达式的值或字符串。

beans 的属性值设置为一个表达式的值:

<jsp:setProperty name= “beans的名字 ” property= “beans 的属性名 ” value=“<%=expression%>” />

beans 的属性值设置为一个字符串:

<jsp:setProperty name= “beans 的名字” property= “beans 的属性名” value= 字符串/>

(2)通过form表单的参数的值来设置 beans 的相应属性的值,要求表单参数名字必须与 beans 属性的名字相同。JSP

引擎会自动将表单中的数据(字符串)转换为 beans 属性的类型。

 

<jsp:setProperty name= "beans 的名字" property="*" />

该标签不用再具体指定 beans 的属性的值对应的是表单中的哪个参数的值,系统会自动

根据名字进行匹配

 

(3)通过 request 的参数的值来设置 beans 的相应属性的值,要求 request 参数名字必须与 beans 属性的名字相同

 

<jsp:setProperty name= "beans的名字" property="属性名" param= “参数名”/>

 

注:不能在<jsp:setProperty> 中同时使用 value 和 param。

 

 

 

jsp:getProperty

该标签可以获得 beans 的属性值,并将这个值用串的形式显示给客户.

语法格式:

<jsp:getProperty name= “beans 的名字” property= “beans 的属性” />

或

<jsp:getProperty name= “beans 的名字” property= “beans 的属性” />

</jsp:getProperty>

 

举例:

<jsp:getProperty name="person" property="username"/>
    <jsp:getProperty name="person" property="age"/>

JSP———数据交互【2】

 

 

 

 

 

 

 

JSP———数据交互【2】

 

 

 

JSP———数据交互【2】

 

 

 

 

 

 

序列化

序列化:对象的寿命通常随着生成该对象的程序的终止而终止,有时候需要把在内存中的各种对象的状态(也就是实例变量,不是方法)保存下来,并且可以在需要时再将对象恢复。

 

总结:

Java 序列化技术可以使你将一个对象的状态写入一个Byte 流里(序列化),并且可以从其它地方把该Byte 流里的数据读出来(反序列化)

 

用途:

  • 想把的内存中的对象状态保存到一个文件中或者数据库中时候
  • 想把对象通过网络进行传播的时候

如何序列化:

只要一个类实现Serializable接口,那么这个类就可以序列化了

 

例如,有一个 Person类,实现了Serializable接口,那么这个类就可以被序列化了。

class Person implements Serializable{   
    private static final long serialVersionUID = 1L; //下面解释这个是做什么的
    String name;
    int age;
    public Person(String name,int age){
        this.name = name;
        this.age = age;
    }   
    public String toString(){
        return "name:"+name+"\tage:"+age;
    }
}

通过ObjectOutputStreamwriteObject()方法把这个类的对象到一个地方(文件),再通过ObjectInputStream readObject()方法把这个对象出来

 File file = new File("file"+File.separator+"out.txt");
    
    FileOutputStream fos = null;
    try {
        fos = new FileOutputStream(file);
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(fos);
            Person person = new Person("tom", 22);
            System.out.println(person);
            oos.writeObject(person);            //写入对象
            oos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                oos.close();
            } catch (IOException e) {
                System.out.println("oos关闭失败:"+e.getMessage());
            }
        }
    } catch (FileNotFoundException e) {
        System.out.println("找不到文件:"+e.getMessage());
    } finally{
        try {
            fos.close();
        } catch (IOException e) {
            System.out.println("fos关闭失败:"+e.getMessage());
        }
    }
                            
    FileInputStream fis = null;
    try {
        fis = new FileInputStream(file);
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(fis);
            try {
                Person person = (Person)ois.readObject();   //读出对象
                System.out.println(person);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } 
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                ois.close();
            } catch (IOException e) {
                System.out.println("ois关闭失败:"+e.getMessage());
            }
        }
    } catch (FileNotFoundException e) {
        System.out.println("找不到文件:"+e.getMessage());
    } finally{
        try {
            fis.close();
        } catch (IOException e) {
            System.out.println("fis关闭失败:"+e.getMessage());
        }
}

输出结果为:

name:tom    age:22

name:tom    age:22

 

serialVersionUID ,实现了Serializable接口之后,Eclipse就会提示你增加一个 serialVersionUID,虽然不加的话上述程序依然能够正常运行。

序列化 ID 在 Eclipse 下提供了两种生成策略

  • 一个是固定的 1L
  • 一个是随机生成一个不重复的 long 类型数据(实际上是使用 JDK 工具,根据类名、接口名、成员方法及属性等来生成)

上面程序中,输出对象和读入对象使用的是同一个Person类。

如果是通过网络传输的话,如果Person类的serialVersionUID不一致,那么反序列化就不能正常进行。例如在客户端A中Person类的serialVersionUID=1L,而在客户端B中Person类的serialVersionUID=2L 那么就不能重构这个Person对象。

 

如果没有特殊需求的话,使用用默认的 1L 就可以,这样可以确保代码一致时反序列化成功。那么随机生成的序列化 ID 有什么作用呢,有些时候,通过改变序列化 ID 可以用来限制某些用户的使用。

 

上一篇:Error creating bean with name ‘***Controller‘


下一篇:错误解决:No Feign Client for loadBalancing defined.