Javaweb学习笔记(JavaBean组件)

Javaweb学习笔记(JavaBean组件),第1张

Javaweb学习笔记(JavaBean组件)

Javaweb学习笔记(JavaBean组件)

初识JavaBean

什么是JavaBean访问JavaBean的属性 反射

认识Class类通过反射创建对象

通过无参构造方法实例化对象通过有参构造方法实例化对象 通过反射访问属性通过反射调用方法 内省

什么是内省修改JavaBean属性读取JavaBean的属性 JSP标签访问JavaBean

< jsp:useBean>

单独使用class属性单独使用type属性beanName属性和type属性相结合使用 < jsp:setProperty>标签

property属性单独使用 < jsp:getProperty>标签

初识JavaBean 什么是JavaBean

JavaBean是Java开发语言中一个重复使用的软件组件,他本质是一个Java类。
JavaBean编码规范为:
(1)他必须具有一个公共的、无参的构造方法,这个方法可以是编译器自动产生的默认构造方法。
(2)它提供公共的setter方法和getter方法让外部程序设置和获取JavaBean的属性。

访问JavaBean的属性

在JavaBean中属性和成员变量不是一个概念,它是以方法定义的形式出现的,这些方法必须遵循一定的命名规范。
例如:JavaBean中包含一个String类型的name属性,那么在JavaBean中必须至少包含getName()和setName()方法中的一个,这两个方法的声明如下所示:

public String getName();
public String setName(String name);

(1)getName()方法:
称为getter方法或者属性访问器,该方法以小写的get前缀开始,后跟属性名,属性名的第一个字母要大写。
(2)setName()方法
称为setter方法或者属性修改器该方法必须以小写的set前缀开始后跟属性名,属性名的第一个字母要大写。
如果一个属性只有getter方法,则该属性为只读属性,如果一个属性只有setter则该属性为只写属性,如果既有getter方法也有setter方法,则该属性为读写属性,通常来说在开发JavaBean时,其属性都定义为读写属性。
如果一个属性类型为Boolean,那么它的命名方式为is/get而不是set/get。

反射 认识Class类

Java反射的源头是Class类,一般情况下需要先有一个类的完整路径引入后,才可以按照固定的格式产生示例化对象,但是在Java中允许通过一个水利化对象找到一个类的完整信息,这就是Class类的作用。
示例:

package cn.itcast.chapter04.servlet;
class X{}
public class Student {
	public static void main(String[] args){
		X x=new X();
		System.out.println(x.getClass().getName());
	}
}


程序输出了对象所在的完整的“包.类”的名称,对象x调用了getClass()方法,该方法是从Object类中继承来的,此方法的定义为:

public final ClassgetClass()

该方法的返回值是一个Class类,Class类表示一个类的本身,同过Class可以完整地得到一个类中的结构,包括此类中的方法定义、属性定义等。Class类中常用的方法:

方法声明功能描述static Class forName(String className)返回与带有给定字符串名或类接口相关联的Class对象Constructor[]getConstructors()返回一个包含某些Constructor对象的数组,这些对象反映此Class对象所表示类的所有公共构造方法Field[] getDeclaredField(String name)返回包含某些Field对象的数组,这些对象反映此Class对象所表示的类或接口所声明的所有字段。Field[] getFields()返回一个包含某些Field对象的数组,这些对象反映此Class对象所标识的类或借口的所有可访问公共字段,包括继承的公共字段Method[] getMethod()返回一个包含某些Method对象的数组,这些对象反映此Class对象锁表是的类或接口的公共成员方法。Method getMethod(String name,Class…parameterTypes)返回一个Method对象,反映此Class对象所表示的类或接口实现的接口Class[] getInterfaces()返回该类所实现的接口的一个数组,确定此对象所表示的类或接口实现的接口String getName()以String的形式返回次Class对象所标识的实体名称Package getPackage()获取此类的包Class getsuperclass()返回此Class所表示的实体的超类的ClassT newInstance()创建此Class对象所表示类的一个新实例booleanisArray()判定此Class对象是否表示一个数组类

