Configuring swagger programmatically with jetty and jboss-resteasy

2,347 views
Skip to first unread message

Anusha Pachunuri

unread,
May 14, 2014, 10:29:19 AM5/14/14
to swagger-sw...@googlegroups.com

I have been trying to use swagger to document my jaxrs-resteasy service. I want to configure this programmatically in a embedded jetty server setting. Here are my Resource,Server and Application classes. I can access http://127.0.0.1:9091/rest/hello and verify that my rest service is working.. but when i try to access http://127.0.0.1:9091/rest/api-docs i cant get it working, but see a 404 not found instead. Can someone point me towards what i could be doing wrong while configuring Swagger.

Resource file

@Api(value = "/", description = "Index")
@Path("/")
public class Index {

    @GET
    @ApiOperation(
                value = "call Index",
                response = Response.class,
                responseContainer = "Object"
            )
    @Produces("text/html")
    public Response  index() throws URISyntaxException { 
        File f = new File(System.getProperty("user.dir")+"/index.html");
        String mt = new MimetypesFileTypeMap().getContentType(f);
        return Response.ok(f, mt).build();   
    }

    @GET
    @Path("/hello")
    @ApiOperation(
                value = "hello Get",
                response = Response.class,
                responseContainer = "Object"
            )
    public Response  helloGet() {     
        return Response.status(200).entity("HTTP GET method called").build();
    }

}

Server

public class JettyServer {

