how to use custom jackson object mappers for model conversion in swagger-core 1-5

1,757 views
Skip to first unread message

Santhosh gnanasurian

unread,
Jul 23, 2015, 5:44:20 AM7/23/15
to Swagger

I am using swagger 1.5 / Jackson 2.5.3 / jersey 2.x to build a rest API. I have array of elements as response. I have customized Jackson to render response output but the customizations aren’t picked up by swagger .For example ,


Model :
Array[ArrayItem]
ArrayItem {id,name}


Swagger Display :

{  "ArrayItem" : [{  Id : xxx,Name : yyy},{id:xxx2,Name:yyy2}] }


Jackson Display :

{ [{  Id : xxx,Name : yyy},{id:xxx2,Name:yyy2}] }


As you can see the wrapper has been removed in jackson by using customized oject mappers.vI looked at the model convertors [https://github.com/swagger-api/swagger-core/wiki/overriding-models] from swagger documentation but they are specific to 1.3 .The classes mentioned in the example aren’t not available in 1.5.


I looked into this thread

[http://grokbase.com/t/gg/swagger-swaggersocket/154r0xr750/questions-about-swagger-jersey-jaxrs] and there is following suggestion by Ron [reply 1] but i implemented it and it didnt work (or i didnt follow it properly)

In that version (1.5) we have a tight integration with Jackson for serialization of models. Anything that Jackson supports out of the box should be supported here as well (annotations, customizations and so on). Keep in mind that we have our own mappers with which you may need to register your customizations - one in the Json class and one in the Yaml.

Can someone please explain how this can be achieved.How can I make swagger use the same Object mappers as jackson.

I have initialized swagger in the following way as mentioned in jersey 1.5.x guide .The below content is actually in Jersey Config class but it follows same methodology

public JerseyConfig() {

        register(RequestContextFilter.class);
        register(JacksonFeature.class);


        packages("io.swagger.jaxrs.listing.ApiListingResource");
        packages("io.swagger.jaxrs.listing.SwaggerSerializers");
        packages("io.swagger.jaxrs.listing");
        packages("com.customSerializers");
        //register custom serializers with swagger object mapper 
        SimpleModule module = new SimpleModule();

        module.addSerializer(XXX.class, new XXXSerializer());
        module.addSerializer(YYYResponse.class,new YYYYResponse.YYYYYResponseSerializer());
        Json.mapper().registerModule(module);
        Json.mapper().setAnnotationIntrospector(new JacksonAnnotationIntrospector());
    } 

    }

web.xml

<servlet>
      <servlet-name>jersey</servlet-name>
      <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
      <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>
            io.swagger.jaxrs.listing,
            {your.application.packages}
        </param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>jersey</servlet-name>
        <url-pattern>/api/*</url-pattern>
    </servlet-mapping>

<servlet>
        <servlet-name>Jersey2Config</servlet-name>
        <servlet-class>io.swagger.jersey.config.JerseyJaxrsConfig</servlet-class>
        <init-param>
            <param-name>api.version</param-name>
            <param-value>1.0.0</param-value>
        </init-param>
        <init-param>
            <param-name>swagger.api.basepath</param-name>
            <param-value>http://localhost:8080/api</param-value>
        </init-param>
        <load-on-startup>2</load-on-startup>
</servlet>

Ron Ratovsky

unread,
Jul 23, 2015, 9:53:38 AM7/23/15
to swagger-sw...@googlegroups.com
Hi Santhosh,

The JerseyConfig you shared should do the trick, however, I don't see how you load it in your app...

--
You received this message because you are subscribed to the Google Groups "Swagger" group.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
-----------------------------------------
http://swagger.io
https://twitter.com/SwaggerApi
-----------------------------------------

Santhosh gnanasurian

unread,
Jul 28, 2015, 10:47:19 PM7/28/15
to Swagger, r...@swagger.io
Hi Ron,
I tried to load it in two ways

Method 1: 
Here the jersey config containing the swagger json/yaml object is loaded first and  then swagger configuration
<servlet>
<servlet-name>SmartPanelBrickServlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.schneider_electric.dces.smartpanelbrick.rest.config.JerseyConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>JerseyJaxrsConfig</servlet-name>
<servlet-class>io.swagger.jersey.config.JerseyJaxrsConfig</servlet-class>
<init-param>
<param-name>api.version</param-name>
<param-value>2.0.0</param-value>
</init-param>
<init-param>
<param-name>swagger.api.basepath</param-name>
<param-value>/smartpanel/v2</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>

Method 2:
I put the swagger intialization in seperate bootstrap servlet loaded in below order

<servlet>
<servlet-name>SmartPanelBrickServlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.schneider_electric.dces.smartpanelbrick.rest.config.JerseyConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>JerseyJaxrsConfig</servlet-name>
<servlet-class>io.swagger.jersey.config.JerseyJaxrsConfig</servlet-class>
<init-param>
<param-name>api.version</param-name>
<param-value>2.0.0</param-value>
</init-param>
<init-param>
<param-name>swagger.api.basepath</param-name>
<param-value>/smartpanel/v2</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
       <servlet>
<servlet-name>CustomMapperSwaggerinit</servlet-name>
<servlet-class>XXXX</servlet-class>
<init-param>
<param-name>XXXXX</param-name>
<param-value>YYYYY</param-value>
</init-param>
<load-on-startup>3</load-on-startup>
</servlet>

Both the methods didnt work.So i removed the wrapper response and modified the response container to be list.It works now as it should but i still have a lot of custom deserializers i would like to use.Is there any way to override?

Thanks,
Santhosh

Ron Ratovsky

unread,
Aug 3, 2015, 10:34:29 AM8/3/15
to Santhosh gnanasurian, Swagger
Santosh,

What is the current configuration of your application? Is it the same as in the original message or something else?
Reply all
Reply to author
Forward
0 new messages