在Class类中本身没有定义非私有的构造方法,因此不能通过new直接创建Class类的实例,获得Class类的实例有3中方式:
(1)通过“对象.getClass()”方式获取该对象的Class实例。
(2)通过Class类的静态方法forName(),用类的全路径名获取一个Class实例。
(3)通过“类名.class”的方式来获取Class实例,对于基本数据类型的封装类,还可以采用.TYPE来获取相对应的基本数据类型的Class实例。

通过反射创建对象

当时用构造方法创建对象时,构造方法可以是有参的也可以是无参的。

通过无参构造方法实例化对象

如果想通过Class类本身实例化其他类的对象,那么可以使用newInstance()方法,但是必须要保证被实例化的类中存在一个无参构造方法。
例:

package cn.itcast.chapter04.servlet;
class Person{
	private String name;
	private int age;
	public String getName(){
		return name;
	}
	public void setName(String name){
		this.name=name;
	}
	public int getAge(){
		return age;
	}
	public void setAge(int age){
		this.age=age;
	}
	public String toString(){
		return"姓名:"+this.name+",年龄:"+this.age;
	}
}
public class ReflectDemo01 {
	public static void main(String[] args)throws Exception{
		Class clazz=Class.forName("cn.itcast.chapter04.servlet.Person");
		Person p=(Person)clazz.newInstance();
		p.setName("张三");
		p.setAge(18);
		System.out.print(p);
	}
}

通过有参构造方法实例化对象

通过有参构造方法实例化对象有三个步骤:
(1)通过Class类的getConstructors()获取本类中的全部构造方法。
(2)向构造方法中传递一个对象数组进去,里面包含构造方法中所需的各个参数。
(3)通过Constructor类实例化对象。
Constructor常用的方法:

方法声明功能描述int getModifiles()获取构造方法的修饰符String getName()获得构造方法的名称Class[] getParameterTypes()获取构造方法中的参数类型T newInstance(Object…intargs)向构造方法中传递参数,实例化对象

示例:

package cn.itcast.chapter04.servlet;

import java.lang.reflect.Constructor;

class Person{
	private String name;
	private int age;
	public Person(String name,int age){
		this.name=name;
		this.age=age;
	}
	public String getName(){
		return name;
	}
	public void setName(String name){
		this.name=name;
	}
	public int getAge(){
		return age;
	}
	public void setAge(int age){
		this.age=age;
	}
	public String toString(){
		return"姓名:"+this.name+",年龄:"+this.age;
	}
}
public class ReflectDemo01 {
	public static void main(String[] args)throws Exception{
		Class clazz=Class.forName("cn.itcast.chapter04.servlet.Person");
		Constructor cons[]=clazz.getConstructors();
		Person p=(Person)cons[0].newInstance("张三",30);
		System.out.print(p);
	}
}

通过反射访问属性

通过反射不仅可以创建对象,还可以访问属性,在反射机制中,属性的 *** 作是通过Filed类实现的,它提供的set()和get()方法分别作用与设置和获取属性,如果访问的属性时私有的,需要在使用set()和get()方法前,使用Filed类中的setAccessible()方法将需要 *** 作的属性设置成可以被外界访问的。
示例:

package cn.itcast.chapter04.servlet;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
class Person{
	private String name;
	private int age;
	public String toString(){
		return"姓名:"+this.name+",年龄:"+this.age;
	}
}
public class ReflectDemo01 {
	public static void main(String[] args)throws Exception{
		Class clazz=Class.forName("cn.itcast.chapter04.servlet.Person");
		Object p=clazz.newInstance();
		Field nameField=clazz.getDeclaredField("name");
		nameField.setAccessible(true);
		nameField.set(p, "李四");
		Field ageField=clazz.getDeclaredField("age");
		ageField.setAccessible(true);
		ageField.set(p, 20);
		System.out.print(p);
	}
}

通过反射调用方法

当获得某个类对应的Class对象后,可以通过Class对象的getMethods()方法和getMethod()方法获取全部方法或者制定方法,getMethod方法返回值是Method对象,getMethods方法返回值是Method对象数组。在Method里包含一个invoke()方法,该方法定义为:

public Object invoke(Object obj,object args....);

上述方法中obj是该方法主要参数,args是一个相当于数组的可变参数,用来接收传入的实参。
示例:

package cn.itcast.chapter04.servlet;

import java.lang.reflect.Method;

