REST: springfox improvements, WADL generation
authorGustavo Martin Morcuende <gu.martinm@gmail.com>
Sun, 24 Jan 2016 23:07:57 +0000 (00:07 +0100)
committerGustavo Martin Morcuende <gu.martinm@gmail.com>
Sun, 24 Jan 2016 23:07:57 +0000 (00:07 +0100)
springfox responseContainer="List" doesn't work for me :(

REST/web-services-spring-rest-server/pom.xml
REST/web-services-spring-rest-server/src/doc/main/java/de/spring/webservices/rest/doc/Swagger2Configuration.java [deleted file]
REST/web-services-spring-rest-server/src/doc/main/resources/spring-configuration/spring-config.xml [deleted file]
REST/web-services-spring-rest-server/src/main/java/de/spring/webservices/doc/Swagger2Configuration.java [new file with mode: 0644]
REST/web-services-spring-rest-server/src/main/java/de/spring/webservices/rest/controller/CarController.java
REST/web-services-spring-rest-server/src/main/java/de/spring/webservices/rest/wadl/WADLController.java [new file with mode: 0644]
REST/web-services-spring-rest-server/src/main/resources/spring-configuration/mvc/rest/rest-config.xml
REST/web-services-spring-rest-server/src/main/resources/spring-configuration/spring-doc-config.xml [new file with mode: 0644]
REST/web-services-spring-rest-server/src/main/webapp/WEB-INF/web.xml
REST/web-services-spring-rest/pom.xml

index cff3af6..144a67c 100644 (file)
                        <groupId>com.fasterxml.jackson.core</groupId>
                        <artifactId>jackson-databind</artifactId>
                </dependency>
+
+               <!-- Creates WADL from Spring REST annotations -->
+               <dependency>
+                       <groupId>org.jvnet.ws.wadl</groupId>
+                       <artifactId>wadl-core</artifactId>
+                       <version>1.1.6</version>
+               </dependency>
+               <dependency>
+                       <groupId>org.jvnet.ws.wadl</groupId>
+                       <artifactId>wadl-client-plugin</artifactId>
+                       <version>1.1.6</version>
+               </dependency>
+               <dependency>
+               <groupId>org.springframework</groupId>
+               <artifactId>spring-oxm</artifactId>
+               <version>4.2.4.RELEASE</version>
+               </dependency>
+
+               <!-- API documentation -->
+               <dependency>
+                       <groupId>io.springfox</groupId>
+                       <artifactId>springfox-swagger1</artifactId>
+                       <version>2.3.1</version>
+               </dependency>
+               <dependency>
+                       <groupId>io.springfox</groupId>
+                       <artifactId>springfox-swagger-ui</artifactId>
+                       <version>2.3.1</version>
+               </dependency>
                
                <!-- Required by spring-context for using JSR-303. See LocalValidatorFactoryBean in rest-config.xml -->
                <dependency>
