Monday, January 16, 2017

Springfox swagger UI upgrade

Few days ago I did an upgrade of springfox/swagger2 2.5.0 -> 2.6.1.
And it appeared, that authorisation API_KEY input field doesn't present on UI any more.
After a research it appeared, that springfox-swagger2 2.6.1 now completely support all original Swagger UI authentication types [basic, oauth2, api token]
All you need to do is to configure SecurityScheme for your Swagger Configuration like this:

 SecurityScheme securityScheme = new ApiKey(TOKEN_HEADER, "", TOKEN_TRANSPORT_HEADER);  
     return new Docket(DocumentationType.SWAGGER_2)  
         .select()  
         .apis(RequestHandlerSelectors.any())  
         .paths(PathSelectors.any())  
         .build()  
         .apiInfo(getApiInfo())  
         .securitySchemes(Lists.newArrayList(securityScheme));  

Wednesday, May 30, 2012

Apache CXF. Disable WADL schema generation.

Some time ago the project that I am working on was examined for vulnerabilities. One of the security item was public point for WADL schema. Basically using simple URL like this:
http://localhost:8080/myservice/client?_wadl
user can see the entire WADL of webservices. We decided to remove it. First of all we can disable it only since Apache CXF version 2.4.2:
  1. The first step is to create WadlGenerator object with required configuration.
  2. <bean id="wadlGenerator" class="org.apache.cxf.jaxrs.model.wadl.WadlGenerator">
            <property name="ignoreRequests" value="true"/>
        </bean>
    
  3. Set wadlGenerator bean to the service providers
  4. <jaxrs:server id="clientService" address="/clientservice">
            <jaxrs:serviceBeans>
                <ref bean="clientBean" />
            </jaxrs:serviceBeans>
            <jaxrs:extensionMappings>
                <entry key="json" value="application/json"/>
                <entry key="xml" value="application/xml"/>
            </jaxrs:extensionMappings>
            <jaxrs:providers>
                <ref bean="jaxbProvider"/>
                <ref bean="wadlGenerator" />
            </jaxrs:providers>
        </jaxrs:server>
    

Tuesday, May 29, 2012

Apache CXF + Jackson

Some days ago I had a task for converting java HashMap to JSON responce, using Apache CXF framework. It was surprise for me that standart CXF JSON provider(Jettison) doesn't work with maps. As I didnt want to write my custom XMLAdapter, I desided to use Jackson, as it works with maps perfectly.

There are next steps to configure:
  1. Add Jackson maven dependency
  2. <dependency>
        <groupId>org.codehaus.jackson</groupId>
        <artifactId>jackson-jaxrs</artifactId>
        <version>1.9.7</version>
    </dependency> 
    

  3. Include Jackson provider bean into your service providers:
  4. <bean id="jsonProvider" class="org.codehaus.jackson.jaxrs.JacksonJsonProvider"/>
    <jaxrs:server id="clientService" address="/clientservice">
            <jaxrs:serviceBeans>
                <ref bean="clientBean" />
            </jaxrs:serviceBeans>
            <jaxrs:extensionMappings>
                <entry key="json" value="application/json"/>
                <entry key="xml" value="application/xml"/>
            </jaxrs:extensionMappings> 
            <jaxrs:providers>
                <ref bean="jaxbProvider"/>
            </jaxrs:providers>
     </jaxrs:server>
    
Now all JSON responces from "clientService" are generated by Jackson.
Also next Jackson configuration could be very usefull:
  • Enable wrapping entities with root element.
  • Exclude null values from JSON responce. 
  • This features are disabled by default. To enable it I created my custom ObjectMapper class, that extends from "org.codehaus.jackson.map.ObjectMapper"
    import org.codehaus.jackson.map.ObjectMapper;
    import org.codehaus.jackson.map.SerializationConfig;
    import org.codehaus.jackson.map.annotate.JsonSerialize;
    
    public class CustomObjectMapper extends ObjectMapper{
    
        public CustomObjectMapper() {
        super();
        super.configure(SerializationConfig.Feature.WRAP_ROOT_VALUE, true);
        super.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
        }
    
    }
    

    Then added CustomObjectMapper to "jsonProvider" constructor:
    <bean id="jacksonMapper" class="com.xproject.server.util.CustomObjectMapper" />
    <bean id="jaxbProvider" class="org.codehaus.jackson.jaxrs.JacksonJsonProvider">
            <constructor-arg ref="jacksonMapper" />
     </bean>