Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

With EL, is it possible to do field access on beans rather than getters/setters?

EDIT

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);
        }
    }
}
like image 712
Jonathan S. Fisher Avatar asked Jan 30 '13 17:01

Jonathan S. Fisher


People also ask

What can I use instead of getters and setters?

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.

Do getters and setters permit different access levels?

Getters and setters can allow different access levels - for example the get may be public, but the set could be protected.

Do getters always need setters?

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.

What's the advantage of using getters and setters that only get and set instead of simply using public fields for those variables?

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.


1 Answers

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.

like image 147
Buhake Sindi Avatar answered Sep 22 '22 23:09

Buhake Sindi