Spring MVC de part sa structure supporte l'architecture de type REST. Il n'utilise cependant pas le standard JSR-311. Il existe plusieurs implémentations de ce standard comme Jersey, Restlet, Apache CXF, et la plupart fournissent une génération automatique de wadl.
Je me suis donc motivé pour générer cette wadl avec un simple Controller spring.
Pour cela, je me suis fortement basé sur l'article suivant :
http://nurkiewicz.blogspot.com/2012/02/automatically-generating-wadl-in-spring.html
Source du controlleur :
package org.dyndns.tuxgalaxy.springrestwadl.controllers; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Map; import java.util.Set; import javax.servlet.http.HttpServletRequest; import net.java.dev.wadl._2009._02.WadlApplication; import net.java.dev.wadl._2009._02.WadlDoc; import net.java.dev.wadl._2009._02.WadlMethod; import net.java.dev.wadl._2009._02.WadlParam; import net.java.dev.wadl._2009._02.WadlParamStyle; import net.java.dev.wadl._2009._02.WadlRepresentation; import net.java.dev.wadl._2009._02.WadlRequest; import net.java.dev.wadl._2009._02.WadlResource; import net.java.dev.wadl._2009._02.WadlResources; import net.java.dev.wadl._2009._02.WadlResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.mvc.condition.ProducesRequestCondition; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; @Controller @RequestMapping("/application.wadl") public class WadlController { @Autowired private RequestMappingHandlerMapping handlerMapping; @RequestMapping(method=RequestMethod.GET, produces={"application/xml"} ) public @ResponseBody WadlApplication generateWadl(HttpServletRequest request) { WadlApplication result = new WadlApplication(); WadlDoc doc = new WadlDoc(); doc.setTitle("REST Service WADL"); result.getDoc().add(doc); WadlResources wadResources = new WadlResources(); wadResources.setBase(getBaseUrl(request)); MaphandletMethods = handlerMapping.getHandlerMethods(); for (Map.Entry entry : handletMethods.entrySet()) { WadlResource wadlResource = new WadlResource(); HandlerMethod handlerMethod = entry.getValue(); RequestMappingInfo mappingInfo = entry.getKey(); Set pattern = mappingInfo.getPatternsCondition().getPatterns(); Set httpMethods = mappingInfo.getMethodsCondition().getMethods(); ProducesRequestCondition producesRequestCondition = mappingInfo.getProducesCondition(); Set mediaTypes = producesRequestCondition.getProducibleMediaTypes(); for (RequestMethod httpMethod : httpMethods) { WadlMethod wadlMethod = new WadlMethod(); for (String uri : pattern) { wadlResource.setPath(uri); } wadlMethod.setName(httpMethod.name()); Method javaMethod = handlerMethod.getMethod(); wadlMethod.setId(javaMethod.getName()); WadlDoc wadlDocMethod = new WadlDoc(); wadlDocMethod.setTitle(javaMethod.getDeclaringClass().getName()+"."+javaMethod.getName()); wadlMethod.getDoc().add(wadlDocMethod); // Request WadlRequest wadlRequest = new WadlRequest(); Annotation[][] annotations = javaMethod.getParameterAnnotations(); for (Annotation[] annotation : annotations) { for (Annotation annotation2 : annotation) { if (annotation2 instanceof RequestParam ) { RequestParam param2 = (RequestParam)annotation2; WadlParam waldParam = new WadlParam(); waldParam.setName(param2.value()); waldParam.setStyle(WadlParamStyle.QUERY); waldParam.setRequired(param2.required()); String defaultValue = cleanDefault(param2.defaultValue()); if ( !defaultValue.equals("") ) { waldParam.setDefault(defaultValue); } wadlRequest.getParam().add(waldParam); } else if ( annotation2 instanceof PathVariable ) { PathVariable param2 = (PathVariable)annotation2; WadlParam waldParam = new WadlParam(); waldParam.setName(param2.value()); waldParam.setStyle(WadlParamStyle.TEMPLATE); waldParam.setRequired(true); wadlRequest.getParam().add(waldParam); } } } if ( ! wadlRequest.getParam().isEmpty() ) { wadlMethod.setRequest(wadlRequest); } // Response if ( !mediaTypes.isEmpty() ) { WadlResponse wadlResponse = new WadlResponse(); wadlResponse.getStatus().add(200l); for (MediaType mediaType : mediaTypes) { WadlRepresentation wadlRepresentation = new WadlRepresentation(); wadlRepresentation.setMediaType(mediaType.toString()); wadlResponse.getRepresentation().add(wadlRepresentation); } wadlMethod.getResponse().add(wadlResponse); } wadlResource.getMethodOrResource().add(wadlMethod); } wadResources.getResource().add(wadlResource); } result.getResources().add(wadResources); return result; } private String getBaseUrl (HttpServletRequest request) { String requestUri = request.getRequestURI(); return request.getScheme()+"://"+ request.getServerName()+":"+ request.getServerPort() + requestUri; } private String cleanDefault(String value) { value = value.replaceAll("\t", ""); value = value.replaceAll("\n", ""); value = value.replaceAll("", ""); value = value.replaceAll("", ""); value = value.replaceAll("", ""); return value; } }
Example de wadl généré
Example
Un example de code se trouve sur google code ( projet : SpringRestWadl )
Importer le projet dans eclipse puis accéder à l'url :
http://localhost:8080/SpringRestWadl/rest/application.wadl