    public static void main(String[] args) throws IOException {

        Server server = new Server(9091);
        final HandlerList handlers = new HandlerList();

        ServletHolder h = new ServletHolder(new HttpServletDispatcher());
        h.setInitParameter("javax.ws.rs.Application", "com.all.MyServices");

//      h.setInitOrder(1);

        ServletContextHandler restContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
        restContextHandler.setContextPath("/rest");
        restContextHandler.addServlet(h, "/*");

        handlers.addHandler(restContextHandler);

        server.setHandler(handlers);

        try {
            server.start();
            server.join();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

Service file

public class MyServices extends Application  {

    private static Set<Index> services = new HashSet<>(); 

    public  MyServices() {     

        System.out.println( "Initializing Swagger BeanConfig" );
        BeanConfig beanConfig = new BeanConfig();
        beanConfig.setVersion("1.0");
        beanConfig.setResourcePackage( Index.class.getPackage().getName() );
        beanConfig.setBasePath( "http://localhost:9091/api" );
        beanConfig.setDescription( "My RESTful services" );
        beanConfig.setTitle( "My RESTful API" );
        beanConfig.setScan( true );

        services.add(new Index());
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    @Override
    public  Set getSingletons() {
        return services;
    }  

    @SuppressWarnings("rawtypes")
    public  static Set getServices() {  
        return services;
    } 
}

Ron

unread,
May 14, 2014, 11:04:29 AM5/14/14
to swagger-sw...@googlegroups.com
Hi,

I'm no expert in programmatically configuring jetty, but you need to make sure 2 things:
  1. ApiListingResourceJSON should be loaded as a servlet (this is serving your /api-docs)
  2. ResourceListingProvider and ApiDeclarationProvider need to be loaded as Providers for resteasy.

I imagine you have more experience with that than me, but that should give you the direction you should be looking at.



--
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.

Anusha Pachunuri

unread,
May 16, 2014, 4:53:14 PM5/16/14
to swagger-sw...@googlegroups.com
Thanks for pointing that out Ron.
Sorry i forgot to respond on the group earlier.

I read that placing the dist folder from Swagger-UI project under webapp should work. I am now trying to access http://localhost:9091/rest/api-docs
and i get  {"apiVersion":"1.0.2","swaggerVersion":"1.2","info":{"title":"My RESTful API","description":"My RESTful resources"}}

But dont see a UI. I also added 
restContextHandler.setResourceBase("C:/Users/Anusha/workspace/swagger-resteasy/src/main/webapp/dist") to see if it helps. But doesn't.

Can you help me with this?

Thanks
Anusha



Anusha Pachunuri

unread,
May 16, 2014, 5:25:51 PM5/16/14
to swagger-sw...@googlegroups.com
{"apiVersion":"1.0","swaggerVersion":"1.2","apis":[{"path":"/abc","description":"Index"}],"info":{"title":"My RESTful API","description":"My RESTful services"}}
is the actual response i am getting, but i was expecting this showed up with a UI.

Anusha

Ron

unread,
May 17, 2014, 3:03:16 AM5/17/14
to swagger-sw...@googlegroups.com
Do you get any errors with the UI? I need to understand better what you're experiencing, otherwise it would be difficult to offer assistance.

I would first try to run the UI separately from the application, but you'd need to enable CORS for that. Please follow the wiki page https://github.com/wordnik/swagger-core/wiki/CORS for that.


--

Anusha Pachunuri

unread,
May 19, 2014, 11:55:32 AM5/19/14
to swagger-sw...@googlegroups.com
I cloned the SwaggerUI project and copied the dist folder under webapp in my project. So when i try to access Swagger UI at this location
file:///C:/Users/Anusha/workspace/swagger-resteasy/src/main/webapp/dist/index.html, i can access the swagger petstore api, but get a CORS exception when i try to access my api http://localhost:9091/rest/api-docs/
Can't read from server. It may not have the appropriate access-control-origin settings.

I went through the link you mentioned, and i configured my Filter 

public class ApiOriginFilter implements javax.servlet.Filter {

public void init(FilterConfig filterConfig) throws ServletException {
}

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("filter");
HttpServletResponse res = (HttpServletResponse) response;
res.addHeader("Access-Control-Allow-Origin", "*");
res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
res.addHeader("Access-Control-Allow-Headers", "Content-Type");
chain.doFilter(request, response);
}

public void destroy() {
}
}

public class JettyServer {
 
public static void main(String[] args) throws IOException {

Server server = new Server(9091);
final HandlerList handlers = new HandlerList();
ServletHolder h = new ServletHolder(new HttpServletDispatcher());
h.setInitParameter("javax.ws.rs.Application", "com.all.MyServices");
h.setInitParameter("resteasy.resources", "com.wordnik.swagger.jaxrs.listing.ApiListingResourceJSON");
h.setInitParameter("resteasy.providers", "com.wordnik.swagger.jaxrs.listing.ApiDeclarationProvider,com.wordnik.swagger.jaxrs.listing.ResourceListingProvider");

ServletContextHandler restContextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
restContextHandler.setContextPath("/rest");
restContextHandler.addServlet(h, "/*");

FilterHolder f = new FilterHolder(ApiOriginFilter.class);
restContextHandler.addFilter(f, "/rest/*", EnumSet.noneOf(DispatcherType.class));
restContextHandler.setResourceBase("src/main/webapp");
handlers.addHandler(restContextHandler);
server.setHandler(handlers);

try {
server.start();
server.join();
} catch (Exception e) {
e.printStackTrace();
}
}
}

I doubt the filter is being applied. Do you have any suggestions?

Anusha

Ron

unread,
May 19, 2014, 12:23:34 PM5/19/14
to swagger-sw...@googlegroups.com
This is just a guess but you may want to pass in the DispatcherType of REQUEST instead in this line:
restContextHandler.addFilter(f, "/rest/*", EnumSet.noneOf(DispatcherType.class));

Possibly even ALL.



--

Anusha Pachunuri

unread,
May 19, 2014, 12:35:12 PM5/19/14
to swagger-sw...@googlegroups.com
Yes i was just gonna respond the exact same thing. I happened to try that and it worked(yayy)
Thanks for looking into it.

Now the next step is being able to access it inside the application.
Does it mean http://localhost:9091/rest/api-docs itself should come up with the ui?

Anusha

Ron

unread,
May 19, 2014, 12:37:16 PM5/19/14
to swagger-sw...@googlegroups.com
No. The /api-docs url will generate the swagger documentation.
You need to put that URL into swagger-ui and click explore (or change the swagger-ui configuration to point to it directly).

You can also pack swagger-ui with your application, but I'm not sure how to configure that using the embedded jetty.
You can look on how to serve static files with embedded jetty.


--

Anusha Pachunuri

unread,
May 19, 2014, 12:39:06 PM5/19/14
to swagger-sw...@googlegroups.com
Oh sorry. I actually misread your comment.
I used "/*" instead of "/rest". That made it work. But may be i need to change them as well. Will give it try.

Please also answer my question regarding what embedding into the application would mean? Being able to see the ui at rest/api-docs?

Anusha Pachunuri

unread,
May 19, 2014, 12:42:41 PM5/19/14
to swagger-sw...@googlegroups.com
Sure, will take a look then

Thanks

Ron

unread,
May 19, 2014, 12:43:37 PM5/19/14
to swagger-sw...@googlegroups.com
No. rest/api-docs will show you the swagger resource listing.
You can take a look at the following sample (which uses regular jetty) to see how swagger-ui can be integrated - https://github.com/wordnik/swagger-spec/tree/master/samples/helloworld/server


--

shiva thogiti

unread,
May 19, 2014, 11:12:43 PM5/19/14
to swagger-sw...@googlegroups.com
Hello,

     Am new to Documentation using Swagger. Am assigned with this task now. For each service we had 3 resources and they asked me to try to do documentation using one resource and for GET part. I created a controller and a route config . Can anyone explain me for further steps.

Thanks 

Ron

unread,
May 20, 2014, 8:21:14 AM5/20/14
to swagger-sw...@googlegroups.com
Hi Shiva,

You really should start your own thread unless you're using exactly the same configuration as stated above.
I'd need more information about your environment before I can offer further assistance (do you use any JAX-RS provider, servlets? springmvc? a dependency injection library? which web application and so on).




--

shiva thogiti

unread,
May 20, 2014, 1:33:10 PM5/20/14
to swagger-sw...@googlegroups.com
Hi Ron,
   
      Its a WebApi project and its a .net project. We r using restful services. 
Coming to my controller:
public class APIDocController : Controller
    {
        HttpConfiguration _config;
        IContentNegotiator _contentNegotiator;
        IReadOnlyDictionary<string, ResourceDefinition> _resources;
        IHttpControllerSelector _defaultSelector;

        public APIDocController(
            HttpConfiguration config,
            IContentNegotiator contentNegotiator,
            IEnumerable<ResourceDefinition> resources)
        {
            _config = config;
            _contentNegotiator = contentNegotiator;
            _resources = resources.ToDictionary(r => r.Name.ToUpperInvariant());
            _defaultSelector = new DefaultHttpControllerSelector(_config);
        }

        public ActionResult Index()
        {
            return Json(HealthModel.FromConfig(), JsonRequestBehavior.AllowGet);
        }

and I have a resource:
Contact resource

namespace LN.PM.Contact.Service.WebApi.Resources
{
    /// <summary>
    /// A resource for <see cref="IContact"/>.
    /// </summary>
    public class ContactResource : ResourceDefinition<IContact>
    {
        public ContactResource()
            : base("Contacts")
        {

        }

and my routeconfig looks like below:

 routes.MapRoute(
                name: "Doc",
                url: "apidoc",
                defaults: new
                {
                    controller = "apidoc",
                    action = "index"
                });

            routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "{controller}/{id}/{property}/{subid}",
                defaults: new
                {
                    id = RouteParameter.Optional,
                    property = RouteParameter.Optional,
                    subid = RouteParameter.Optional
                }
            );

and also i created SwaggerNet.cs :

[assembly: WebActivator.PreApplicationStartMethod(typeof(LN.PM.Contact.Service.WebApi.App_Start.SwaggerNet), "PreStart")]
[assembly: WebActivator.PostApplicationStartMethod(typeof(LN.PM.Contact.Service.WebApi.App_Start.SwaggerNet), "PostStart")]
namespace LN.PM.Contact.Service.WebApi.App_Start 
{
    public static class SwaggerNet 
    {
        public static void PreStart()
        {
            RouteTable.Routes.MapHttpRoute(
                name: "SwaggerApi",
                routeTemplate: "api/docs/{controller}",
                defaults: new { swagger = true }
            );
        }
        
        public static void PostStart() 
        {
}

so now by using this resource file i need call my mediatypes using Get method. If I can do that then we can go for documentation. 
For example result should look like this when i browse 
{
  apiVersion: "4.0.0.0",
  swaggerVersion: "2.0",
  basePath: "http://localhost:5555",
  resourcePath: null,
  apis: [
  {
    path: "/api/docs/Values",
    description: "No Documentation Found.",
    operations: [ ]
  },
  {
    path: "/api/docs/Home",
    description: "No Documentation Found.",
    operations: [ ]
  }
]

}


Ron

unread,
May 21, 2014, 7:34:41 AM5/21/14
to swagger-sw...@googlegroups.com
Shiva,

The .net Swagger libraries are all developed as 3rd party tools. I'm not really familiar with any of them (or .net in general), so I'm afraid I can't help you with the integration of it.
Once you pick a Swagger implementation from the list - https://github.com/wordnik/swagger-spec/#net - you can open an issue on that repository and ask for assistance there (unless they have their own mailing list, make sure to read the documentation on the relevant repository).

What I can assist with is general Swagger information about how things should look like eventually, should you need that.

BR,
Ron


Amanda Lee

unread,
Nov 26, 2014, 12:35:18 PM11/26/14
to swagger-sw...@googlegroups.com
Hi, Ron, I'm in a similar situation here. when I go to my "http://localhost:8085/swagger/api-docs", I can get the swagger documentation, but the api is not there.
{"apiVersion":"1.0","swaggerVersion":"1.2","info":{"title":"Swagger Title","description":"My Swagger page"}}

This is the service, 
@GET
    @Path("/hello")
    @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
    @ApiOperation(
            value = "get hello",
            response = Response.class,
            responseContainer = "Object"
        )
    @Wrapped(element = "network-services")
    public Response getHello() {
}

I added annotation to the model too.

@XmlRootElement(name = "network-service")
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
@ApiModel( value = "NetworkService", description = "Network Service Model" )
public class NetworkService {

    @XmlElement(name = "service-id")
    @JsonProperty("service-id")
    @ApiModelProperty( value = "Network service's id", required = true )
    private String serviceId;
}

For the Swagger UI file, I copied all the folders under dist folder to my src/main/webapp, and changed the url to be "http://localhost:8085/swagger/api-docs"

Is there something I'm missing here.

thank you.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggersocket+unsub...@googlegroups.com.

Ron

unread,
Nov 26, 2014, 1:03:52 PM11/26/14
to swagger-sw...@googlegroups.com
Can you share your web.xml?

To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

Amanda Lee

unread,
Nov 26, 2014, 1:09:48 PM11/26/14
to swagger-sw...@googlegroups.com
There is no web.xml. I'm using Maven, there is only pom.xml. and I add the dependency of Swagger to pom.xml. I'm using resteasy too. what do you want to know, so that I can copy the code here?

<dependency>
<groupId>com.wordnik</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.3.10</version>
</dependency>
<dependency>
<groupId>com.wordnik</groupId>
<artifactId>swagger-core_2.10</artifactId>
<version>1.3.10</version>
</dependency>
<dependency>
<groupId>com.wordnik</groupId>
<artifactId>swagger-jaxrs_2.10</artifactId>
<version>1.3.10</version>
</dependency>
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggersocket+unsubscri...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Ron

unread,
Nov 26, 2014, 1:12:54 PM11/26/14
to swagger-sw...@googlegroups.com
Then how to you initialize resteasy and swagger-core?

Also, with regards to the dependencies, you only need swagger-jaxrs_2.10. It will pull in the rest.

To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

Amanda Lee

unread,
Nov 26, 2014, 1:29:44 PM11/26/14
to swagger-sw...@googlegroups.com
Hi, Ron, I'm new to this project, I'm trying to understand it and add swagger to it. there is one method in the Restserver file

@Override
    public Set<Class<?>> getClasses() {
       classes.add(org.jboss.resteasy.plugins.providers.jackson.ResteasyJacksonProvider.class);
        classes.add(org.jboss.resteasy.plugins.providers.jaxb.JAXBXmlSeeAlsoProvider.class);
        classes.add(org.jboss.resteasy.plugins.providers.jaxb.JAXBXmlRootElementProvider.class);
        classes.add(org.jboss.resteasy.plugins.providers.jaxb.JAXBElementProvider.class);
        classes.add(org.jboss.resteasy.plugins.providers.jaxb.JAXBXmlTypeProvider.class);
        classes.add(org.jboss.resteasy.plugins.providers.jaxb.CollectionProvider.class);
        classes.add(org.jboss.resteasy.plugins.providers.jaxb.MapProvider.class);
        classes.add(org.jboss.resteasy.plugins.providers.jaxb.XmlJAXBContextFinder.class);
}

And here is from one file which implements BundleActivator, 

@Override
    public void start(BundleContext context) throws Exception {
Properties properties = System.getProperties();
        properties.put("javax.ws.rs.client.ClientBuilder", "org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder");
        System.setProperties(properties);

Does this help?

Thanks.

Ron

unread,
Nov 26, 2014, 1:34:41 PM11/26/14
to swagger-sw...@googlegroups.com
Not quite. I still don't see how RESTEasy know which resources to scan/load. Do you have an Application class (or rather one that extends it)?

To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

Amanda Lee

unread,
Nov 26, 2014, 2:01:12 PM11/26/14
to swagger-sw...@googlegroups.com
Application class is quite simple, only getClasses(), getSingletons(),getProperties() with no exact content.

here is the server and application:
public class RestServer extends Application {
public RestServer() {        
        BeanConfig beanConfig = new BeanConfig();
        beanConfig.setBasePath("http://localhost:8085/api");
        beanConfig.setVersion("1.0");
        beanConfig.setResourcePackage(SMRestProxyNoOpCreate.class.getPackage().toString());
        beanConfig.setDescription("My Swagger page");
        beanConfig.setTitle("Swagger Title");
        beanConfig.setScan(true);
        
        System.out.println("Resouce Package: "+beanConfig.getResourcePackage());
    }

public static void main(String[] args) {
int port = 8085;
Server server = new Server(port);
        ServletContextHandler servletContextHandler = new ServletContextHandler();
        servletContextHandler.setContextPath("/");

          EnumSet<DispatcherType> all =
                EnumSet.of(DispatcherType.ASYNC,
                        DispatcherType.ERROR, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.REQUEST);

        FilterHolder filterHolder = new FilterHolder(new CrossOriginFilter());
        String origin = "*";
        filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, origin);
        filterHolder.setInitParameter(CrossOriginFilter.ALLOW_CREDENTIALS_PARAM, "true");
        filterHolder.setInitParameter(CrossOriginFilter.ALLOWED_HEADERS_PARAM, "X-Requested-With,Content-Type,Accept,Origin,Authorization");
        servletContextHandler.addFilter(filterHolder, "/rest/*", all);
//Add Swagger configuration
        ServletHolder servletHolder = new ServletHolder(new HttpServletDispatcher());
        servletHolder.setInitParameter("javax.ws.rs.Application", RestServer.class.getCanonicalName());
        servletContextHandler.addServlet(servletHolder, "/*");
                    
   final ServletHolder swaggerHolder = new ServletHolder(new HttpServletDispatcher());
   final ServletContextHandler swagger = new ServletContextHandler(ServletContextHandler.SESSIONS);
   FilterHolder swaggerFilter = new FilterHolder(new CrossOriginFilter());
   swaggerHolder.setInitParameter("resteasy.resources", "com.wordnik.swagger.jaxrs.listing.ApiListingResourceJSON");
   swaggerHolder.setInitParameter("resteasy.providers", "com.wordnik.swagger.jaxrs.listing.ApiDeclarationProvider,com.wordnik.swagger.jaxrs.listing.ResourceListingProvider");
   swagger.setContextPath("/swagger");
   swagger.addServlet(swaggerHolder, "/*");
   swagger.setResourceBase("src/main/webapp");
   swagger.addFilter(swaggerFilter, "/swagger/*", EnumSet.noneOf(DispatcherType.class));

         final HandlerList handlers = new HandlerList();
       handlers.addHandler(servletContextHandler);
       handlers.addHandler(swagger);
       
       server.setHandler(handlers);
       server.start();
            server.join();
}

Amanda Lee

unread,
Nov 26, 2014, 2:05:47 PM11/26/14
to swagger-sw...@googlegroups.com
Hi, Ron, for the index.html, what value should put to url parameter?

Ron

unread,
Nov 26, 2014, 3:41:50 PM11/26/14
to swagger-sw...@googlegroups.com
Amanda,

The Application class contains Swagger's BeanConfig which is used to initialize Swagger, but based on the output you're getting, the Application class is not being used and so Swagger is not being initialized properly.
You need to take the BeanConfig initialization and put it in some code that will run when your application starts up.

As for the index.html, the url parameter should be the one pointing at your /api-docs.

To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

Amanda Lee

unread,
Nov 26, 2014, 3:58:01 PM11/26/14
to swagger-sw...@googlegroups.com
Thank you, Ron. When I put Resoucepackage to beanConfig, it seems that this function "SMRestProxyNoOpCreate.class.getPackage().toString()" return an extra package in the beginning, so the Swagger can't get the api. I replaced it with the package name.

        beanConfig.setResourcePackage(SMRestProxyNoOpCreate.class.getPackage().toString());  //this is the original one, I changed it to the package name

when I go to "http://localhost:8085/swagger/api-docs", I got the following, my api is there. If I want to check the swagger UI, I tried the "http://localhost:8085/swagger/", it didn't work, it throws exception.

{"apiVersion":"1.0","swaggerVersion":"1.2","apis":[{"path":"/","description":"Manage Swagger UI"}],"info":{"title":"Swagger Title","description":"My Swagger page"}}


This is my service

@Path("/")
@Api( value = "/", description = "Manage Swagger UI" )
public class SMRestProxyNoOpCreate {
}

The exception it throws:
ERROR [org.jboss.resteasy.core.ExceptionHandler] - failed to execute
javax.ws.rs.NotFoundException: Could not find resource for full path: http://localhost:8085/swagger/
at org.jboss.resteasy.core.registry.ClassNode.match(ClassNode.java:73) ~[resteasy-jaxrs-3.0.4.Final.jar:na]

Thanks.

Ron

unread,
Nov 26, 2014, 4:01:32 PM11/26/14
to swagger-sw...@googlegroups.com
Change the @Api annotation to this:

@Api( value = "/root", description = "Manage Swagger UI" )

This will not affect your API at all, just the way to documentation is hosted.

To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

Amanda Lee

unread,
Nov 26, 2014, 4:05:36 PM11/26/14
to swagger-sw...@googlegroups.com
Hi, Ron, I change it to this.


@Path("/")
@Api( value = "/root", description = "Manage Swagger UI" )
public class SMRestProxyNoOpCreate {


{"apiVersion":"1.0","swaggerVersion":"1.2","apis":[{"path":"/","description":"Rest Service"},{"path":"/root","description":"Manage Swagger UI"}],"info":{"title":"Swagger Title","description":"My Swagger page"}}

I have tried "http://localhost:8085/swagger/root", "http://localhost:8085/swagger/", "http://localhost:8085/root", but I still can't see the Swagger UI.

Ron

unread,
Nov 26, 2014, 4:08:22 PM11/26/14
to swagger-sw...@googlegroups.com
Those URLs are not related to the UI. Is the UI deployed as part of your application?

Based on the json you shared, there's another REST service with @Api(value = "/") - you should fix it as the documentation won't be read properly that way.

To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

Amanda Lee

unread,
Nov 26, 2014, 4:12:07 PM11/26/14
to swagger-sw...@googlegroups.com
I created one folder webapp under src/main, and copied the filed under dist folder of Swagger UI project to this webapp folder, then change the index.html(change to url to "http://localhost:8085/swagger/api-docs"), then I did a mvn clean install for my project, then start the server. I think it would include this UI to my application. is it?

Ron

unread,
Nov 26, 2014, 4:13:46 PM11/26/14
to swagger-sw...@googlegroups.com
Yes. It should be available at the root context of your application.

To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

Amanda Lee

unread,
Nov 26, 2014, 4:18:05 PM11/26/14
to swagger-sw...@googlegroups.com
Hi, Ron, you are right. I deleted another api with "Rest service" description, and did a build.

Here is the swagger documentation "http://localhost:8085/swagger/api-docs"

{"apiVersion":"1.0","swaggerVersion":"1.2","apis":[{"path":"/root","description":"Manage Swagger UI"}],"info":{"title":"Swagger Title","description":"My Swagger page"}}

but I still get exception for  "http://localhost:8085/swagger/", "http://localhost:8085/swagger/root", and 404 error for "http://localhost:8085/root", 

Ron

unread,
Nov 26, 2014, 4:20:53 PM11/26/14
to swagger-sw...@googlegroups.com
I don't know the context root of your application, so it's difficult to say.
Have you tried http://localhost:8085/ directly?

To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

Amanda Lee

unread,
Nov 26, 2014, 4:26:00 PM11/26/14
to swagger-sw...@googlegroups.com
yeah, it's 404 error, my context root is /swagger. This is my settings.

/Add Swagger configuration
  final ServletHolder swaggerHolder = new ServletHolder(new HttpServletDispatcher());
  final ServletContextHandler swaggerHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
  FilterHolder swaggerFilter = new FilterHolder(new CrossOriginFilter());
  swaggerHolder.setInitParameter("resteasy.resources", "com.wordnik.swagger.jaxrs.listing.ApiListingResourceJSON");
  swaggerHolder.setInitParameter("resteasy.providers", "com.wordnik.swagger.jaxrs.listing.ApiDeclarationProvider,com.wordnik.swagger.jaxrs.listing.ResourceListingProvider");
 
  swaggerHandler.setContextPath("/swagger");
  swaggerHandler.addServlet(swaggerHolder, "/*");

  swaggerHandler.setResourceBase("src/main/webapp");
  swaggerHandler.addFilter(swaggerFilter, "/*", all);

And for the ApiModel annotation, in the service file, it return a Response.class(which is an abstract class), while it's a list of "networkServices" object, I put the "ApiModel" annotation to networkservice class, is that right? I only put "@ApiModelProperty" to one of its parameter, should I put it to all of its parameters?

@XmlRootElement(name = "network-service")
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)
@ApiModel( value = "NetworkService", description = "Model" )
public class NetworkService {

    @XmlElement(name = "service-id")
    @JsonProperty("service-id")
    @ApiModelProperty( value = "Network service's id", required = true )
    private String serviceId;
}


On Wednesday, November 26, 2014 4:20:53 PM UTC-5, Ron R wrote:
I don't know the context root of your application, so it's difficult to say.
Have you tried http://localhost:8085/ directly?
On 26 November 2014 at 23:18, Amanda Lee <amanda...@gmail.com> wrote:
Hi, Ron, you are right. I deleted another api with "Rest service" description, and did a build.

Here is the swagger documentation "http://localhost:8085/swagger/api-docs"

{"apiVersion":"1.0","swaggerVersion":"1.2","apis":[{"path":"/root","description":"Manage Swagger UI"}],"info":{"title":"Swagger Title","description":"My Swagger page"}}

but I still get exception for  "http://localhost:8085/swagger/", "http://localhost:8085/swagger/root", and 404 error for "http://localhost:8085/root", 





Ron

unread,
Nov 26, 2014, 4:38:41 PM11/26/14
to swagger-sw...@googlegroups.com
You need to add @ApiModelProperty only if you want to have additional control on the property's documentation. Please take a look at the Annotations documentation for further details - https://github.com/swagger-api/swagger-core/wiki/Annotations.

As for the swagger-ui, unfortunately, I'm no expert when it comes to programmatically configuring jetty. You'd have to look at its docs to see how to host static files and why it may not work with your current configuration. I suspect the path you put there is wrong since that's the maven structure, not the actual structure of your application. Perhaps "/" would work better than "src/main/webapp", or maybe "/WEB-INF". I'm afraid that beyond that, I won't be able to help.

To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.
Message has been deleted

Amanda Lee

unread,
Dec 1, 2014, 10:32:51 AM12/1/14
to swagger-sw...@googlegroups.com
Thank you, Ron. Hope you have a great Thanksgiving. 
    I have tried localhost:8085/, but it didn't work, returns 404 error. "http://localhost:8085/swagger/root", return http error. "http://localhost:8085/swagger/root/network-services/hello", return http error. As I tried the Postman to access the Rest API, I can access "http://localhost:8085/rest/network-services/hello", and get right respond. I have tried the "http://localhost:8085/rest", "http://localhost:8085/rest/root", they didn't work, return http error too.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggersocket+unsubscri...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Amanda Lee

unread,
Dec 1, 2014, 10:47:36 AM12/1/14
to swagger-sw...@googlegroups.com
Hi, Ron, when I open the index.html under my webapp folder, it shows like this, it can show the Rest API I add annotation to. But this GET method returns 404 error. The Request URL is "http://localhost:8085/api/network-services/hello", when I browse this url, it returns 404 error.


Ron

unread,
Dec 2, 2014, 10:09:41 AM12/2/14
to swagger-sw...@googlegroups.com
It looks like your basePath is misconfigured.

You stated before that the API that works is http://localhost:8085/rest/network-services/hello which suggests the basePath should be set to http://localhost:8085/rest.

On 1 December 2014 at 17:47, Amanda Lee <amanda...@gmail.com> wrote:
Hi, Ron, when I open the index.html under my webapp folder, it shows like this, it can show the Rest API I add annotation to. But this GET method returns 404 error. The Request URL is "http://localhost:8085/api/network-services/hello", when I browse this url, it returns 404 error.


Amanda Lee

unread,
Dec 2, 2014, 12:06:54 PM12/2/14
to swagger-sw...@googlegroups.com
Hi, Ron, you are right. I set the BasePath to be "http://localhost:8085/rest", and the "http://localhost:8085/swagger/api-docs" returns the Swagger documentation "{"apiVersion":"1.0","swaggerVersion":"1.2","apis":[{"path":"/root","description":"Manage Swagger UI"}],"info":{"title":"Swagger Title","description":"My Swagger page"}}". And when I open the index.html directly on Chrome, I can see all the Rest API I have added annotations. But I can't find the url which can show the same page. I have tried "http://localhost:8085/swagger", "http://localhost:8085/rest", but both of them throws the exception "ERROR [org.jboss.resteasy.core.ExceptionHandler] - failed to execute
javax.ws.rs.NotFoundException: Could not find resource for full path: http://localhost:8085/rest/". Do you have any idea which is the url which can show the Swagger UI having all the REST API?


/Add Swagger configuration
  final ServletHolder swaggerHolder = new ServletHolder(new HttpServletDispatcher());
  final ServletContextHandler swaggerHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
  FilterHolder swaggerFilter = new FilterHolder(new CrossOriginFilter());
  swaggerHolder.setInitParameter("resteasy.resources", "com.wordnik.swagger.jaxrs.listing.ApiListingResourceJSON");
  swaggerHolder.setInitParameter("resteasy.providers", "com.wordnik.swagger.jaxrs.listing.ApiDeclarationProvider,com.wordnik.swagger.jaxrs.listing.ResourceListingProvider");
   
  swaggerHandler.setContextPath("/swagger");
  swaggerHandler.addServlet(swaggerHolder, "/*");
   
  swaggerHandler.setResourceBase("src/main/webapp");
  swaggerHandler.addFilter(swaggerFilter, "/*", all);

For the above servletholder, I set the resourceBase to be the path of the webapp folder which contains all the swagger UI files. In the index.html, I set the url to be "http://localhost:8085/swagger/api-docs".
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggersocket+unsub...@googlegroups.com.

Ron

unread,
Dec 2, 2014, 12:22:35 PM12/2/14
to swagger-sw...@googlegroups.com
This is related to statically serving files from embedded jetty, which is not something I'm familiar with (it is not related directly to Swagger).

You'd have to look at its documentation or just search for a possible solution. I imagine that applies to serving any static files.

I think I mentioned this before though - the path you set there is the one in the maven directory structure, but it is not the structure of the actual .war file that will be build from maven.

To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

Amanda Lee

unread,
Dec 2, 2014, 1:13:23 PM12/2/14
to swagger-sw...@googlegroups.com
ok, thank you. Ron. I guess I will check the documentation for embedded jetty. My Swagger is ok. Thank you very much for your patience. I appreciate it.
To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggersocket+unsubscri...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Ron

unread,
Dec 2, 2014, 1:18:51 PM12/2/14
to swagger-sw...@googlegroups.com
No problem. Just remember that your static files end up at the root of your WAR, so perhaps you can try pointing there ("/").

To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

Amanda Lee

unread,
Dec 2, 2014, 2:20:31 PM12/2/14
to swagger-sw...@googlegroups.com
Thanks, Ron. For the Swagger UI files, how could I know they are in the right place? Are they supposed to be at the target folder to make sure we have deployed it? 

Ron

unread,
Dec 2, 2014, 2:32:42 PM12/2/14
to swagger-sw...@googlegroups.com
They would be in the generated .war in the target folder. The build process may explode the war so you could check it easily, otherwise just open it and see.

To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

Amanda Lee

unread,
Dec 2, 2014, 2:38:38 PM12/2/14
to swagger-sw...@googlegroups.com
Well, in my target folder, there is jar file, not war file. I can see the webapp folder under my target folder, all of the files are there. I'm trying to print out the resourcebase for the swagger servletholder, I manually set it to be "swaggerHandler.setResourceBase("file:/C:/*/target/classes/webapp/");", but still the "http://localhost:8085/swagger/" still throws exception for not finding the resource.

Ron

unread,
Dec 2, 2014, 2:43:02 PM12/2/14
to swagger-sw...@googlegroups.com
Right, it's a jar because it uses embedded jetty and is not a deployable web app, forgot about it.
I don't know if the setResourceBase would work properly with a URI. When setting it, that's definitely not the path. Extract the jar and check its internal structure.

To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

Amanda Lee

unread,
Dec 2, 2014, 2:53:04 PM12/2/14
to swagger-sw...@googlegroups.com

Hi, Ron, I extracted the jar file, here is its structure. I checked the webapp folder, it contains all the Swagger UI files(under dist folder from github).

Ron

unread,
Dec 2, 2014, 2:55:45 PM12/2/14
to swagger-sw...@googlegroups.com
Then perhaps   swaggerHandler.setResourceBase("webapp");  or  swaggerHandler.setResourceBase("/webapp");  would work.

Amanda Lee

unread,
Dec 2, 2014, 3:04:29 PM12/2/14
to swagger-sw...@googlegroups.com
Hi, Ron, I tried "swaggerHandler.setResourceBase("webapp");", and print out the resourceBase, it shows: "file:/C:/workspace/projectName/webapp". For "swaggerHandler.setResourceBase("/webapp");", it print out the resourcebase "file:/C:/webapp". They both throw the "couldn't find resource for the full path....".  I'm testing with the url "http://localhost:8085/swagger/" for the page.

To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggersocket+unsub...@googlegroups.com.

Ron

unread,
Dec 2, 2014, 3:25:47 PM12/2/14
to swagger-sw...@googlegroups.com
I'd suggest googling further then. I'm pretty much out of ideas for now.

To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

Amanda Lee

unread,
Dec 2, 2014, 4:11:17 PM12/2/14
to swagger-sw...@googlegroups.com
Thanks, Ron. I have narrowed it down here. I will google it. I appreciate your help.



On Tuesday, December 2, 2014 3:25:47 PM UTC-5, Ron R wrote:
I'd suggest googling further then. I'm pretty much out of ideas for now.
On 2 December 2014 at 22:04, Amanda Lee <amanda...@gmail.com> wrote:
Hi, Ron, I tried "swaggerHandler.setResourceBase("webapp");", and print out the resourceBase, it shows: "file:/C:/workspace/projectName/webapp". For "swaggerHandler.setResourceBase("/webapp");", it print out the resourcebase "file:/C:/webapp". They both throw the "couldn't find resource for the full path....".  I'm testing with the url "http://localhost:8085/swagger/" for the page.


On Tuesday, December 2, 2014 2:55:45 PM UTC-5, Ron R wrote:
Then perhaps   swaggerHandler.setResourceBase("webapp");  or  swaggerHandler.setResourceBase("/webapp");  would work.
On 2 December 2014 at 21:53, Amanda Lee <amanda...@gmail.com> wrote:

Hi, Ron, I extracted the jar file, here is its structure. I checked the webapp folder, it contains all the Swagger UI files(under dist folder from github).



On Tuesday, December 2, 2014 2:43:02 PM UTC-5, Ron R wrote:
Right, it's a jar because it uses embedded jetty and is not a deployable web app, forgot about it.
I don't know if the setResourceBase would work properly with a URI. When setting it, that's definitely not the path. Extract the jar and check its internal structure.


--
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-swaggersocket+unsubscri...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Ron

unread,
Dec 2, 2014, 4:14:10 PM12/2/14
to swagger-sw...@googlegroups.com
If you find the solution, please share it for future reference.

To unsubscribe from this group and stop receiving emails from it, send an email to swagger-swaggers...@googlegroups.com.

Amanda Lee

unread,
Dec 2, 2014, 4:41:26 PM12/2/14
to swagger-sw...@googlegroups.com
Sure.
Reply all
Reply to author
Forward
0 new messages