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

el, field-accessors, getter-setter, jsf

Solution

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.

Problem

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); } } } ```

Original source