Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

BULL - Bean Utils Light Library

License

NotificationsYou must be signed in to change notification settings

ExpediaGroup/bull

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

BULL

Bean Utils Light Library

BULL is a Java Bean to Java Bean transformer that recursively copies data from one object to another, it is generic, flexible, reusable, configurable, and incredibly fast.It's the only library able to transform Mutable, Immutable, and Mixed bean without any custom configuration.

Start using

Maven CentralJavadocsBuild StatusJoin the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk

GitHub siteCoverage StatusLicenseDependabot

A tutorial that integrates the library can be foundhere.

All BULL modules are available on Maven Central:

  • Bean BOM

It contains all the modules available in the project

<dependency>    <groupId>com.expediagroup.beans</groupId>    <artifactId>bull-bom</artifactId>    <version>x.y.z</version>    <type>pom</type>    <scope>import</scope></dependency>
  • Bean Transformer

<dependency>    <groupId>com.expediagroup.beans</groupId>    <artifactId>bull-bean-transformer</artifactId>    <version>x.y.z</version></dependency>
  • Map Transformer

<dependency>    <groupId>com.expediagroup.beans</groupId>    <artifactId>bull-map-transformer</artifactId>    <version>x.y.z</version></dependency>

The project provides two different builds, one compatible withjdk 8 (or above),one withjdk 11 and on withjdk 17 or above.

In case you need to integrate it in a:

Some jdk versions remove the Java Bean constructor's argument names from the compiled code and this may cause problems to the library.On top of that, it's suggested to configure themaven-compiler-plugin, inside your project, as follow:

<build>    ...    <pluginManagement>        <plugins>            ...            <plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-compiler-plugin</artifactId>                <version>${maven.compiler.plugin.version}</version>                <configuration>                    <source>${maven.compiler.source}</source>                    <target>${maven.compiler.target}</target>                    <parameters>true</parameters>                    <forceJavacCompilerUse>true</forceJavacCompilerUse>                </configuration>            </plugin>        </plugins>    </pluginManagement>    ...</build>

Maven build

Full build

./mvnw clean install

or on Windows

mvnw.cmd clean install

Skip test coverage and checkstyle check

./mvnw clean install -P relaxed

or on Windows

mvnw.cmd clean install -P relaxed

Check for dependencies update

mvn versions:display-dependency-updates -P check-for-updates

or on Windows

mvnw.cmd versions:display-dependency-updates -P check-for-updates

Features:

  • support copy of immutable beans.
  • support copy of mutable beans.
  • support copy of hybrid beans (some fields private and some not).
  • support copy of Java Records.
  • support copy of Java beans without getter and setter methods.
  • support copy with Java primitive type.
  • support copy with Java Collection type. e.g.List<BeanA> => List<BeanB>
  • support copy with nested map fields. e.g.Map<String, Map<String, String>>
  • support copy with array containing primitive types. e.g.String[] =>String[]
  • support copy with an array type. e.g.BeanA[] =>BeanB[]
  • support copy with property name mapping. e.g.int id => int userId
  • support copy with recursion copy.
  • support validation through annotations.
  • support copy of beans with different field's name.
  • support lambda function field transformation.
  • support copy of java bean built through Builder.
  • easy usage, declarative way to define the property mapping (in case of different names), or simply adding the Lombok annotations.
  • allows setting the default value for all objects not existing in the source object.
  • allows skipping transformation for a given set of fields.
  • supports the retrieval of the value from getters if a field does not exist in the source object.
  • supports the automatic conversion of primitive types.

Feature samples

Bean transformation samples

Simple case:

