是否仍然使用OGNL来访问未作为bean属性公开的私有变量(即没有get
/ set
方法对)?我想使用OGNL作为一种更快,更清晰的反射方法,用于单元测试。
这是我的代码:
@Test
public void shouldSetup() throws OgnlException{
class A{
private Object b = "foo";
private Object c = "bar";
public Object getB(){ return b; }
}
A a = new A();
System.out.println( "This'll work..." );
Ognl.getValue( "b", a );
System.out.println( "...and this'll fail..." );
Ognl.getValue( "c", a );
System.out.println( "...and we'll never get here." );
}
答案 0 :(得分:1)
其实你可以。您需要在MemberAccess
中设置OgnlContext
以允许访问非公开字段,并使用getValue(ExpressionAccessor expression, OgnlContext context, Object root)
方法检索值。
@Test
public void shouldSetup() throws OgnlException {
class A {
private Object b = "foo";
private Object c = "bar";
public Object getB() { return b; }
}
A a = new A();
// set DefaultMemberAccess with allowed access into the context
OgnlContext context = new OgnlContext();
context.setMemberAccess(new DefaultMemberAccess(true));
System.out.println( "This'll work..." );
// use context in getValue method
Ognl.getValue( "b", context, a );
System.out.println( "...and this'll work..." );
// use context in getValue method
Ognl.getValue( "c", context, a );
System.out.println( "...and we'll get here." );
}
答案 1 :(得分:0)
我能做的最好的事情是直接使用反射:
static Object getValue( final String ognlPath, final Object o ){
final StringTokenizer st = new StringTokenizer( ognlPath, "." );
Object currentO = o;
String nextFieldName = null;
try{
while( st.hasMoreTokens() ){
nextFieldName = st.nextToken();
if( currentO == null ){
throw new IllegalStateException( "Cannot find field '" + nextFieldName + "' on null object." );
}
Field f = currentO.getClass().getDeclaredField( nextFieldName );
f.setAccessible( true );
currentO = f.get( currentO );
}
return currentO;
}catch( NoSuchFieldException e ){
throw new RuntimeException( "Could not find field '" + nextFieldName + "' on " + currentO.getClass().getCanonicalName(), e );
}catch( IllegalAccessException e ){
throw new RuntimeException( "Failed to get from path '" + ognlPath + "' on object: " + o, e );
}
}