首页 > 技术文章 > jsp使用javaBean,实现简单的属性编辑器

ant-xu 2019-08-16 13:24 原文

javaBean在使用的时候,会将字符串类型转化为对应的Bean中的类型。Java给出的可以自动转换的类型有boolean、byte、short、int、long、float、double、java.lang.String、java.awt.Color、java.awt.Font,这些都对应有各自的属性编辑器。但如果想要添加新的转换类型,即新的属性编辑器。需要了解一个类和一个接口。本篇将记录String-->java.util.Date的转换。

主要思想是,用属性编辑管理器注册属性编辑器。这样,就能自动转换。属性编辑管理器会自动被调用并自动调用属性编辑器。

接口PropertyEditor:这个接口位于java.beans下。这个接口是属性编辑器的接口,实现这个接口就实现了属性编辑器。这样就能够实现不同类型间的转换,比如这里需要的String-->Date的转换。关于接口中的方法这里不再列出,非常简单的方法一看就明白。对于该接口,java还提供了一个实现类ProPertyEditorSupport。这个实现类为了方便JavaGUI的使用,又添加了一些关于JavaGUI的方法。但是不影响我们的使用。笔者在看完IntegerEditor后认为下面的方法需要注意。

getAsText()-->String:以文本形式获得属性值。

getValue-->Object:获得属性值。

setAsText(String text)-->void:通过解析给定的String设置属性值。

setValue(Object value)-->void:设置(或更改)将编辑的对象。

类PropertyEditorManager:这个类也位于java.beans下。通过名字也可以明白这个是管理属性编辑器的类。文档中这样说:该类使用三种技术来查找给定类型的编辑器。首先,它提供一个 registerEditor 方法,允许专门为某一给定类型注册编辑器。其次,它试图通过将 "Editor" 添加到给定类型的完全限定类名中(例如 "foo.bah.FozEditor")来查找合适的类。最后,它使用简单的类名称(没有包名称)添加 "Editor",并在包的搜索路径中查找匹配类。因此,对于输入类 foo.bah.Fred,PropertyEditorManager 首先将查看其表以确定是否已经为 foo.bah.Fred 注册了编辑器,若已注册,则使用它。然后它将查找 foo.bah.FredEditor 类。接着将查找(比如说)standardEditorsPackage.FredEditor 类。该类有四个静态方法和一个公共无参构造

registerEditor(Class<?> targetType, Class<?> editorClass)-->void,注册一个将用来编辑给定目标类的编辑器类。

findEditor(Class<?> targetType)-->PropertyEditor,查找给定目标类型的值编辑器。

getEditorSearchPaht(Class<?> targetType, Class<?> editorClass)-->String [],获得用来搜索属性编辑器的包名称

setEditorSearchPaht(String [] path)-->void,更改将用来查找属性编辑器的包名称的列表。

本文使用第一种方法,即注册属性编辑器的方法,下面记录过程

1、在了解接口后,决定看下默认的属性编辑器是怎样完成的,于是利用反射的到Integer的属性编辑器中的方法和属性。

public static void main(String[] args) {
        PropertyEditorManager pem = new PropertyEditorManager();
        PropertyEditor propertyEditor =pem.findEditor(Integer.class);
        Class cls = propertyEditor.getClass();
        Field [] fieldList = cls.getDeclaredFields();
        for(Field f: fieldList) {
            System.out.println(f);
        }
        Method [] methodList = cls.getDeclaredMethods();
        for(Method m: methodList) {
            System.out.println(m);
        }
        //输出的结果为
        /*public void com.sun.beans.editors.IntegerEditor.setAsText(java.lang.String) 
        throws java.lang.IllegalArgumentException*/
    }

2、由输出的结果可以看出,这个类中只有一个自己的方法为setAsText(),于是找到该类的源码。

public  void setAsText(String text) throws IllegalArgumentException {
    setValue((text == null) ? null : Integer.decode(text));
}o

3、这里就可以看出,原来大部分的方法实现都在PropertyEditorSupport中。所以有了下面的实现。

public class DatePropertyEditor extends PropertyEditorSupport{
    
    @Override
    public void setAsText(String str) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
         try {
            setValue(sdf.parse(str));
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

4、注册属性编辑器,为了能够在jsp中使用于是利用servlet的init()来完成此步骤的运行。

public class RegisterEditorServlet extends HttpServlet{
    private static final long serialVersionUID = 1L;
    
    public void init() throws ServletException{
        PropertyEditorManager.registerEditor(Date.class, DatePropertyEditor.class);
    }
}

5、servlet的配置。

<servlet>
    <servlet-name>dateEditorRegister</servlet-name>
    <servlet-class>com.test.utils.RegisterEditorServlet</servlet-class>
    <load-on-startup>0</load-on-startup>
</servlet>

6、验证。两个jsp页面如下

<!-- 页面1中只有一个表单,其中由时间的参数 -->
<form action="vertify.jsp">
    <label for="id">账户:</label>
    <input class="form" id="id" type="text" name="id" placeholder="请输入账户"/>
    <label for="pwd">密码:</label>
    <input class="form" id="pwd" type="password" name="pwd" placeholder="请输入密码">
    <label for="time">时间:</label>
    <input class="form" id="time" type="date" name="atime">
    <input type="submit" value="Submit">
    <input type="reset" value="Reset">
</form>

如下是页面2

<jsp:useBean id="user" class="com.test.User"/>    <!-- 准备一个Bean -->
    
<jsp:setProperty property="*" name="user"/>    <!-- 自动赋值 -->

<jsp:getProperty property="id" name="user"/>
<jsp:getProperty property="pwd" name="user"/>
<jsp:getProperty property="atime" name="user"/>    <!-- Date类型自动转化输出 -->

7、结果显示

在找IntegerEditor时看到,这个类继承自NumberEditor,然后看到NumberEditor中也只有一个方法如下。

public String getJavaInitializationString() {
    Object value = getValue();
    return (value != null)
            ? value.toString()
            : "null";
}

然后又看了String的属性转换器,其中只有两个方法

public java.lang.String com.sun.beans.editors.StringEditor.getJavaInitializationString()
public void com.sun.beans.editors.StringEditor.setAsText(java.lang.String)

与NumberEditor和IntegerEditor中方法对应。还有一个属性转换器,用于GUI所以这里没说

找到源码IntegerEditor源码的地方https://jar-download.com/artifacts/com.github.demidenko05/a-javabeans/1.0.4/source-code/com/sun/beans/editors/DoubleEditor.java

推荐阅读