Spring 中的 BeanWrapper

news2024/11/13 23:26:30

BeanWrapper 是 Spring 框架中的一个接口,它提供了一种方式来设置和获取 JavaBean 的属性。JavaBean 是一种特殊的 Java 类,遵循特定的编码约定(例如,私有属性和公共的 getter/setter 方法),通常用于封装数据

主要功能
1.属性访问:
        BeanWrapper 允许以统一的方式访问 JavaBean 对象的属性,包括简单属性、复杂类型属性、集合和数组等。它支持通过属性路径(property path)来访问嵌套对象的属性,例如 person.address.streetName。
2.类型转换:
        BeanWrapper 内置了对常见类型的转换支持,可以自动处理不同数据类型的转换。
可以注册自定义的 PropertyEditor 或使用 ConversionService 来实现更复杂的类型转换逻辑。
3.属性编辑器:
        可以为特定的数据类型注册 PropertyEditor,这允许在从字符串到对象或反之的转换过程中进行定制化处理。
4.错误处理:
        当尝试设置非法值或访问不存在的属性时,BeanWrapper 可以捕获并报告这些错误。

访问简单属性 

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

public class BeanWrapperExample {
    public static void main(String[] args) {
        // 创建一个目标对象
        Person person = new Person();

        // 创建 BeanWrapper 实例
        BeanWrapper beanWrapper = new BeanWrapperImpl(person);

        // 设置属性值
        beanWrapper.setPropertyValue("name", "John Doe");
        beanWrapper.setPropertyValue("age", 30);

        // 获取属性值
        String name = (String) beanWrapper.getPropertyValue("name");
        int age = (Integer) beanWrapper.getPropertyValue("age");

        System.out.println("Name: " + name);
        System.out.println("Age: " + age);
    }
}

class Person {
    private String name;
    private int age;

    // 必须提供 getter 和 setter 方法
    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;
    }
}

 访问嵌套属性

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

public class NestedPropertyAccess {
    public static void main(String[] args) {
        Person person = new Person();
        Address address = new Address();
        person.setAddress(address);
        
        BeanWrapper beanWrapper = new BeanWrapperImpl(person);
        
        // 设置嵌套属性
        beanWrapper.setPropertyValue("address.street", "123 Main St");
        beanWrapper.setPropertyValue("address.city", "Springfield");
        
        // 获取嵌套属性
        String street = (String) beanWrapper.getPropertyValue("address.street");
        String city = (String) beanWrapper.getPropertyValue("address.city");
        
        System.out.println("Street: " + street); // 输出: Street: 123 Main St
        System.out.println("City: " + city);     // 输出: City: Springfield
    }
}

class Person {
    private String name;
    private int age;
    private Address address;

    // Getters and Setters
    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 Address getAddress() { return address; }
    public void setAddress(Address address) { this.address = address; }
}

class Address {
    private String street;
    private String city;

    // Getters and Setters
    public String getStreet() { return street; }
    public void setStreet(String street) { this.street = street; }
    public String getCity() { return city; }
    public void setCity(String city) { this.city = city; }
}

自动类型转换

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

public class TypeConversion {
    public static void main(String[] args) {
        Person person = new Person();
        
        BeanWrapper beanWrapper = new BeanWrapperImpl(person);
        
        // 设置属性值,自动类型转换
        beanWrapper.setPropertyValue("age", "30"); // 字符串 "30" 转换为 int 30
        
        // 获取属性值
        int age = (Integer) beanWrapper.getPropertyValue("age");
        
        System.out.println("Age: " + age); // 输出: Age: 30
    }
}

class Person {
    private String name;
    private int age;

    // Getters and Setters
    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; }
}

注册自定义 PropertyEditor

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import java.beans.PropertyEditorSupport;

public class CustomPropertyEditor {
    public static void main(String[] args) {
        Person person = new Person();
        
        BeanWrapper beanWrapper = new BeanWrapperImpl(person);
        
        // 注册自定义 PropertyEditor
        beanWrapper.registerCustomEditor(Date.class, new DateEditor());
        
        // 设置日期属性
        beanWrapper.setPropertyValue("birthdate", "2023-01-01");
        
        // 获取日期属性
        Date birthdate = (Date) beanWrapper.getPropertyValue("birthdate");
        
        System.out.println("Birthdate: " + birthdate); 
        // 输出: Birthdate: Sun Jan 01 00:00:00 CST 2023
    }
}

