views:

2524

answers:

1

Hi,

I'd like to convert this SimpleFormController to use the annotation support introduced in Spring MVC 2.5

Java

public class PriceIncreaseFormController extends SimpleFormController {

    ProductManager productManager = new ProductManager();

    @Override
    public ModelAndView onSubmit(Object command)
            throws ServletException {

        int increase = ((PriceIncrease) command).getPercentage();
        productManager.increasePrice(increase);

        return new ModelAndView(new RedirectView(getSuccessView()));
    }

    @Override
    protected Object formBackingObject(HttpServletRequest request)
      throws ServletException {
        PriceIncrease priceIncrease = new PriceIncrease();
        priceIncrease.setPercentage(20);
        return priceIncrease;
    }

}

Spring Config

<!-- Include basic annotation support -->
<context:annotation-config/>  

<!-- Comma-separated list of packages to search for annotated controllers. Append '.*' to search all sub-packages -->
<context:component-scan base-package="springapp.web"/> 

<!-- Enables use of annotations on controller methods to map URLs to methods and request params to method arguments  -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>

<bean name="/priceincrease.htm" class="springapp.web.PriceIncreaseFormController">
    <property name="sessionForm" value="true"/>
    <property name="commandName" value="priceIncrease"/>
    <property name="commandClass" value="springapp.service.PriceIncrease"/>
    <property name="validator">
        <bean class="springapp.service.PriceIncreaseValidator"/>
    </property>
    <property name="formView" value="priceincrease"/>
    <property name="successView" value="hello.htm"/>
    <property name="productManager" ref="productManager"/>
</bean>

Basically, I'd like to replace all the XML configuration for the /priceincrease.htm bean with annotations within the Java class. Is this possible, and if so, what are the corresponding annotations that I should use?

Thanks, Don

+4  A: 

It'll look something like the following, although whether it works or not exactly as is will depend a bit on your configuration (view resolver, etc). I should also note that there are about eight billion valid ways to write this thing. See the Spring documentation, 13.11.4 "Supported handler method arguments and return types" for an overview of the insanity. Also note that you can autowire the validator

@Controller
@RequestMapping("/priceincrease.htm")
public class PriceIncreaseFormController {

    ProductManager productManager;

    @Autowired
    public PriceIncreaseFormController(ProductManager productManager) {
        this.productManager = productManager;
    }

    // note: this method does not have to be called onSubmit
    @RequestMapping(method = RequestMethod.POST)
    public String onSubmit(@ModelAttribute("priceIncrease") PriceIncrease priceIncrease, BindingResult result, SessionStatus status {

        new PriceIncreaseValidator().validate(priceIncrease, result);
        if (result.hasErrors()) {
            return "priceincrease";
        }
        else {
            int increase = priceIncrease.getPercentage();
            productManager.increasePrice(increase);
            status.setComplete();
            return "redirect:hello.htm";
        }
    }

    // note: this method does not have to be called setupForm
    @RequestMapping(method = RequestMethod.GET)    
    public String setupForm(Model model) {
        PriceIncrease priceIncrease = new PriceIncrease();
        priceIncrease.setPercentage(20);
        model.addAttribute("priceIncrease", priceIncrease);
        return "priceincrease";
    }

}
Boden
It's those eight billion valid ways that I despise and I usually just end up implementing Controller directly - at least then I can trace the interface as appropriate. Both the annotations and the form controller hierarchy are confusing IMO.
MetroidFan2002
The key thing to me is that the annotation based controllers can be unit tested a lot easier than the ones using the old class hierarchy. Of course it takes time to get used to it. Another feature I wouldn't wanna miss anymore is the ability to extend the method parameter injection but the testing thing is the ost ovious one to me.
Oliver Gierke