Dynamic Proxy in Java EL [closed]

2019-05-10 04:18发布

问题:

EDIT: I narrowed down the problem and posted the related question here. Please check it out!

I am trying to use dynamic proxies to make HTML form processing easier. I am using a pretty plain MVC setup (no fancy frameworks) using JSPs on Google App Engine. I keep getting the following exception:

javax.el.PropertyNotFoundException: Could not find property testValue in class com.sun.proxy.$Proxy7
    at javax.el.BeanELResolver.toBeanProperty(BeanELResolver.java:430)
    at javax.el.BeanELResolver.getValue(BeanELResolver.java:290)
    at javax.el.CompositeELResolver.getValue(CompositeELResolver.java:231)
    at org.apache.el.parser.AstValue.getValue(AstValue.java:123)
    at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:186)
    ...

Okay, so here is the code. First, the interface I am proxying:

public interface MyForm {
      public String getTestValue();
}

Next, the code that creates the proxy:

// imports omitted

public final class Forms {

    private Forms() { }

    public static <T> T fromRequest(
            final Class<T> klass,
            final HttpServletRequest request) {

        Object proxy = Proxy.newProxyInstance(
                klass.getClassLoader(),
                new Class<?>[]{ klass },
                new InvocationHandler() {
                    @Override public Object invoke(
                            Object proxy,
                            Method method,
                            Object[] args) throws Throwable {

                        return "Will this be returned?";
                    }
                });
        return (T)proxy;
    }
}

Next the "action" class:

// imports omitted

public class MyAction extends Action {

    // Called by the controller, which forwards to the returned JSP
    public String perform(HttpServletRequest request) throws Exception {

        final MyForm form = Forms.fromRequest(MyForm.class, request);
        request.setAttribute("form", form);
        return "view.jsp";
    }
}

Finally, the JSP:

<html>
    <body>
        <div>${ form.testValue }</div>
    </body>
</html>

As you can see, I'm not actually doing any form processing yet. First, I just want to implement a proof of concept with the dynamic proxy. As mentioned, the code above does not work. However, perplexingly, if I make the request attribute an anonymous class that simply forwards to the proxy, it does work! So the following change fixes it:

request.setAttribute("form", new MyForm() {
    @Override getTestValue() { return form.getTestValue(); }
});

However, having to anonymously subclass the interface kind of defeats the purpose of the proxy. Could someone please tell me what's going on?