class Person{
	private String name;
	private int age;
	public String sayHello(String name,int age){
		return "姓名:"+name+",年龄:"+age;
	}
}
public class ReflectDemo01 {
	public static void main(String[] args)throws Exception{
		Class clazz=Class.forName("cn.itcast.chapter04.servlet.Person");
		Method md=clazz.getMethod("sayHello", String.class,int.class);
		String result=(String)md.invoke(clazz.newInstance(), "张三",35);
		System.out.print(result);
	}
}

内省 什么是内省

JDK提供了一套API用来访问某个属性的getter和setter方法,这就是内省。
内省访问JavaBean有两种方法:
(1)先通过java.beans包下的Instrospector类获得JavaBean对象的BeanInfo信息,再通过BeanInfo获取属性的描述器,然后通过这个属性描述器就可以获取某个属性对应的getter和setter方法,最后通过反射机制来调用这些方法。
(2)直接通过java.beans包下的PropertyDescriptor类来 *** 作Bean对象。
示例:
Person.java

package JavaBean;

public class Person {
		private String name;
		private int age;
		public String getName(){
			return name;
		}
		public void setName(String name){
			this.name=name;
		}
		public int getAge(){
			return age;
		}
		public void setAge(int age){
			this.age=age;
		}
		public String sayHello(){
			return "姓名:"+this.name+",年龄:"+this.age;
		}


}

Introspector01.java

package JavaBean;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;

