Skip to main content

Spring MVC and Reflection

Annotation based Spring MVC controllers and annotations in general provide flexibility for rapid application development in today's JAVA development environment. When you combine annotations with reflection you get quick, neat and powerful solutions. Here is an example that combines a simple annotated Spring MVC form with reflection.

@RequestMapping(method = RequestMethod.POST)
    public String processSubmit(@ModelAttribute TestPlan testPlan, BindingResult result) {
        if (result.hasErrors()) {
            return "test/form";
        } else {
            try {

                prepareTestPlan(testPlan);
                // find the right method and execute it
                Method[] methods = WebServiceTestForm.class.getMethods();
                for (Method m : methods) {
                    TestDesc t = m.getAnnotation(TestDesc.class);
                    if (t != null && t.name() != null && t.name().equals(testPlan.getTestName())) {
                        Map<String, Object> map = applicationContext.getBeansWithAnnotation(Controller.class);
                        WebServiceTestForm form = (WebServiceTestForm) map.get(WebServiceTestForm.class.getSimpleName());
                        try {
                            m.invoke(form, testPlan);
                        } catch (InvocationTargetException e) {
                            logger.error(e.getMessage(), e);
                        } catch (IllegalAccessException e) {
                            logger.error(e.getMessage(), e);
                        }
                    }
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                testPlan.setResult("Error: " + e.toString());
            }
            return "test/form";
        }
    }

The method above is configured to be execute a when a form is submitted. TestPlan object in the above code is a POJO that is backing the form. Therefore TestPlan object is populated with whatever values are submitted from the form. WebServiceTestForm is the Spring MVC form controller object that this processSubmit method belongs.

In the processSubmit method, reflection is used to find a method of this WebServiceTestForm. Input for the reflection is provided by the TestPlan object through user submitting the form. Once the method is found through reflection, it needs to be invokded. However  before it can be invoked correctly the singleton instance of the bean must be accessed through the Spring context. Therefore ApplicationContext object of Spring framework is used . With Spring 3.0.X ApplicationContext interface can be used to locate beans with annotations. Once the bean is located method is invoked on the bean.

With reflection, annotations and Spring's ApplicationContext, this code is used pretty much as the entry point for all from submissions and is responsible for correctly executing logic with much less code.

Please note: This code is not tested in a production environment. With use of reflection, you should always carefully test, think of security and monitor performance.

Comments