publicclassFromBean {publicclassToBean {privatefinalStringname;@NotNullprivatefinalBigIntegerid;publicBigIntegerid;privatefinalList<FromSubBean>subBeanList;privatefinalStringname;privateList<String>list;privatefinalList<String>list;privatefinalFromSubBeansubObject;privatefinalList<ToSubBean>subBeanList;privateImmutableToSubFoosubObject;// all constructors                                         // all args constructor// getters and setters...                                   // getters and setters...}

And one line code as:

ToBeantoBean =beanUtils.getTransformer().transform(fromBean,ToBean.class);

Different field names copy:

From class and To class with different field names:

publicclassFromBean {publicclassToBean {privatefinalStringname;privatefinalStringdifferentName;privatefinalintid;privatefinalintid;privatefinalList<FromSubBean>subBeanList;privatefinalList<ToSubBean>subBeanList;privatefinalList<String>list;privatefinalList<String>list;privatefinalFromSubBeansubObject;privatefinalToSubBeansubObject;// getters...publicToBean(finalStringdifferentName,finalintid,}finalList<ToSubBean>subBeanList,finalList<String>list,finalToSubBeansubObject) {this.differentName =differentName;this.id =id;this.subBeanList =subBeanList;this.list =list;this.subObject =subObject;    }// getters...}

And one line code as:

beanUtils.getTransformer().withFieldMapping(newFieldMapping<>("name","differentName")).transform(fromBean,ToBean.class);

it is also possible to map a field in the source class into multiple fields in the destination object.

Given the following source class:

public class SourceClass {    private final String name;    private final int id;}

the following destination class:

public class DestinationClass {    private final String name;    private final int id;    private final int index;}

and the following operations:

var sourceObj = new SourceClass("foo", 123);var multipleFieldMapping = new FieldMapping<>("id", "index", "identifier");var destObj = new BeanUtils().getBeanTransformer()                     .withFieldMapping(multipleFieldMapping)                     .transform(sourceObj, DestinationClass.class);System.out.println("name = " + destObj.getName());System.out.println("id = " + destObj.getId());System.out.println("index = " + destObj.getIndex());

the output will be:

name = fooid = 123index = 123

Mapping destination fields with correspondent fields contained inside one of the nested objects in the source object:

Assuming that the objectFromSubBean is declared as follow:

publicclassFromSubBean {privateStringserialNumber;privateDatecreationDate;// getters and setters...}

and our source object and destination object are described as follow:

publicclassFromBean {publicclassToBean {privatefinalintid;privatefinalintid;privatefinalStringname;privatefinalStringname;privatefinalFromSubBeansubObject;privatefinalStringserialNumber;privatefinalDatecreationDate;// all args constructor                                     // all args constructor// getters...                                               // getters...}                                                           }

the fields:serialNumber andcreationDate needs to be retrieved fromsubObject, this can be done by defining the whole path to the end property:

FieldMappingserialNumberMapping =newFieldMapping<>("subObject.serialNumber","serialNumber");FieldMappingcreationDateMapping =newFieldMapping<>("subObject.creationDate","creationDate");beanUtils.getTransformer()         .withFieldMapping(serialNumberMapping,creationDateMapping)         .transform(fromBean,ToBean.class);

Different field names defining constructor args:

publicclassFromBean {publicclassToBean {privatefinalStringname;privatefinalStringdifferentName;privatefinalintid;privatefinalintid;privatefinalList<FromSubBean>subBeanList;privatefinalList<ToSubBean>subBeanList;privatefinalList<String>list;privatefinalList<String>list;privatefinalFromSubBeansubObject;privatefinalToSubBeansubObject;// all args constructor// getters...publicToBean(@ConstructorArg("name")finalStringdifferentName,@ConstructorArg("id")finalintid,}@ConstructorArg("subBeanList")finalList<ToSubBean>subBeanList,@ConstructorArg(fieldName ="list")finalList<String>list,@ConstructorArg("subObject")finalToSubBeansubObject) {this.differentName =differentName;this.id =id;this.subBeanList =subBeanList;this.list =list;this.subObject =subObject;                                                                     }// getters...                                                                                                          }

And one line code as:

ToBeantoBean =beanUtils.getTransformer().transform(fromBean,ToBean.class);

Different field names and types applying transformation through lambda function:

publicclassFromBean {publicclassToBean {privatefinalStringname;@NotNullprivatefinalBigIntegerid;publicBigIntegeridentifier;privatefinalBigIntegerindex;publicBigIntegerindex;privatefinalList<FromSubBean>subBeanList;privatefinalStringname;privateList<String>list;privatefinalList<String>list;privatefinalFromSubBeansubObject;privatefinalList<ImmutableToSubFoo>nestedObjectList;privatefinalStringlocale;privatefinalLocalelocale;privateImmutableToSubFoonestedObject;// constructors...                                          // constructors...// getters and setters...                                   // getters and setters...                                                                                                                              }                                                           }
FieldTransformer<BigInteger,BigInteger>fieldTransformer =newFieldTransformer<>("identifier",BigInteger::negate);FieldTransformer<String,Locale>localeTransformer =newFieldTransformer<>("locale",Locale::forLanguageTag);beanUtils.getTransformer()    .withFieldMapping(newFieldMapping<>("id","identifier"))    .withFieldTransformer(fieldTransformer).transform(fromBean,ToBean.class)    .withFieldTransformer(localeTransformer);

It's also possible to apply the same transformation function on multiple fields. Taking as an example the above bean andassuming that we would negate both the id and the identifier, the transformer function has to be defined as follows:

FieldTransformer<BigInteger,BigInteger>fieldTransformer =newFieldTransformer<>(List.of("identifier","index"),BigInteger::negate);

Assign a default value in case of missing field in the source object:

Assign a default value in case of a missing field in the source object:

publicclassFromBean {publicclassToBean {privatefinalStringname;@NotNullprivatefinalBigIntegerid;publicBigIntegerid;privatefinalStringname;privateStringnotExistingField;// this will be null and no exceptions will be raised// constructors...                                          // constructors...// getters...                                               // getters and setters...}                                                           }

And one line code as:

ToBeantoBean =beanUtils.getTransformer()                    .setDefaultValueForMissingField(true).transform(fromBean,ToBean.class);

Disable the default value set for primitive types in case they are null:

BULL by default sets the default value for all primitive types fields in case their value is in the source object.Given the following Java Bean:

publicclassFromBean {publicclassToBean {privatefinalStringname;@NotNullprivatefinalBigIntegerid;publicBigIntegerid;privatefinalStringname;// constructors...                                          // constructors...// getters...                                               // getters and setters...}                                                           }

in case the fieldid in theFromBean object isnull, the value assigned the correspondent field in theToBean object will be0.To disable this you can simply do:

ToBeantoBean =beanUtils.getTransformer()                    .setDefaultValueForMissingPrimitiveField(false).transform(fromBean,ToBean.class);

in this case, the fieldid after the transformation will benull

Applying a transformation function in case of missing fields in the source object:

Assign a default value in case of a missing field in the source object:

publicclassFromBean {publicclassToBean {privatefinalStringname;@NotNullprivatefinalBigIntegerid;publicBigIntegerid;privatefinalStringname;privateStringnotExistingField;// this will have value: sampleVal// all args constructor                                     // constructors...// getters...                                               // getters and setters...}                                                           }

And one line code as:

FieldTransformer<String,String>notExistingFieldTransformer =newFieldTransformer<>("notExistingField", () ->"sampleVal");ToBeantoBean =beanUtils.getTransformer()                    .withFieldTransformer(notExistingFieldTransformer)                    .transform(fromBean,ToBean.class);

Apply a transformation function on a field contained in a nested object:

This example shows how a lambda transformation function can be applied to a nested object field.

Given:

publicclassFromBean {publicclassToBean {privatefinalStringname;privatefinalStringname;privatefinalFromSubBeannestedObject;privatefinalToSubBeannestedObject;// all args constructor                                     // all args constructor// getters...                                               // getters...}                                                           }

and

publicclassToSubBean {privatefinalStringname;privatefinallongindex;                    }

Assuming that the lambda transformation function should be applied only to field:name contained into theToSubBean object, the transformation function has to be defined asfollow:

FieldTransformer<String,String>nameTransformer =newFieldTransformer<>("nestedObject.name",StringUtils::capitalize);ToBeantoBean =beanUtils.getTransformer()                    .withFieldTransformer(nameTransformer)                    .transform(fromBean,ToBean.class);

Map a primitive type field in the source object into a nested object:

This example shows how to map a primitive field into a nested object into the destination one.

Given:

publicclassFromBean {publicclassToBean {privatefinalStringname;privatefinalStringname;privatefinalFromSubBeannestedObject;privatefinalToSubBeannestedObject;privatefinalintx;// all args constructor                                     // all args constructor// getters...                                               // getters...}                                                           }

and

publicclassToSubBean {privatefinalintx;// all args constructor}// getters...

Assuming that the valuex should be mapped into the field:x contained into theToSubBean object, the field mapping has to be defined asfollow:

ToBeantoBean =beanUtils.getTransformer()                    .withFieldMapping(newFieldMapping<>("x","nestedObject.x"));

Apply a transformation function on all fields matching with the given one:

This example shows how a lambda transformation function can be applied to all fields matching with the given one independently from their position.

Given:

publicclassFromBean {publicclassToBean {privatefinalStringname;privatefinalStringname;privatefinalFromSubBeannestedObject;privatefinalToSubBeannestedObject;// all args constructor                                     // all args constructor// getters...                                               // getters...}                                                           }

and

publicclassFromSubBean {publicclassToSubBean {privatefinalStringname;privatefinalStringname;privatefinallongindex;privatefinallongindex;// all args constructor                                     // all args constructor// getters...                                               // getters...}                                                           }

Assuming that the lambda transformation function should be applied only to the field:name contained in theToSubBean object, the transformation function has to be definedasfollow:

FieldTransformer<String,String>nameTransformer =newFieldTransformer<>("name",StringUtils::capitalize);ToBeantoBean =beanUtils.getTransformer()                    .setFlatFieldNameTransformation(true)                    .withFieldTransformer(nameTransformer)                    .transform(fromBean,ToBean.class);

Static transformer function:

List<FromFooSimple>fromFooSimpleList =Arrays.asList(fromFooSimple,fromFooSimple);

can be transformed as follow:

Function<FromFooSimple,ImmutableToFooSimple>transformerFunction =BeanUtils.getTransformer(ImmutableToFooSimple.class);List<ImmutableToFooSimple>actual =fromFooSimpleList.stream()                .map(transformerFunction)                .collect(Collectors.toList());

or if you have a pre-configured transformer:

Function<FromFooSimple,ImmutableToFooSimple>transformerFunction =BeanUtils.getTransformer(<yourPreconfiguredTransformer>,ImmutableToFooSimple.class);List<ImmutableToFooSimple>actual =fromFooSimpleList.stream()                .map(transformerFunction)                .collect(Collectors.toList());

Enable Java Beans validation:

Assuming that the field:id in the fromBean instance is null.

publicclassFromBean {publicclassToBean {privatefinalStringname;@NotNullprivatefinalBigIntegerid;publicBigIntegerid;privatefinalStringname;// all args constructor                                     // all args constructor// getters...                                               // getters and setters...}                                                            }

adding the following configuration an exception will be thrown:

ToBeantoBean =beanUtils.getTransformer()                     .setValidationEnabled(true)                     .transform(fromBean,ToBean.class);

Copy on an existing instance:

Given:

publicclassFromBean {publicclassToBean {privatefinalStringname;privateStringname;privatefinalFromSubBeannestedObject;privateToSubBeannestedObject;// all args constructor                                     // constructor// getters...                                               // getters and setters...}                                                           }

if you need to perform the copy on an already existing object, just do:

ToBeantoBean =newToBean();beanUtils.getTransformer().transform(fromBean,toBean);

Skip transformation on a given set of fields:

Given:

publicclassFromBean {publicclassToBean {privatefinalStringname;privateStringname;privatefinalFromSubBeannestedObject;privateToSubBeannestedObject;// all args constructor                                     // constructor// getters...                                               // getters and setters...}                                                           }publicclassFromBean2 {privatefinalintindex;privatefinalFromSubBeannestedObject;// all args constructor// getters...}

if you need to skip the transformation for a given field, just do:

ToBeantoBean =newToBean();beanUtils.getTransformer()    .skipTransformationForField("nestedObject")    .transform(fromBean,toBean);

wherenestedObject is the name of the field in the destination object.

This feature allows us totransform an object keeping the data from different sources.

To better explain this function let's assume that theToBean (defined above) should be transformed as follow:

  • name field value has been taken from theFromBean object
  • nestedObject field value has been taken from theFromBean2 object

the objective can be reached by doing:

// create the destination objectToBeantoBean =newToBean();// execute the first transformation skipping the copy of: 'nestedObject' field that should come from the other source objectbeanUtils.getTransformer()    .skipTransformationForField("nestedObject")    .transform(fromBean,toBean);// then execute the transformation skipping the copy of: 'name' field that should come from the other source objectbeanUtils.getTransformer()    .skipTransformationForField("name")    .transform(fromBean2,toBean);

Keep a field type value from the source object as is:

Given:

publicclassFromBean {publicclassToBean {privatefinalStringname;privateStringname;privatefinalDateTimedateTime;privatefinalDateTimedateTime;// all args constructor                                     // constructor// getters...                                               // getters and setters...}                                                           }

if you need to keep the value of a field type from the source object as it, you can add all the types you want to keep as they areby doing:

ClassUtils.CUSTOM_SPECIAL_TYPES.add(DateTime.class);ToBeantoBean =newToBean();beanUtils.getTransformer()    .transform(fromBean,toBean);

Not existing field in the source object:

In case the destination class has a field that does not exist in the source object, but it contains a getter method returning the value, the library should gets the field value from that method.

publicclassFromBean {publicclassToBean {privatefinalBigIntegerid;publicBigIntegergetId() {returnBigInteger.TEN;// all args constructor   }// getters...}                                                                                                                           }

And one line code as:

ToBeantoBean =beanUtils.getTransformer().transform(fromBean,ToBean.class);

Transform primitive types automatically

Given the following Java Bean:

publicclassFromBean {publicclassToBean {privatefinalStringindexNumber;privatefinalintindexNumber;privatefinalBigIntegerid;publicLongid;// constructors...                                          // constructors...// getters...                                               // getters and setters...}                                                           }

as, by default the primitive type conversion is disabled, to get the above object converted we should haveimplemented transformer functions for both fieldindexNumber andid, but this can be done automatically by enabling thethe functionality described above.

Transformertransformer =beanUtils.getTransformer()                             .setPrimitiveTypeConversionEnabled(true);ToBeantoBean =transformer.transform(fromBean,ToBean.class);

IMPORTANT: The primitive type transformation (if enabled) is executed before any otherFieldTransformer function is defined on a specific field.This means that once theFieldTransformer function will be executed the field value has already been transformed.

Builder supported patterns

The library supports the transformation of Java Bean using the following Builder patterns:

Standard pattern:

publicclassItemType {privatefinalClass<?>objectClass;privatefinalClass<?>genericClass;ItemType(finalClass<?>objectClass,finalClass<?>genericClass) {this.objectClass =objectClass;this.genericClass =genericClass;    }publicstaticItemTypeBuilderbuilder() {returnnewItemType.ItemTypeBuilder();    }// getter methodspublicstaticclassItemTypeBuilder {privateClass<?>objectClass;privateClass<?>genericClass;ItemTypeBuilder() {        }publicItemTypeBuilderobjectClass(finalClass<?>objectClass) {this.objectClass =objectClass;returnthis;        }publicItemTypeBuildergenericClass(finalClass<?>genericClass) {this.genericClass =genericClass;returnthis;        }publicItemTypebuild() {returnnewItemType(this.objectClass,this.genericClass);        }    }}

Custom Builder pattern:

To enable the transformation of Java Beans using the following Builder pattern:

publicclassItemType {privatefinalClass<?>objectClass;privatefinalClass<?>genericClass;ItemType(finalItemTypeBuilderbuilder) {this.objectClass =builder.objectClass;this.genericClass =builder.genericClass;    }publicstaticItemTypeBuilderbuilder() {returnnewItemType.ItemTypeBuilder();    }// getter methodspublicstaticclassItemTypeBuilder {privateClass<?>objectClass;privateClass<?>genericClass;ItemTypeBuilder() {        }publicItemTypeBuilderobjectClass(finalClass<?>objectClass) {this.objectClass =objectClass;returnthis;        }publicItemTypeBuildergenericClass(finalClass<?>genericClass) {this.genericClass =genericClass;returnthis;        }publicItemTypebuild() {returnnewItemType(this);        }    }}

It's needed to enable the custom Builder Transformation as follows:

ToBeantoBean =newBeanTransformer()                         .setCustomBuilderTransformationEnabled(true)                         .transform(sourceObject,ToBean.class);

Transform Java Record

Simple case:

publicrecordFromFooRecord(BigIntegerid,Stringname) {publicrecordRecordToFoo(BigIntegerid,Stringname) {                           }                                                            }

And one line code as:

vartoBean =beanUtils.getTransformer().transform(fromBean,RecordToFoo.class);

Constraints:

  • the class's fields that have to be copied must not be static

More sample beans can be found in the test package:com.expediagroup.beans.sample

Third-party library comparison

Following a comparison between the BULL functionalities and the following Third-Party libraries:

BULLApache Bean UtilsJacksonDozer
Mutable bean copyXXXX+
Mutable bean with nested objectsX-XX+
Mutable bean extending classesX-XX+
Immutable bean copyX--X*
Mixed bean copyX--X+
Copy of beans without getter and setter methods definedX---
Mutable Bean with different field's nameX--X+
Mixed with different field's typeX--X+
Immutable with different field's typeX--X+
Mutable Bean containing collection type fields containing complex objectsX-XX
Mixed Bean containing collection type fields containing complex objectsX--X+
Immutable Bean containing collection type fields containing complex objectsX--X+
Mutable Bean containing containing Map type fields with nested Maps inside. e.g.Map<String, Map<String, Integer>>X-XX
Mixed Bean containing containing Map type fields with nested Maps inside. e.g.Map<String, Map<String, Integer>>X--X+
Immutable Bean containing containing Map type fields with nested Maps inside. e.g.Map<String, Map<String, Integer>>X--X+
Annotation field validationX-X-

[*] Immutable types are not supported by Dozer. When a type doesn't have a no-arg constructor and all fields are final, Dozer can't perform the mapping.A workaround is introducing the Builder Pattern. An example can be foundhere[+] Requires a custom configuration

Performance

Let's have a look at the performance library performance. The test has been executed on the following objects:

  • Mutable objects
  • Mutable objects extending another mutable object
  • Immutable objects
  • Immutable objects extending another immutable object
  • Mixed objects
MutableImmutableMixed
Simple objects (without nested objects)~0.011ms~0.018msNA
Complex objects (containing several nested object and several items in Map and Array objects)~0.37ms~0.21ms~0.22ms
CPU/Heap usage~0.2%/35 MB~0.2%/30 MB~0.2%/25 MB

Transformation timescreenshot

Real case testing

The Bean Utils library has been tested on a real case scenario integrating it into a real edge service (called BPE).The purpose was to compare the latency introduced by the library plus the memory/CPU usage.The dashboard's screenshot shows the latency of the invoked downstream service (called BPAS) and the one where the library has been installed (BPE).Following the obtained results:

Classic transformerBeanUtils library
Throughput per second6060
Average CPU usage0.3%0.3%
Min/Max Heap Memory Usage (MB)90/32090/320
Average Latency than the downstream service+2ms+2ms
JVM stats screenshotscreenshotscreenshot
Dashboard screenshotscreenshotscreenshot

Validation samples

Validating a java bean has never been so simple. The library offers different APIs related to this, following some examples:

Validate a Java Bean:

Given the following bean:

publicclassSampleBean {@NotNullprivateBigIntegerid;privateStringname;// constructor// getters and setters...}

an instance of the above object:

SampleBeansampleBean =newSampleBean();

And one line code as:

beanUtils.getValidator().validate(sampleBean);

this will throw anInvalidBeanException as theid field is null.

Retrieve the violated constraints:

Given the following bean:

publicclassSampleBean {@NotNullprivateBigIntegerid;privateStringname;// constructor// getters and setters...}

an instance of the above object:

SampleBeansampleBean =newSampleBean();

And one line code as:

List<String>violatedConstraints =beanUtils.getValidator().getConstraintViolationsMessages(sampleBean);

this will return a list containing a constraint validation message for theid field as it's null and the constraint:@NotNull is not met.

in case it's needed to have theConstraintViolation object:

Set<ConstraintViolation<Object>>violatedConstraints =beanUtils.getValidator().getConstraintViolations(sampleBean);

Primitive type object converter

Converts a given primitive value into the given primitive type.The supported types, in which an object can be converted (from/to), are:

  • Byte,byte orbyte[]
  • Short orshort
  • Integer orint
  • Long orlong
  • Float orfloat
  • Double ordouble
  • BigDecimal
  • BigInteger
  • Character orchar
  • Boolean orboolean
  • String

Convert a String into an int:

Given the following variable:

StringindexNumber ="26062019";

to convert it in anint:

Converterconverter =newBeanUtils().getPrimitiveTypeConverter();intindexNumber =converter.convertValue(indexNumber,int.class);

Obtain a conversion function that converts from char to byte:

It's possible to obtain a type conversion function, reusable several times in different places.Assuming that the required conversion is fromchar to `byte

charc ='1';

the conversion function is retrieved through:

Converterconverter =newBeanUtils().getPrimitiveTypeConverter();Optional<Function<Object,Object>>conversionFunction =converter.getConversionFunction(char.class,byte.class);byteconverted =conversionFunction.map(processor ->processor.apply(c)).orElse(0);
  • in case the conversion is not needed as the primitive type and the destination type are the same it will return an emptyOptional
  • in case the conversion function is unavailable or no not possible the method throws a:TypeConversionException

Map transformation samples

Samples on how to transform aMap and all others function applicable to it can be viewedhere

Documentation

Detailed project documentation is availablehere, including some samples fortesting the library inside your project.

An article that explains how it works, with suggestions and examples, is available on DZone:How to Transform Any Type of Java Bean With BULL

Credits

Created by:Fabio Borriello with the contribution of:Patrizio Munzi,Andrea Marsiglia,Giorgio Delle Grottaglie & the Hotels.com's Checkout team in Rome.

The application's logo has been designed by Rob Light.

Related articles

Release

All the instructions for releasing a new version are available atRELEASES.md

Badge your project

Bull enabled

Add the following snippet in your Markdown file:

[![Bull enabled](https://img.shields.io/badge/bull-enabled-red?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAA8FBMVEUAAADRKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi/RKi////+bJRrYAAAATnRSTlMAABoFB0UGATtcHQsinVIEAz3Dy6QwHmzlylsTl/uGVvXonjMm0+pLApjjNO3nv0H3/N9VTVnauEn49r391vCCcnsJCn76aa6LFxnVZrus5DL8AAAApElEQVR42k2NA7rDABAGM89mbZupbbd7/9sU8Xzc/aUYwN09igMeHp+eHR94eX17tx/w8fn1+m08gJ/fv3+XG+vh8fpE/AEPGI9gKCxXIrYlGhOJJ5KWI5UWyWRzmBP3+au/UASe0Qy/peujXKlyr9XyHJIrtbraaLa0x1tbdGKdlPbo9vqDQX84GstEu5kOZ/PFcrXOqpsf7bFN72B/mHA8LVAuoY0XA5ziPJYAAAAASUVORK5CYII=)](https://github.com/ExpediaGroup/bull)

Support

Join the chat at https://join.slack.com/t/bull-crew/shared_invite/enQtNjM1MTE5ODg1MTQzLWI5ODhhYTQ2OWQxODgwYzU1ODMxMWJiZDkzODM3OTJkZjBlM2MwMTI3ZWZjMmU0OGZmN2RmNjg4NWI2NTMzOTk

For any question, proposal, or help, please refer to the slack channel:#bull.

Legal

This project is available under theApache 2.0 License.

Copyright 2018-2023 Expedia Inc.


[8]ページ先頭

©2009-2025 Movatter.jp