class Person {
    private String name;
    private int age;
    private Date birthdate;

    // Getters and Setters
    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 Date getBirthdate() { return birthdate; }
    public void setBirthdate(Date birthdate) { this.birthdate = birthdate; }
}

class DateEditor extends PropertyEditorSupport {
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        try {
            setValue(new SimpleDateFormat("yyyy-MM-dd").parse(text));
        } catch (ParseException e) {
            throw new IllegalArgumentException("Invalid date format");
        }
    }
}

 处理属性设置错误

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.PropertyAccessException;

public class ErrorHandling {
    public static void main(String[] args) {
        Person person = new Person();
        
        BeanWrapper beanWrapper = new BeanWrapperImpl(person);
        
        try {
            // 尝试设置一个不存在的属性
            beanWrapper.setPropertyValue("invalidProperty", "value");
        } catch (PropertyAccessException e) {
            System.out.println("Error: " + e.getMessage());
// 输出: Error: Invalid property 'invalidProperty' of bean class [Person]: 
// Bean property 'invalidProperty' is not readable or has an invalid getter 
// method: Does the return type of the getter match the parameter type 
// of the setter?
        }
    }
}

class Person {
    private String name;
    private int age;

    // Getters and Setters
    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; }
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2238259.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Pr:视频过渡快速参考(合集 · 2025版)

Adobe Premiere Pro 自带七组约四十多个视频过渡 Video Transitions效果,包含不同风格和用途,可在两个剪辑之间创造平滑、自然的转场,用来丰富时间、地点或情绪的变化。恰当地应用过渡可让观众更好地理解故事或人物。 提示: 点击下…

stm32 踩坑笔记

串口问题: 问题:会改变接收缓冲的下一个字节 串口的初始化如下,位长度选择了9位。因为要奇偶校验,要选择9位。但是接收有用数据只用到1个字节。 问题原因: 所以串口接收时会把下一个数据更改

昇思大模型平台打卡体验活动:项目4基于MindSpore实现Roberta模型Prompt Tuning

基于MindNLP的Roberta模型Prompt Tuning 本文档介绍了如何基于MindNLP进行Roberta模型的Prompt Tuning,主要用于GLUE基准数据集的微调。本文提供了完整的代码示例以及详细的步骤说明,便于理解和复现实验。 环境配置 在运行此代码前,请确保…

后悔没早点知道,Coze 插件 + Cursor 原来可以这样赚钱

最近智能体定制化赛道异常火爆。 打开闲鱼搜索"Coze 定制",密密麻麻的服务报价直接刷屏,即使表明看起来几十块的商家,一细聊,都是几百到上千不等的报价。 有趣的是,这些智能体定制化服务背后,最核心的不只是工作流设计,还有一个被很多人忽视的重要角色 —— …

基于STM32的节能型路灯控制系统设计

引言 本项目基于STM32微控制器设计了一个智能节能型路灯控制系统,通过集成多个传感器模块和控制设备,实现对路灯的自动调节。该系统能够根据周围环境光照强度、车辆和行人活动等情况,自动控制路灯的开关及亮度调节,从而有效减少能…

Qml 模型-视图-代理(贰)之 动态视图学习

目录 动态视图 动态视图用法 ⽅向(Orientation) 键盘导航和⾼亮 页眉与页脚 网格视图 动态视图 动态视图用法 Repeater 元素适合有限的静态数据, QtQuick 提供了 ListView 和 GridView, 这两个都是基于 Flickable(可滑动) 区域的元素…

新标准大学英语综合教程1课后习题答案PDF第三版

《新标准大学英语(第三版)综合教程1 》是“新标准大学英语(第三版)”系列教材之一。本书共包含6个单元,从难度和话题上贴近大一上学生的认知和语言水平,包括与学生个人生活领域和社会文化等相关内容&#x…

Python闭包|你应该知道的常见用例(下)

引言 在 Python 编程语言中,闭包通常指的是一个嵌套函数,即在一个函数内部定义的另一个函数。这个嵌套的函数能够访问并保留其外部函数作用域中的变量。这种结构就构成了一个闭包。 闭包在函数式编程语言中非常普遍。在 Python 中,闭包特别有…

Rocky、Almalinux、CentOS、Ubuntu和Debian系统初始化脚本v9版

