【发布时间】:2017-11-19 19:26:18
【问题描述】:
我目前正在编写一个旨在过滤某些请求的 ORDS 插件。我不打算让过滤器正常工作,所以我决定follow Oracle's provided instructions 获取他们的插件 API。
我已经使用 Gradle 任务自动配置了大部分构建:
- 下载 WAR
- 将插件 JAR(之前也使用 Gradle 构建)添加到 ORDS
- 确保配置目录设置正确
实际上,这是我运行的自动等价物:
# Assuming the JAR is cURL'd in from somewhere...
java -jar ords.war plugin build/myPlugin.jar
java -jar ords.war configdir /home/makoto/ords-configuration
...我将它部署到我的本地 IntelliJ 实例。
这是我的 servlet 的样子。这是非常基本的。
import oracle.dbtools.plugin.api.di.annotations.Provides;
import oracle.dbtools.plugin.api.http.annotations.Dispatches;
import oracle.dbtools.plugin.api.http.annotations.PathTemplate;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Provides
@Dispatches(@PathTemplate(("/plugin/servlet/")))
public class TestServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().println("this worked?!");
}
}
文档让我相信我应该可以通过http://localhost:8080/ords/my_schema/plugin/servlet/ 访问它,但事实似乎并非如此。相反,我收到了 404:
DispatcherNotFoundException [statusCode=404, reasons=[]]
at oracle.dbtools.http.entrypoint.Dispatcher.choose(Dispatcher.java:87)
at oracle.dbtools.http.entrypoint.Dispatcher.dispatch(Dispatcher.java:98)
at oracle.dbtools.http.entrypoint.EntryPoint$FilteredServlet.service(EntryPoint.java:240)
at oracle.dbtools.http.filters.FilterChainImpl.doFilter(FilterChainImpl.java:73)
at oracle.dbtools.url.mapping.RequestMapperImpl.doFilter(RequestMapperImpl.java:125)
at oracle.dbtools.url.mapping.URLMappingBase.doFilter(URLMappingBase.java:103)
at oracle.dbtools.url.mapping.filter.URLMappingFilter.doFilter(URLMappingFilter.java:148)
at oracle.dbtools.http.filters.HttpFilter.doFilter(HttpFilter.java:47)
at oracle.dbtools.http.filters.FilterChainImpl.doFilter(FilterChainImpl.java:64)
at oracle.dbtools.http.cors.CORSResponseFilter.doFilter(CORSResponseFilter.java:83)
at oracle.dbtools.http.filters.HttpResponseFilter.doFilter(HttpResponseFilter.java:45)
at oracle.dbtools.http.filters.FilterChainImpl.doFilter(FilterChainImpl.java:64)
at oracle.dbtools.http.errors.ErrorPageFilter.doFilter(ErrorPageFilter.java:94)
at oracle.dbtools.http.filters.HttpFilter.doFilter(HttpFilter.java:47)
at oracle.dbtools.http.filters.FilterChainImpl.doFilter(FilterChainImpl.java:64)
at oracle.dbtools.http.auth.ForceAuthFilter.doFilter(ForceAuthFilter.java:44)
at oracle.dbtools.http.filters.HttpFilter.doFilter(HttpFilter.java:47)
at oracle.dbtools.http.filters.FilterChainImpl.doFilter(FilterChainImpl.java:64)
at oracle.dbtools.http.filters.Filters.filter(Filters.java:47)
at oracle.dbtools.http.entrypoint.EntryPoint.service(EntryPoint.java:82)
at oracle.dbtools.http.entrypoint.EntryPointServlet.service(EntryPointServlet.java:49)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at oracle.dbtools.rt.web.HttpEndpointBase.dispatchableServices(HttpEndpointBase.java:116)
at oracle.dbtools.rt.web.HttpEndpointBase.service(HttpEndpointBase.java:81)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
-- snip --
我错过了什么?我不清楚什么应该是 very 基本 servlet - 这实际上类似于“Hello World!”他们提供的示例 - 只是没有正确注册。
注意:
- 架构已为 ORDS 启用。
- 这个错误发生在我使用的两个容器中; Glassfish 和 Tomcat。
- 我没有使用 APEX,这似乎是该产品的常见插件。我打算将 ORDS 用作我的数据的 RESTful 提供程序。
-
@Dispatches路径中的尾部斜杠似乎没有效果;如果它被删除或存在,问题仍然存在。
我正在寻找关于这里可能发生的事情的权威答案或见解。在黑暗中猜测和射击对我没有好处,因为我自己一直在修补这个,而且很有可能我们的修补路径会重叠。
尽管我不愿意在任何问题中添加图片,BalusC suggested 我会检查 JAR 的内容以确保其中包含特定的提供程序文件。
从这个屏幕截图中,似乎有 两个...
...它们的内容是一样的...
com.foo.bar.baz.bing.servlet.TestServlet
oracle.dbtools.plugin.api.di.AnnotationsProvider
...但是当我去提取 JAR 并检查文件时,它只包含 AnnotationsProvider 行。
oracle.dbtools.plugin.api.di.AnnotationsProvider
但是等等!越来越奇怪了!
当我挂载 JAR 以提取 individual 文件时,我看到很多重复:
...这让我相信,不知何故,旧文件正在覆盖新文件。
【问题讨论】:
-
你为什么用双括号
@PathTemplate(("/plugin/servlet/"))定义你的PathTemplate? -
@JorgeCampos:语法正确; Java 会很好地忽略双括号。否则,我的 build 会遇到问题,而不是插件 API。
-
尝试删除第一个
/,即plugin/servlet/@Makoto -
@SagarV:那不会有什么不同。
-
您究竟是如何构建插件 JAR 文件的?我在演示插件 JAR 的源代码中看到它向 SPI 注册自身。 ORDS 示例文件夹中提供的 Ant 任务正是在创建 JAR 时完成的。您提到您为此使用了 Gradle 任务,所以我推测您是自己编写的。为了验证它是否正确地完成了它的工作,提取 Gradle 生成的插件 JAR 文件并检查是否有一个
/META-INF/oracle.dbtools.plugin.api.di.providers文件,其唯一内容是您的TestServlet的 FQN。如果不是,那它肯定不会被 WAR 中的 ORDS 核心发现。
标签: java oracle-ords