Saturday, March 31, 2012

Endpoint documentation controller for Spring MVC 3.1

I saw a demo on new Spring MVC 3.1 features by Rossen Stoyanchev a while back and found one particular demo item incredibly useful.
The demonstration was for an Endpoint Controller - a page to display all the uri's supported by the application, their corresponding handler methods and related patterns(method, params etc).

The RequestMappingHandlerMapping component of Spring MVC maps the uri's to different @RequestMapped methods, and the demo item shows a way to expose these uri's and handler methods using a controller - the Endpoint documentation Controller, which looks like this:


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

@Controller
public class EndpointDocController {
 private final RequestMappingHandlerMapping handlerMapping;

 @Autowired
 public EndpointDocController(RequestMappingHandlerMapping handlerMapping) {
  this.handlerMapping = handlerMapping;
 }
 
 @RequestMapping(value="/endpointdoc", method=RequestMethod.GET)
 public void show(Model model) {
  model.addAttribute("handlerMethods", this.handlerMapping.getHandlerMethods());
 } 
}

and a jsp page to display this information cleanly:
<div class="container">
  <div class="container">
    <h1>Spring MVC 3.1 Demo Endpoints</h1>
    <c:forEach items="${handlerMethods}" var="entry">
      <div>
        <hr>
        <p><strong>${entry.value}</strong></p>      
      </div>
      <div class="span-3 colborder">
        <p>
          <span class="alt">Patterns:</span><br> 
          <c:if test="${not empty entry.key.patternsCondition.patterns}">
            ${entry.key.patternsCondition.patterns}
          </c:if>
        </p>
      </div>
......


This would be something along the lines of what is displayed in the UI:


More information is available at the demo link and at Rossen Stoyanchev's github location: https://github.com/rstoyanchev/spring-mvc-31-demo.git

4 comments:

  1. Gives me the following error with Spring 4.1.1

    No qualifying bean of type [org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping] found for dependency:

    Any suggestions?

    ReplyDelete
  2. You should declare a bean of type org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping either in your spring config file or configuration class

    ReplyDelete
  3. Thank you, you saved me!! I didn't know where to hit my head, but now... It Works!!!! I used this trick to create WADL for Rest Services, adapting an old script found googling (and I think that original question came from a user who had my same problem with same controller)

    ReplyDelete
  4. use this java based config.

    @Configuration
    @EnableWebMvc
    public class WebConfig extends WebMvcConfigurationSupport {

    @Override
    @Bean
    public RequestMappingHandlerMapping requestMappingHandlerMapping() {
    RequestMappingHandlerMapping hm = super.requestMappingHandlerMapping();
    hm.setUseSuffixPatternMatch(false);
    return hm;
    }
    }

    ReplyDelete