diff --git a/REST/web-services-spring-rest-server/src/doc/main/java/de/spring/webservices/rest/doc/Swagger2Configuration.java b/REST/web-services-spring-rest-server/src/doc/main/java/de/spring/webservices/rest/doc/Swagger2Configuration.java
deleted file mode 100644 (file)
index 6e0de24..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-package de.spring.webservices.rest.doc;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.servlet.config.annotation.EnableWebMvc;
-
-import springfox.documentation.builders.ApiInfoBuilder;
-import springfox.documentation.builders.PathSelectors;
-import springfox.documentation.builders.RequestHandlerSelectors;
-import springfox.documentation.service.ApiInfo;
-import springfox.documentation.spi.DocumentationType;
-import springfox.documentation.spring.web.plugins.Docket;
-import springfox.documentation.swagger.web.UiConfiguration;
-import springfox.documentation.swagger2.annotations.EnableSwagger2;
-
-@Configuration
-@EnableWebMvc
-@EnableSwagger2
-public class Swagger2Configuration {
-       private static final String DOCKET_ID = "web-services-spring-rest";
-       
-       @Bean
-       public Docket documentation() {
-               return new Docket(DocumentationType.SWAGGER_2)
-                               .groupName(DOCKET_ID)
-                               .select()
-                                       .apis(RequestHandlerSelectors.withMethodAnnotation(RequestMapping.class))
-                                       .paths(PathSelectors.any())
-                                       .build()
-                       .pathMapping("/")
-                       .useDefaultResponseMessages(false)
-                       .apiInfo(metadata())
-                       .enable(true);
-       }
-
-       @Bean
-       UiConfiguration uiConfig() {
-               return UiConfiguration.DEFAULT;
-       }
-
-       
-       private static ApiInfo metadata() {
-               return new ApiInfoBuilder()
-                               .title("gumartinm REST API")
-                               .description("Gustavo Martin Morcuende")
-                               .version("1.0-SNAPSHOT")
-                       .contact("gumartinm.name")
-                       .build();
-       }
-
-}
diff --git a/REST/web-services-spring-rest-server/src/doc/main/resources/spring-configuration/spring-config.xml b/REST/web-services-spring-rest-server/src/doc/main/resources/spring-configuration/spring-config.xml
deleted file mode 100644 (file)
index 5ca5917..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:context="http://www.springframework.org/schema/context"
-       xmlns:util="http://www.springframework.org/schema/util"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans
-        http://www.springframework.org/schema/beans/spring-beans.xsd
-        http://www.springframework.org/schema/context
-        http://www.springframework.org/schema/context/spring-context.xsd
-        http://www.springframework.org/schema/util
-        http://www.springframework.org/schema/util/spring-util.xsd">
-
-       <!--
-       
-       Local deployment URLs:
-       
-       Swagger:
-       http://localhost:8080/web-services-spring-rest/spring-rest/v2/api-docs?group=web-services-spring-rest
-       
-       Swagger-UI:
-       http://localhost:8080/web-services-spring-rest/swagger-ui.html
-       
-       -->
-
-    <bean class="de.spring.webservices.rest.doc.Swagger2Configuration"/>
-
-</beans>
diff --git a/REST/web-services-spring-rest-server/src/main/java/de/spring/webservices/doc/Swagger2Configuration.java b/REST/web-services-spring-rest-server/src/main/java/de/spring/webservices/doc/Swagger2Configuration.java
new file mode 100644 (file)
index 0000000..df71590
--- /dev/null
@@ -0,0 +1,58 @@
+package de.spring.webservices.doc;
+
+import static com.google.common.collect.Lists.newArrayList;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.servlet.config.annotation.EnableWebMvc;
+
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.builders.ResponseMessageBuilder;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger.web.UiConfiguration;
+import springfox.documentation.swagger1.annotations.EnableSwagger;
+
+@Configuration
+@EnableWebMvc
+@EnableSwagger
+@ComponentScan("de.spring.webservices.rest.controller")
+public class Swagger2Configuration {
+       
+       @Bean
+       public Docket documentation() {
+               return new Docket(DocumentationType.SWAGGER_12)
+                               .select()
+                                       .apis(RequestHandlerSelectors.withMethodAnnotation(RequestMapping.class))
+                                       .paths(PathSelectors.any())
+                                       .build()
+                                       .globalResponseMessage(RequestMethod.GET,
+                                                       newArrayList(new ResponseMessageBuilder()
+                                                                       .code(500).message("Global server custom error message").build()))
+                       .pathMapping("/")
+                       .useDefaultResponseMessages(false)
+                       .apiInfo(metadata())
+                       .enable(true);
+       }
+
+       @Bean
+       UiConfiguration uiConfig() {
+               return UiConfiguration.DEFAULT;
+       }
+       
+       private static ApiInfo metadata() {
+               return new ApiInfoBuilder()
+                               .title("gumartinm REST API")
+                               .description("Gustavo Martin Morcuende")
+                               .version("1.0-SNAPSHOT")
+                       .contact("gumartinm.name")
+                       .build();
+       }
+
+}
index e769bc6..c81ca23 100644 (file)
@@ -5,6 +5,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicLong;
 
+import javax.ws.rs.Path;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.http.HttpHeaders;
@@ -21,10 +23,11 @@ import org.springframework.web.bind.annotation.ResponseStatus;
 import org.springframework.web.bind.annotation.RestController;
 
 import de.spring.webservices.domain.Car;
-
-//import io.swagger.annotations.ApiOperation;
-//import io.swagger.annotations.ApiResponse;
-//import io.swagger.annotations.ApiResponses;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiParam;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+import io.swagger.annotations.ResponseHeader;
 
 @RestController
 @RequestMapping("/api/cars/")
