Take this answer with a grain of salt. Much has changed since I asked this question years ago. I recommend now using Lombok instead of my EL solution. Leaving the original question for historical reasons.
I'm serious tired of getters/setters clogging my code, when I don't need to control access to the internal state of an object. The only real reason I have to still generate getters/setters is because EL works by locating methods, not fields: ${myBean.fieldName}
. where fieldName
refers to the method getFieldName()
. Would it be possible to extend an EL Resolver to just return the public field value unless a getter was found?
Update based on answer of Steve Atkinson: I hope this helps someone else. Notice how I explicitly check that I only use this elresolver on Form or Lead objects, which are my domain objects.
public class PublicFieldSupportingELResolver extends ELResolver {
@Override
public Class<?> getCommonPropertyType(ELContext context, Object base) {
if (base instanceof Form || base instanceof Lead) {
try {
context.setPropertyResolved(true);
return base.getClass();
} catch (Exception e) {
context.setPropertyResolved(false);
return null;
}
} else {
context.setPropertyResolved(false);
return null;
}
}
@Override
public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
return null;
}
@Override
public Class<?> getType(ELContext context, Object base, Object property) {
if (base instanceof Form || base instanceof Lead) {
try {
Field field = base.getClass().getField((String) property);
context.setPropertyResolved(true);
return field.getType();
} catch (Exception e) {
context.setPropertyResolved(false);
return null;
}
} else {
context.setPropertyResolved(false);
return null;
}
}
@Override
public Object getValue(ELContext context, Object base, Object property) {
if (base instanceof Form || base instanceof Lead) {
try {
Field field = base.getClass().getField((String) property);
Object value = field.get(base);
context.setPropertyResolved(true);
return value;
} catch (Exception e) {
context.setPropertyResolved(false);
return null;
}
} else {
context.setPropertyResolved(false);
return null;
}
}
@Override
public boolean isReadOnly(ELContext context, Object base, Object property) {
if (base instanceof Form || base instanceof Lead) {
try {
base.getClass().getField((String) property);
context.setPropertyResolved(true);
return true;
} catch (Exception e) {
context.setPropertyResolved(false);
return false;
}
} else {
context.setPropertyResolved(false);
return false;
}
}
@Override
public void setValue(ELContext context, Object base, Object property, Object value) {
if (base instanceof Form || base instanceof Lead) {
try {
Field field = base.getClass().getField((String) property);
field.set(base, value);
context.setPropertyResolved(true);
} catch (Exception e) {
context.setPropertyResolved(false);
}
} else {
context.setPropertyResolved(false);
}
}
}
You may use lombok - to manually avoid getter and setter method. But it create by itself. The using of lombok significantly reduces a lot number of code.
Getters and setters can allow different access levels - for example the get may be public, but the set could be protected.
Some data members should be read-only, so they may need getters but not setters. Some data members may need to be kept consistent with each other. In such a case you would not provide a setter for each one, but a single method for setting them at the same time, so that you can check the values for consistency.
The getter and setter method gives you centralized control of how a certain field is initialized and provided to the client, which makes it much easier to verify and debug. To see which thread is accessing and what values are going out, you can easily place breakpoints or a print statement.
You can use @Getter
/@Setter
annotations from Project Lombok if you don't want to write/generate getter and setter method(s) on your Java Bean.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With