我尝试了很多,但我找不到如何为所有 Dropwizard 的 ViewBundle 资源选择根 URL。
我的 REST 端点由
/rest
提供服务,因为我已使用 environment.jersey().setUrlPattern('/rest/*'...)
设置它。
我的静态资源是从
/
提供的,因为我注册了一个 AssetBundle
,将其指向 /
作为其 URL 的根:bootstrap.addBundle(new AssetsBundle("/" + resourceBasePath + "/public/", "/"));
现在,如果我想获取视图,我必须将
/rest
附加到其 URL 中。例如,如果我设置@Path("/view/person/{id}")
,则只能在/rest/view/person/123
访问。
这不是我想要的。我希望可以通过
/view/person/123
访问它。
我猜从技术上来说这一定是可能的,因为
AssetBundle
可以安装到/
,应该有一种方法可以将ViewBundle
安装到/view
。
我该怎么做?
使用
Dropwizard's ViewBundle
有时可能会很棘手,例如为所有资源设置 root path
时。据我所知,由于 Dropwizard
本身并没有提供一个简单的解决方案,因此我们必须发挥创造力。所以我心里有两个想法。
为视图创建单独的服务:这是一种方法,您可以为您的视图提供完全独立的
Dropwizard
服务。通过这种方式,您可以仅为他们设置不同的 URL 模式。然而有一个问题,现在您将需要照顾两项服务,而不是只有一项,这可能会很累。
使用
Servlet Filter
或 Server-Side redirection
: 另一种方法是设置 Servlet Filter 或某种 Server-Side
重定向。所以基本上,这将获取来自“/view/”的请求并将它们传递给“/rest/view/”。因此,即使您的视图在技术上仍然由“/rest/view/”提供,用户也可以通过转到“/view/”来获取它们,如果我理解正确的话,这就是您想要的。
您可以使用两个不同的 servlet 来分离 Jersey 资源和 ViewBundle 资源。 Dropwizard 允许设置多个 servlet。
这里有一个代码示例来演示这一点。在此示例中,可以从 /api/ 访问其余 API,从 / 访问视图。
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
}
}
在此示例中,
MyResource
是服务 REST API 的资源,MyViewResource
是服务视图的资源。
请注意,添加这些 servlet 的顺序很重要。具有更通用模式的 servlet(在本例中为 /*)应最后添加。
请根据您的应用程序要求修改此内容。
REST 资源和 ViewBundle 共享相同的 Servlet,因此
/rest
前缀将应用于两者。您可以做的是从位于 /view/
的单独 servlet 上下文提供视图。
ServletContextHandler viewContext = new ServletContextHandler(ServletContextHandler.SESSIONS);
viewContext.setContextPath("/view");
ContextHandlerCollection contexts = new ContextHandlerCollection();
contexts.setHandlers(new Handler[] { jerseyContext, viewContext });
environment.getApplicationContext().getServer().setHandler(contexts);