@@ -34,12 +37,11 @@ public class CarController {
     
     private final AtomicLong counter = new AtomicLong();
 
-//  Do I want to release with Swagger dependencies?
-//    @ApiOperation(value = "getCars", nickname = "getAllCars", response = Car.class)
-//    @ApiResponses({
-//        @ApiResponse(code =  404, message ="Not found"),
-//        @ApiResponse(code =  400, message ="Invalid input")
-//    })
+       @ApiOperation(value = "Get all available cars", nickname = "getAllCars", responseContainer="List", response = Car.class)
+    @ApiResponses({
+        @ApiResponse(code =  404, message ="Specific getCars not found"),
+        @ApiResponse(code =  400, message ="Specific getCars invalid input")
+    })
     @RequestMapping(produces = { MediaType.APPLICATION_JSON_UTF8_VALUE }, method = RequestMethod.GET)
     @ResponseStatus(HttpStatus.OK)
     public List<Car> cars() {
@@ -51,16 +53,15 @@ public class CarController {
         return cars;
     }
 
-//  Do I want to release with Swagger dependencies?
-//  @ApiOperation(value = "getCar", nickname = "getsOneCar", response = Car.class)
-//  @ApiResponses({
-//      @ApiResponse(code =  404, message ="Not found"),
-//      @ApiResponse(code =  400, message ="Invalid input")
-//  })
+       @ApiOperation(value = "Get one car", nickname = "getOneCar", response = Car.class)
+    @ApiResponses({
+        @ApiResponse(code =  404, message ="Specific getCar not found"),
+        @ApiResponse(code =  400, message ="Specific getCar invalid input")
+    })
     @RequestMapping(value = "{id}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.GET)
     @ResponseStatus(HttpStatus.OK)
     public Car car(@RequestHeader(value = "MY_HEADER", required = false) String specialHeader,
-               @PathVariable("id") long id,
+               @ApiParam(name = "id", value = "Car id", required = true) @PathVariable("id") long id,
                @RequestParam Map<String, String> params,
                @RequestParam(value = "wheel", required = false) String[] wheelParams) {
                
@@ -92,14 +93,16 @@ public class CarController {
         return new Car(counter.incrementAndGet(), String.format(TEMPLATE, id));
     }
     
-//  Do I want to release with Swagger dependencies?
-//  @ApiOperation(value = "postCat", nickname = "createsNewCar", response = Car.class)
-//  @ApiResponses({
-//      @ApiResponse(code =  404, message ="Not found"),
-//      @ApiResponse(code =  400, message ="Invalid input")
-//  })
+       @ApiOperation(code =  201, value = "Create one new car", nickname = "createNewCar")
+    @ApiResponses({
+       @ApiResponse(code =  201, message ="Specific createCar with header",
+                       responseHeaders = { @ResponseHeader(name = HttpHeaders.LOCATION) }, response = Car.class),
+        @ApiResponse(code =  404, message ="Specific createCar not found"),
+        @ApiResponse(code =  400, message ="Specific createCar invalid input")
+    })
     @RequestMapping(consumes = MediaType.APPLICATION_JSON_UTF8_VALUE,
                produces = MediaType.APPLICATION_JSON_UTF8_VALUE, method = RequestMethod.POST)
+       @ResponseStatus(HttpStatus.CREATED)
     public ResponseEntity<Car> create(@RequestBody Car car) {
        long count = counter.incrementAndGet();
        HttpHeaders headers = new HttpHeaders();
diff --git a/REST/web-services-spring-rest-server/src/main/java/de/spring/webservices/rest/wadl/WADLController.java b/REST/web-services-spring-rest-server/src/main/java/de/spring/webservices/rest/wadl/WADLController.java
new file mode 100644 (file)
index 0000000..1125157
--- /dev/null
@@ -0,0 +1,236 @@
+package de.spring.webservices.rest.wadl;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Set;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.xml.namespace.QName;
+
+import org.apache.commons.lang.StringUtils;
+import org.jvnet.ws.wadl.Application;
+import org.jvnet.ws.wadl.Doc;
+import org.jvnet.ws.wadl.Param;
+import org.jvnet.ws.wadl.ParamStyle;
+import org.jvnet.ws.wadl.Representation;
+import org.jvnet.ws.wadl.Request;
+import org.jvnet.ws.wadl.Resource;
+import org.jvnet.ws.wadl.Resources;
+import org.jvnet.ws.wadl.Response;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
+import org.springframework.http.HttpStatus;
+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.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.ValueConstants;
+import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping;
+import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
+
+/**
+ * Taken from: http://javattitude.com/2014/05/26/wadl-generator-for-spring-rest/
+ * 
+ * With some modifications.
+ *
+ */
+@Controller
+@RequestMapping("/rest.wadl")
+public class WADLController {
+       private static final String NAMESPACE_URI = "http://www.w3.org/2001/XMLSchema" ;
+       private static final String WADL_TITLE = "Spring REST Service WADL";
+       
+    private final AbstractHandlerMethodMapping<RequestMappingInfo> handlerMapping;
+    private final ApplicationContext context;
+    
+    @Autowired
+       public WADLController(AbstractHandlerMethodMapping<RequestMappingInfo> handlerMapping, ApplicationContext context) {
+               this.handlerMapping = handlerMapping;
+               this.context = context;
+       }
+       
+    @RequestMapping(produces = { MediaType.APPLICATION_XML_VALUE }, method=RequestMethod.GET ) 
+    public @ResponseBody Application generateWadl(HttpServletRequest request) {
+        Application result = new Application();
+        
+        Doc doc = new Doc();
+        doc.setTitle(WADL_TITLE);
+        result.getDoc().add(doc);
+        
+        Resources wadlResources = new Resources();
+        wadlResources.setBase(getBaseUrl(request));
+                 
+        handlerMapping.getHandlerMethods().forEach( (mappingInfo, handlerMethod) -> {
+            Object object = handlerMethod.getBean();
+            Object bean = context.getBean(object.toString());
+            if(!bean.getClass().isAnnotationPresent(RestController.class)) {
+               return;
+            }
+            
+            mappingInfo.getMethodsCondition().getMethods().forEach(httpMethod -> {
+               Resource wadlResource = null; 
+                org.jvnet.ws.wadl.Method wadlMethod = new org.jvnet.ws.wadl.Method();
+     
+                Set<String> pattern =  mappingInfo.getPatternsCondition().getPatterns();
+                for (String uri : pattern) {
+                       wadlResource = createOrFind(uri, wadlResources); 
+                    wadlResource.setPath(uri);      
+                }
+                 
+                wadlMethod.setName(httpMethod.name());
+                Method javaMethod = handlerMethod.getMethod();
+                wadlMethod.setId(javaMethod.getName());
+                Doc wadlDocMethod = new Doc();
+                wadlDocMethod.setTitle(javaMethod.getDeclaringClass().getSimpleName() + "." + javaMethod.getName());
+                wadlMethod.getDoc().add(wadlDocMethod);
+                 
+                // Request
+                Request wadlRequest = new Request();
+                Annotation[][] annotations = javaMethod.getParameterAnnotations();
+                Class<?>[] paramTypes = javaMethod.getParameterTypes();
+                int i = 0;
+                for (Annotation[] annotation : annotations) {
+                       Class<?> paramType =paramTypes[i];
+                       i++;
+                    for (Annotation annotation2 : annotation) {
+                    
+                       Param wadlParam = doParam(annotation2, paramType);
+                       if (wadlParam != null) {
+                               wadlRequest.getParam().add(wadlParam);
+                       }
+                    }
+                }
+                if (!wadlRequest.getParam().isEmpty() ) {
+                    wadlMethod.setRequest(wadlRequest);
+                }
+                 
+                // Response
+                Set<MediaType> mediaTypes = mappingInfo.getProducesCondition().getProducibleMediaTypes();
+                if (!mediaTypes.isEmpty()) {
+                       ResponseStatus status = handlerMethod.getMethodAnnotation(ResponseStatus.class);
+                    Response wadlResponse = doResponse(mediaTypes, status);
+                    wadlMethod.getResponse().add(wadlResponse);
+                }
+                
+                
+                wadlResource.getMethodOrResource().add(wadlMethod);          
+            });
+             
+        });
+        result.getResources().add(wadlResources);
+         
+        return result;
+    }
+    
+    private Param doParam(Annotation annotation2, Class<?> paramType) {
+       Param wadlParam = null;
+       
+        if (annotation2 instanceof RequestParam ) {
+            RequestParam param = (RequestParam)annotation2;
+            
+            wadlParam = new Param();
+            QName nm = convertJavaToXMLType(paramType);
+            if (StringUtils.isNotEmpty(nm.getLocalPart())) {
+               wadlParam.setType(nm);
+            }
+            wadlParam.setName(param.value());
+            
+            
+            if (!ValueConstants.DEFAULT_NONE.equals(param.defaultValue())) {
+                String defaultValue = cleanDefault(param.defaultValue());
+                if (StringUtils.isNotEmpty(defaultValue) ) {
+                    wadlParam.setDefault(defaultValue);
+                }
+            }
+
+            wadlParam.setStyle(ParamStyle.QUERY);
+            wadlParam.setRequired(param.required());       
+        } else if (annotation2 instanceof PathVariable ) {
+            PathVariable param = (PathVariable)annotation2;
+            
+            wadlParam = new Param();                            
+            QName nm = convertJavaToXMLType(paramType);
+            if (StringUtils.isNotEmpty(nm.getLocalPart())) {
+               wadlParam.setType(nm);
+            }
+            wadlParam.setName(param.value());
+            
+            
+            wadlParam.setStyle(ParamStyle.TEMPLATE);
+            wadlParam.setRequired(true);
+        }
+        
+        return wadlParam;
+    }
+     
+    private Response doResponse(Set<MediaType> mediaTypes, ResponseStatus status) {
+       Response wadlResponse = new Response();
+        
+        mediaTypes.forEach(mediaType -> {
+            Representation wadlRepresentation = new Representation();
+            wadlRepresentation.setMediaType(mediaType.toString());
+            wadlResponse.getRepresentation().add(wadlRepresentation);
+        });
+        
+        wadlResponse.getStatus().add(getResposeValue(status));
+
+        return wadlResponse;
+    }
+    
+    private long getResposeValue(ResponseStatus status) {
+       if(status == null) {
+               return HttpStatus.OK.value();
+        } else {
+            HttpStatus httpcode = status.value();
+            return httpcode.value();
+        }
+    }
+    
+    private QName convertJavaToXMLType(Class<?> type) {
+       QName nm = new QName("");
+       String classname = type.toString();
+       classname = classname.toLowerCase();
+       
+               if (classname.indexOf("string") >= 0) {
+                       nm = new QName(NAMESPACE_URI, "string", "xs");
+               } else if (classname.indexOf("integer") >= 0) {
+                       nm = new QName(NAMESPACE_URI, "int", "xs");
+               } else if (classname.indexOf("long") >= 0) {
+                       nm = new QName(NAMESPACE_URI, "long", "xs");
+               }
+       
+       return nm;
+    }
+    
+    private Resource createOrFind(String uri, Resources wadResources) {
+         List<Resource> current = wadResources.getResource();
+         for(Resource resource:current) {
+                 if(resource.getPath().equalsIgnoreCase(uri)){
+                         return resource;
+                 }
+         }
+         Resource wadlResource = new Resource();
+         current.add(wadlResource);
+         return wadlResource;
+    }
+    
+    private String getBaseUrl(HttpServletRequest request) {
+        String requestUri = request.getRequestURI();
+        int index = requestUri.lastIndexOf('/');
+        requestUri = requestUri.substring(0, index);
+        
+        return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + requestUri;
+    }
+     
+    private String cleanDefault(String value) {
+        value = value.replaceAll("\t", "");
+        value = value.replaceAll("\n", "");
+        return value;
+    }
+}
index bed7947..54b8540 100644 (file)
        <context:annotation-config />
    
        <context:component-scan base-package="de.spring.webservices.rest"/>
-
-    <bean id="jsonObjectMapperFactory" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean" p:indentOutput="true" p:failOnEmptyBeans="false">
+       
+       <!--
+               Required beans for generating XML responses from Java objects using JAXB annotations
+               Jackson also works but it doesn't generate XML with namespaces... O.o
+               
+               This implementation will be slower than the one using Jackson :( but I am going to use it just for WADL generation :)
+       -->    
+    <bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
+        <property name="packagesToScan" value="org.jvnet.ws.wadl"/>
+    </bean>
+       <bean id="jaxbConverter" class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
+       <constructor-arg ref="jaxbMarshaller" />
+       </bean>
+    
+       <!-- Required beans for generating JSON responses from Java objects -->
+    <bean id="jsonObjectMapperFactory" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
+       p:indentOutput="true" p:failOnEmptyBeans="false">
         <property name="featuresToDisable">
             <array>
                 <util:constant static-field="com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES"/>
             </array>
         </property>
     </bean>
-
+    
     <util:list id="messageConverters">
         <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" p:objectMapper-ref="jsonObjectMapperFactory"/>
+               <ref bean="jaxbConverter" />
         <bean class="org.springframework.http.converter.StringHttpMessageConverter" />
     </util:list>
 
diff --git a/REST/web-services-spring-rest-server/src/main/resources/spring-configuration/spring-doc-config.xml b/REST/web-services-spring-rest-server/src/main/resources/spring-configuration/spring-doc-config.xml
new file mode 100644 (file)
index 0000000..773e14f
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:context="http://www.springframework.org/schema/context"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+        http://www.springframework.org/schema/beans/spring-beans.xsd
+        http://www.springframework.org/schema/context
+        http://www.springframework.org/schema/context/spring-context.xsd
+        http://www.springframework.org/schema/util
+        http://www.springframework.org/schema/util/spring-util.xsd">
+
+       <!--
+       
+       Local deployment URLs:
+       
+       Swagger:
+       http://localhost:8080/web-services-spring-rest-server/api-docs
+       
+       Swagger-UI:
+       http://localhost:8080/web-services-spring-rest-server/swagger-ui.html
+       
+       -->
+
+       <context:annotation-config />
+   
+       <context:component-scan base-package="de.spring.webservices.doc"/>
+       
+    <bean class="de.spring.webservices.doc.Swagger2Configuration"/>
+
+</beans>
index 26089bd..6c9c1d0 100644 (file)
@@ -34,7 +34,8 @@
 
     <servlet-mapping>
         <servlet-name>spring-rest</servlet-name>
-        <url-pattern>/spring-rest/*</url-pattern>
+        <!-- REQUIRED PATTERN BY swagger-ui. IT DOESN'T WORK WITH ANY OTHER o.O -->
+        <url-pattern>/*</url-pattern>
     </servlet-mapping>
 
 </web-app>
index bbad4e9..e8ce3dc 100644 (file)
                                <activeByDefault>true</activeByDefault>
                        </activation>
                </profile>
-               <profile>
-                       <id>documentation</id>
-                       <properties>
-                               <environment.profile>documentation</environment.profile>
-                       </properties>
-                       <activation>
-                               <activeByDefault>false</activeByDefault>
-                       </activation>
-                       <dependencies>
-                               <!-- API documentation -->
-                               <dependency>
-                                       <groupId>io.springfox</groupId>
-                                       <artifactId>springfox-swagger2</artifactId>
-                                       <version>2.3.1</version>
-                               </dependency>
-                               <dependency>
-                                       <groupId>io.springfox</groupId>
-                                       <artifactId>springfox-swagger-ui</artifactId>
-                                       <version>2.3.1</version>
-                               </dependency>
-                       </dependencies>
-                       <build>
-                               <resources>
-                                       <resource>
-                                               <directory>${basedir}/src/doc/main/resources/</directory>
-                                               <includes>
-                                                       <include>**/*.*</include>
-                                               </includes>
-                                       </resource>
-                               </resources>
-                               <plugins>
-                                       <plugin>
-                                               <groupId>org.codehaus.mojo</groupId>
-                                               <artifactId>build-helper-maven-plugin</artifactId>
-                                               <version>1.10</version>
-                                               <executions>
-                                                       <execution>
-                                                               <id>add-source</id>
-                                                               <phase>process-sources</phase>
-                                                               <goals>
-                                                                       <goal>add-source</goal>
-                                                               </goals>
-                                                               <configuration>
-                                                                       <sources>
-                                                                               <source>src/doc/main/java/</source>
-                                                                       </sources>
-                                                               </configuration>
-                                                       </execution>
-                                               </executions>
-                                       </plugin>
-                               </plugins>
-                       </build>
-               </profile>
        </profiles>
        <dependencies>
                <!-- 1/3 Required dependency for log4j 2 with slf4j: binding between log4j 
                                <version>2.6.4</version>
                        </dependency>
                        
+                       
                        <!-- Required by spring-context for using JSR-303. See LocalValidatorFactoryBean 
                                in rest-config.xml -->
                        <dependency>