我正在使用Grizzly来提供我的REST服务,该服务可能有多个"模块"。我希望能够为服务和静态内容使用相同的基本URL,以便我可以访问所有这些网址:
我尝试设置的代码如下所示:
private HttpServer createServer(String host, int port, ResourceConfig config)
{
HttpServer server = GrizzlyHttpServerFactory.createHttpServer(URI.create("http://" + host + ":" + port + "/"), config, false);
HttpHandler httpHandler = new CLStaticHttpHandler(HttpServer.class.getClassLoader(), "docs/");
server.getServerConfiguration().addHttpHandler(httpHandler, "/");
return server;
}
使用此代码,我只能看到html页面,并且我得到了一个"由路径标识的资源不存在"当我试图获取我的资源时的响应。 当我注释掉添加HttpHandler的代码时,我能够访问我的资源(但当然没有文档)。 访问我的资源和静态内容需要做什么?
答案 0 :(得分:3)
我最终写了一个服务来自己处理静态资源。我决定从文件系统提供我的文件,但这种方法也适用于从jar中提供它们 - 你只需要将文件作为资源而不是直接创建文件。
@Path("/")
public class StaticService
{
@GET
@Path("/{docPath:.*}.{ext}")
public Response getHtml(@PathParam("docPath") String docPath, @PathParam("ext") String ext, @HeaderParam("accept") String accept)
{
File file = new File(cleanDocPath(docPath) + "." + ext);
return Response.ok(file).build();
}
@GET
@Path("{docPath:.*}")
public Response getFolder(@PathParam("docPath") String docPath)
{
File file = null;
if ("".equals(docPath) || "/".equals(docPath))
{
file = new File("index.html");
}
else
{
file = new File(cleanDocPath(docPath) + "/index.html");
}
return Response.ok(file).build();
}
private String cleanDocPath(String docPath)
{
if (docPath.startsWith("/"))
{
return docPath.substring(1);
}
else
{
return docPath;
}
}
}
答案 1 :(得分:2)
您可以做的一件事是将Grizzly作为servlet容器运行。这样您就可以run Jersey as servlet filter和add a default servlet来处理静态内容。例如
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Formater
{
public class Startup
{
public async Task <object> Invoke (object input)
{
return ".NET";
}
}
}
您需要添加Jersey Grizzly servlet依赖
public class Main {
public static HttpServer createServer() {
WebappContext context = new WebappContext("GrizzlyContext", "");
createJerseyFilter(context);
createDefaultServlet(context);
HttpServer server = GrizzlyHttpServerFactory
.createHttpServer(URI.create("http://localhost:8080/"));
context.deploy(server);
return server;
}
private static void createJerseyFilter(WebappContext context) {
ResourceConfig rc = new ResourceConfig().packages("com.grizzly.test");
// This causes Jersey to forward 404s to default servlet
// which will catch all the static content requests.
rc.property(ServletProperties.FILTER_FORWARD_ON_404, true);
FilterRegistration reg = context.addFilter("JerseyApp", new ServletContainer(rc));
reg.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), "/*");
}
private static void createDefaultServlet(WebappContext context) {
ArraySet<File> baseDir = new ArraySet<>(File.class);
baseDir.add(new File("."));
ServletRegistration defaultServletReg
= context.addServlet("DefaultServlet", new DefaultServlet(baseDir) {});
defaultServletReg.addMapping("/*");
}
public static void main(String[] args) throws IOException {
HttpServer server = createServer();
System.in.read();
server.stop();
}
}
这种方法的唯一问题是默认servlet用于提供文件系统中的文件,而不是像目前尝试的那样从类路径提供文件。您可以在<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-servlet</artifactId>
<version>${jersey2.version}</version>
</dependency>
方法中看到我只是将基目录设置为当前工作目录。这就是你需要的所有文件。您可以将其更改为createDefaultServlet
,以便所有文件都位于"docs"
文件夹中,该文件夹位于当前工作目录中。
如果要从类路径中读取文件,可能需要实现自己的servlet。您可以查看source code for DefaultServlet
并尝试将其修改为从类路径提供。您还可以查看已经从类路径提供内容的Dropwizard's AssetServlet
。
或者你可以说忘了它,只是从文件系统提供服务: - )