• <jsp:useBean>、<jsp:setProperty>与<jsp:getProperty>


    <jsp:useBean>标签

      会调用java对象的无参构造方法,来创建实例。

       <jsp:useBean>标签是用来搭配JavaBean元件的标准标签,这里指的JavaBean是满足以下条件的Java对象:
         1、必须实现java.io.Serializable接口
         2、具有无参数的构造器
         3、没有公开(public)的类变量
         4、具有公开的设值方法(Setter)与取值方法(Getter)
       但是在实际的测试中没有实现序列化接口也没有问题。

    Demo:

    package com.test;
    
    public class AddServiceImpl {
        public String add() {
            return "1 + 2 = 5";
        }
    }
    Java Code
    <%@page contentType="text/html" pageEncoding="UTF-8" %>
    <jsp:useBean id="addService" class="com.test.AddServiceImpl"/>
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>Hello</title>
    </head>
    <body>
    <p><%= addService.add()%></p>
    </body>
    </html>
    index.jsp

    测试地址:http://127.0.0.1/index.jsp

    运行结果:1 + 2 = 5

    查看转译后的servlet源码有如下内容:

          com.test.AddServiceImpl addService = null;
          addService = (com.test.AddServiceImpl) _jspx_page_context.getAttribute("addService", javax.servlet.jsp.PageContext.PAGE_SCOPE);
          if (addService == null){
            addService = new com.test.AddServiceImpl();
            _jspx_page_context.setAttribute("addService", addService, javax.servlet.jsp.PageContext.PAGE_SCOPE);
          }
     
          out.print( addService.add());
    index_jsp.java

    源码分析

      使用<jsp:useBean id="addService" class="com.test.AddServiceImpl"/>声明一个java对象后,servlet会去pageContext域里根据指定的id值去寻找这个java对象,如果找不到,使用无参的构造方法创建并且再把它设置到pageContext作用域里。
      接着就可以使用设定的id值或者说pageContext域的key——addService来直接使用这个对象。

      使用<jsp:useBean>时,还可以指定scope属性,可以指定的值有page(默认)、request、session与application。这样就先会到指定属性范围中寻找该实例,如果找到就直接使用;找不到也不会到其它作用域里去找,而是创建一个新对象并放入到指定的指定的作用域里。

      使用<jsp:useBean>时,还可以指定type属性。type属性的设置可以是一个抽象类,也可以是一个接口。如果只设置type而没有设置class属性,则必须确定在某个属性范围中已经存在所要的对象,否则会发生InstantiationException异常。比如:

    <jsp:useBean id="user" type="com.test.UserBase" class="com.test.User" scope="session"/>
    View Code

    这样产生的 Servlet 中,將會有以下的片段:

        com.test.UserBase user = null;
          synchronized (session) {
            user = (com.test.UserBase) _jspx_page_context.getAttribute("user", javax.servlet.jsp.PageContext.SESSION_SCOPE);
            if (user == null){
              user = new com.test.User();
              _jspx_page_context.setAttribute("user", user, javax.servlet.jsp.PageContext.SESSION_SCOPE);
            }
        }
    View Code

     <jsp:setProperty>标签

      会调用java对象public的setter方法。

      1、获取客户端参数

    Demo

    package com.test;
    
    public class User {
    
        private String name;
    
        private String age;
    
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getAge() {
            return age;
        }
        public void setAge(String age) {
            this.age = age;
        }
    }
    Java Code
    <%@page contentType="text/html" pageEncoding="UTF-8" %>
    <jsp:useBean id="user" class="com.test.User"/>
    <jsp:setProperty name="user"  param="name" property="name"></jsp:setProperty>
    <jsp:setProperty name="user"  param="age" property="age"></jsp:setProperty>
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8">
        <title>Hello</title>
    </head>
    <body>
    <p>
        姓名:<jsp:getProperty name="user" property="name"/><br>
        年龄:<jsp:getProperty name="user" property="age"/>
    </p>
    </body>
    </html>
    index.jsp

    测试地址:http://127.0.0.1/index.jsp?name=zs&age=18

    响应结果:

    姓名:zs
    年龄:18

    如果是获取客户端参数,有三种写法:

    写法一:
      <jsp:setProperty name="user" param="name" property="name"></jsp:setProperty>
      <jsp:setProperty name="user" param="age" property="age"></jsp:setProperty>

    写法二:
      <jsp:setProperty name="user" property="name"></jsp:setProperty>
      <jsp:setProperty name="user" property="age"></jsp:setProperty>
      如果不指定请求参数名称,JSP的自省机制会判断是否有相同名称的请求参数,有的话就找出并调用对应的setter方法。

    写法三:
      <jsp:setProperty name="user" property="*"></jsp:setProperty>
      在property属性设置为“*”时,表示将自动寻找请求参数,如果请求参数名称为xxx,就将请求参数值使用setXxx()方法。

      自省机制可以自动转换请求参数字符串为对应属性的基本类型。

      2、直接赋值

      比如:<jsp:setProperty name="user" property="password" value="123456"/>

      3、<jsp:setProperty>的name属性说明

      在产生的Servlet代码中,会使用PageContext的findAttribute(),依次从page、request、session、application中查找看看有无name指定的属性名称,找到的话,再通过反射机制找出JavaBean上的setXxx()方法并执行。


    <jsp:getProperty>标签

      <jsp:getProperty>基本上就只有一种用法:<jsp:getProperty name="user" property="name"/>。
      这会通过PageContext的findAttribute()从page、request、session、application中依序查找user属性,并通过getName()方法取得值。


    两种不两只的写法

    一、在使用<jsp:useBean>时可以一并设置属性值

    <jsp:useBean id="user" class="com.test.User" scope="session">
        <jsp:setProperty name="user" property="*" />
    </jsp:useBean>
    View Code

    这样转译后产生以下代码:  

        synchronized (session) {
            user = (com.test.User) _jspx_page_context.getAttribute("user", javax.servlet.jsp.PageContext.SESSION_SCOPE);
            if (user == null){
              user = new com.test.User();
              _jspx_page_context.setAttribute("user", user, javax.servlet.jsp.PageContext.SESSION_SCOPE);
              org.apache.jasper.runtime.JspRuntimeLibrary.introspect(_jspx_page_context.findAttribute("user"), request);
            }
        }

    二、分别编写

    <jsp:useBean id="user" class="com.test.User" scope="session"/>
    <jsp:setProperty name="user" property="*" />
    View Code

    这样转译后产生以下代码:

        synchronized (session) {
            user = (com.test.User) _jspx_page_context.getAttribute("user", javax.servlet.jsp.PageContext.SESSION_SCOPE);
            if (user == null){
              user = new com.test.User();
              _jspx_page_context.setAttribute("user", user, javax.servlet.jsp.PageContext.SESSION_SCOPE);
            }
          }
        org.apache.jasper.runtime.JspRuntimeLibrary.introspect(_jspx_page_context.findAttribute("user"), request);

    如果使用后一种写法,则无论找到还是新建JavaBean对象,都一定会使用内省机制来设值。

  • 相关阅读:
    hanlp在jdk11 maven8编译后在jdk8 报错
    Linux top命令输出到文件——持续输出某个进程的信息
    maven with depend
    解决mount时发生错误wrong fs type, bad option, bad superblock
    leetcode中 01背包问题相关汇总
    leetcode刷题总结901-950
    Xgboost如何处理缺失值/
    leetcode刷题总结851-900
    leetcode刷题总结801-850
    leetcode刷题总结751-800
  • 原文地址:https://www.cnblogs.com/Mike_Chang/p/10082550.html
Copyright © 2020-2023  润新知