Rocky、Almalinux、CentOS、Ubuntu和Debian系统初始化脚本 Shell脚本源码地址: Gitee:https://gitee.com/raymond9/shell Github:https://github.com/raymond999999/shell脚本可以去上面的Gitee或Github代码仓库拉取。 支持的功能和系统&am…

AUTOSAR OS模块详解(一) 概述

AUTOSAR OS模块详解(一) 概述 本文主要介绍AUTOSAR架构下的OS概述。 文章目录 AUTOSAR OS模块详解(一) 概述1 前言1.1 操作系统1.2 嵌入式操作系统1.3 AUTOSAR操作系统 2 AUTOSAR OS2.1 AUTOSAR OS组成2.2 AUTOSAR OS类别2.3 任务管理2.4 调度表2.5 资源管理2.6 多核特性2.7 …

5位机械工程师如何共享一台工作站的算力?

在现代化的工程领域中,算力已成为推动创新与技术进步的关键因素之一。对于机械工程师而言,强大的计算资源意味着能够更快地进行复杂设计、模拟分析以及优化工作,从而明显提升工作效率与项目质量。然而,资源总是有限的,…

Scala 中 set 的实战应用 :图书管理系统

1. 创建书籍集合 首先,我们创建一个可变的书籍集合,用于存储图书馆中的书籍信息。在Scala中,mutable.Set可以用来创建一个可变的集合。 val books mutable.Set("朝花惜拾", "活着") 2. 添加书籍 我们可以使用操作符…

DevCheck Pro手机硬件检测工具v5.33

前言 DevCheck Pro是一款手机硬件和操作系统信息检测查看工具,该软件的功能非常强大,为用户提供了系统、硬件、应用程序、相机、网络、电池等一系列信息查看功能 安装环境 [名称]:DevCheckPro [版本]:5.33 [大小]&a…

cv::intersectConvexConvex返回其中一个输入点集,两个点集不相交

问题:cv::intersectConvexConvex返回其中一个输入点集,但两个点集并不相交 版本:opencv 3.1.0 git上也有人反馈了intersectConvexConvex sometimes returning one of the input polygons in case of empty intersection #10044 是凸包嵌套判…

【刷题12】ctfshow刷题

来源:ctfshow easyPytHon_P 考点:代码审计,源代码查看 打开后查看源码,发现一个源码地址,打开看看 可以知道在此目录下有个flag.txt文件,再观察源码 from flask import request cmd: str request.form.get…

spark的学习-03

RDD的创建的两种方式: 方式一:并行化一个已存在的集合 方法:parallelize 并行的意思 将一个集合转换为RDD 方式二:读取外部共享存储系统 方法:textFile、wholeTextFile、newAPIHadoopRDD等 读取外部存储系统的数…

axios平替!用浏览器自带的fetch处理AJAX(兼容表单/JSON/文件上传)

fetch 是啥? fetch 函数是 JavaScript 中用于发送网络请求的内置 API,可以替代传统的 XMLHttpRequest。它可以发送 HTTP 请求(如 GET、POST 等),并返回一个 Promise,从而简化异步操作 基本用法 /* 下面是…

Linux(CentOS)安装 Nginx

CentOS版本:CentOS 7 Nginx版本:1.24.0 有两种安装方式 一、通过 yum 安装 需要 root 权限,普通用户使用 sudo 进行命令操作 参考:https://nginx.org/en/linux_packages.html#RHEL 1、安装依赖 sudo yum install yum-utils 2…

[原创]手把手教学之前端0基础到就业——day11( Javascript )

文章目录 day11(Javascript)01Javascript①Javascript是什么②JavaScript组成③ Javascript的书写位置1. 行内式 (不推荐)2 . 内部位置使用 ( 内嵌式 )3. 外部位置使用 ( 外链式 ) 02变量1. 什么是变量2. 定义变量及赋值3. 注意事项4. 命名规范 03输入和输出1) 输出形式12) 输出…

【C++笔记】C++三大特性之继承

【C笔记】C三大特性之继承 🔥个人主页:大白的编程日记 🔥专栏:C笔记 文章目录 【C笔记】C三大特性之继承前言一.继承的概念及定义1.1 继承的概念1.2继承的定义1.3继承基类成员访问方式的变化1.4继承类模板 二.基类和派生类间的转…