import JavaBean.Person;
public class Introspector01 {
	public static void main(String[] args)throws Exception{
		Person beanObj=new Person();
		BeanInfo bInfoObject=Introspector.getBeanInfo(beanObj.getClass());
			beanObj.getClass().getSuperclass();
		String str="内省成员属性:n";
		PropertyDescriptor[] mPropertyArry=bInfoObject.getPropertyDescriptors();
		for(int i=0;i 

修改JavaBean属性

在java中,还可以通过内省来修改JavaBean属性
示例:

package JavaBean;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

import JavaBean.Person;
public class Introspector01 {
	public static void main(String[] args)throws Exception{
		Person p=new Person();
		PropertyDescriptor pd=new PropertyDescriptor("name",p.getClass());
		Method methodName=pd.getWriteMethod();
		methodName.invoke(p, "小明");
		String val="20";
		pd=new PropertyDescriptor("age",p.getClass());
		Method methodAge=pd.getWriteMethod();
		Class clazz=pd.getPropertyType();
		if(clazz.equals(int.class)){
			methodAge.invoke(p, Integer.valueOf(val));
		}else{
			methodAge.invoke(p, val);
		}
		System.out.println(p);
	}

}

读取JavaBean的属性

使用PropertyDescriptor类的getWriteMethod()方法可以获取属性对应的setter方法,在JavaBean中属性getter和setter是成对出现的,因此java的内省也提供了读取JavaBean属性的方法,只要使用PropertyDescriptor类的getMethod()方法。
示例:

package JavaBean;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

import JavaBean.Person;
public class Introspector01 {
	public static void main(String[] args)throws Exception{
		Person p=new Person();
		p.setName("李芳");
		p.setAge(18);
		PropertyDescriptor pd=new PropertyDescriptor("name",p.getClass());
		Method methodName=pd.getReadMethod();
		Object o=methodName.invoke(p);
		System.out.println("姓名"+o);
		pd=new PropertyDescriptor("age",p.getClass());
		Method methodAge=pd.getReadMethod();
		o=methodAge.invoke(p);
		System.out.println("年龄"+o);
	}
}

JSP标签访问JavaBean < jsp:useBean>

< jsp:useBean>标签用于在某个指定的域范围中查找一个指定名称的JavaBean对象,如果存在则直接返回JavaBean对象的引用,如果不存在则实例化一个新的JavaBean对象并将它按指定的名称存储在指定的域范围中,语法格式为:

 [scope="{page | requst | session | application}]
{
	|
	type="package.class"|
	 type="package.class"|
	beanName="{package.class|<%=expression>}" type="package.class"
} />

其中有5个属性:
(1)id:用于指定JavaBean实例对象的引用名称和其存储在域范围中的名称
(2)scope:用于指定JavaBean实例对象所存储的域范围,其取值只能是page、request、session、application中的一个,默认值是page。
(3)type:用于指定JavaBean实例对象的引用变量类型,必须是JavaBean对象的类名称、父类名称或将JavaBean实现的接口名称。type属性值默认值是class属性的设置值,当JSP容器将< jsp:useBean>标签翻译成Servlet程序时。他将使用type属性值作为JavaBean对象引入变量的类型。
(4)class:用于指定JavaBean的完整类名,JSP容器将使用这个类名来创建JavaBean的实例对象或作为查找到的JavaBean对象的类型。
(5)beanName:用于指定的JavaBean的名称,它的值是a.b.c,这既可以代表一个类的完整名称,也可以代表a/b/c.ser这样的资源文件。

单独使用class属性

示例:先创建两个JavaBean类Employee和Manager。
Employee:

package login;

public class Employee {
	private String company;
	public String getCompany(){
		return company;
	}
	public void setCompany(String company){
		this.company=company;
	}
}

Manager:

package login;

public class Manager {
	private double bonus;
	public double geBonus(){
		return bonus;
	}
	public void setBonus(double bonus){
		this.bonus=bonus;
	}
}

useBean.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




Insert title here


	



翻译成的Servlet

单独使用type属性

将上面的< jsp:Bean>标签中的class改成type:


会出现
当只设置type属性时,JSP容器会在指定的域范围中查找以id属性值为名称的JavaBean对象,如果找不到就会抛出异常。
在< jsp:useBean>标签上面写一段JSP脚本片段,为pageContext多加一个域。

<%
	pageContext.setAttribute("manager", new login.Manager());
%>

beanName属性和type属性相结合使用

将useBean.jsp中的JSP脚本去掉,对< jsp:useBean>标签进行修改。


翻译成的Servlet文件中的代码为:

< jsp:setProperty>标签

< jsp:setProperty>标签可以用来为JavaBean对象设置属性。语法格式为:

< jsp:setProperty name="beanInstanceName"{
	property="propertyName" value="{string |<%=expression%>}"
	property="propertyName" param="parameterName" |property="propertyName |*"
}/>

< jsp:setProperty>标签有四个属性。
(1)name:用于指定JavaBean实例对象名称,其值应该和< jsp:useBean>标签的id属性值相同。
(2)property:用于指定JavaBean实例对象的属性名
(3)param:用于指定请求消息中参数的名字
(4)用于指定为JavaBean实例对象的某个属性设置的值,其值可以是字符串也可以是实例对象。

property属性单独使用

(1)property的属性值为JavaBean的属性
当property属性值为JavaBean的一个属性名时,JSP容器会将请求消息中与property属性值同名的参数值赋给JavaBean对应的属性。
示例:
创建一个setProperty.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="GBK" 
    import="login.Manager"
    %>




Insert title here


	
	
	<%
		manager=(Manager)pageContext.getAttribute("manager");
		out.write("bonus属性的值为:"+manager.getBonus());
	%>




可以看到请求中bonus的值赋给了JavaBean。
如果请求中没有bonus属性,bonus属性值为空字符串,那么JavaBean的值不会被改变。

(2)property的属性值为通配符时
property的属性值为
通配符时,JSP容器会在请求消息中查找所有的请求参数,如果有参数和JavaBean对象属性名相同,JSP容器会将参数的值设置为JavaBean对象对应属性的值。
示例:


	
	<%
		manager=(Manager)pageContext.getAttribute("manager");
		out.write("bonus属性的值为:"+manager.getBonus()+"
"); out.write("company属性的值为:"+manager.getCompany()+"
"); %>

访问http://localhost:9090/chapter05/setProperty.jsp?bonus=800.0&&company=itcast

< jsp:getProperty>标签

如果JavaBean的属性值是一个引用数据类型时,< jsp:getProperty>会调用该对象的toString()方法,如果JavaBean属性时null,< jsp:getProperty>会输出null。语法格式如下:

<< jsp:getProperty name="beanInstanceName" property="PropertyName" />

其中有两个属性:
(1)name用于指定JavaBean实例对象名称。
(2)property用于指定JavaBean的实例对象。
需要注意的是在使用< jsp:getProperty>时,name和property属性都不能省略。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/zaji/5709954.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存