3

I tried a lot, but I couldn't find how to choose the root URL for all Dropwizard's ViewBundle resources.

I have my REST endpoints served from /rest, because I have set it with environment.jersey().setUrlPattern('/rest/*'...).

I have my static assets served from /, because I registered an AssetBundle, pointing it to / as the root of its URLs: bootstrap.addBundle(new AssetsBundle("/" + resourceBasePath + "/public/", "/"));

Right now, if I want to get a view, I have to append /rest to its URL. For example, if I set @Path("/view/person/{id}"), it will only be accessible at /rest/view/person/123.

This is not what I want. I want it to be accessible at /view/person/123.

I am guessing technically it must be possible, since AssetBundle enables to mount to /, there should be a way to mount the ViewBundle to /view.

How can I do it?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Vic Seedoubleyew
  • 9,888
  • 6
  • 55
  • 76

2 Answers2

0

You can separate the Jersey resources and the ViewBundle resources by using two different servlets. Dropwizard allows for multi-servlet setup.

Here's a code sample to demonstrate this. In this sample, rest APIs will be accessible from /api/, and views from /.

public class MyApp extends Application<MyConfiguration> {
    @Override
    public void run(MyConfiguration configuration, Environment environment) throws Exception {
        
        // Setting up REST APIs
        ServletRegistration.Dynamic jerseyServlet = environment.servlets().addServlet("jerseyServlet", ServletContainer.class);
        jerseyServlet.addMapping("/api/*");  // APIs will be accessible from /api/*
        jerseyServlet.setServlet(new ServletContainer(environment.jersey().getResourceConfig()));
        
        // Register resources to jersey environment
        environment.jersey().register(new MyResource());
        //... register other resources

        // Setting up views
        ServletRegistration.Dynamic viewServlet = environment.servlets().addServlet("viewServlet", ServletContainer.class);
        viewServlet.addMapping("/*");  // Views will be accessible from /*
        viewServlet.setServlet(new ServletContainer(new ResourceConfig().register(MyViewResource.class)));
        //... register other view resources
    }
}

In this example, MyResource is the resource serving REST APIs, and MyViewResource is the resource serving views.

Please note, the order in which you add these servlets matters. The servlet that has the more generic pattern (/* in this case) should be added last.

Please modify this as per your application's requirements.

Shila Mosammami
  • 999
  • 6
  • 20
0

maybe it's better to customize the URL pattern for the bundle,so first of all make a custom ViewBundle class that extends ViewBundle and then override the run method and set a custom URL pattern for the ViewBundle!

something like this

public class CustomViewBundle<T extends Configuration> extends ViewBundle<T> {

    @Override
    public void run(T configuration, Environment environment) {
        //set a custom URL pattern for the ViewBundle here!
        environment.jersey().setUrlPattern("/view/*");

        //to runnig the ViewBundle
        super.run(configuration, environment);
    }
}

now,in your application's run method,you can easily use the custom ViewBundle instead of the default one like this:

@Override
public void run(YourConfiguration configuration, Environment environment) {
    /* don't forget to replace YourConfiguration with 
       your configuration class name! */
    bootstrap.addBundle(new CustomViewBundle<>());
    // your code
}

ok as you see,your views now will be accessible at URLs like /view/person/123 instead of /rest/view/person/123 and don't forget to update any @Path annotations in your resource classes accordingly!

Freeman
  • 9,464
  • 7
  • 35
  • 58