如何确定正确的文件系统路径
我正在开发一个应用程序,该应用程序必须下载一些外部资源并通过 Ring 中的 public/static
目录访问它们。
但是..我在将资源保存到应用程序中的静态目录中时遇到问题,在开发时我使用ring-jetty-adapter
;测试与生产服务器正在运行 Tomcat。
我将 :web-content "public"
添加到我的 leiningen 项目中,并在项目根目录中添加了 public
目录,然后我就有了使用 http-agent 的下载功能和duck-streams:
(defn download
[file-name url]
(h/http-agent url
:handler (fn [agnt]
(let [fname file-name]
(with-open [w (d/writer fname)]
(d/copy (h/stream agnt) w))))))
如果我从 REPL 启动 Jetty 并使用 savepath: "public/my.file" ,下载的文件将正确放置在 public 目录中。 但是,当我使用 .war
文件将其部署到 Tomcat 时,它会在 Tomcat 根目录中查找 public
目录,而不是在应用程序上下文路径下。
我尝试添加一个中间件包装器来确定上下文路径,并从那里构建正确的保存路径,但我找不到任何方法来访问 HttpServlet 或确定应用程序是否在适配器或者它是否部署在特定上下文下。
这里的包装器:
(defn wrap-context-info [handler]
(fn [req]
(let [resp (handler req)]
(assoc resp :servlet (:servlet req) :req (:servlet-request req)))))
:servlet
和 :req
都是 nil
。
I am working on an application that has to download some external resources and make them accessible through a public/static
directory in Ring.
But.. I have a problem saving the resources into a static directory in my application, when developing I use the ring-jetty-adapter
; the test & production servers are running Tomcat.
I added :web-content "public"
to my leiningen project and added the public
directory in the root of the project, then I have a download function using http-agent and duck-streams:
(defn download
[file-name url]
(h/http-agent url
:handler (fn [agnt]
(let [fname file-name]
(with-open [w (d/writer fname)]
(d/copy (h/stream agnt) w))))))
If I am booting Jetty from the REPL and use savepath: "public/my.file"
, the downloaded file is placed correctly in the public
directory.
But when I deploy it using a .war
file to Tomcat, it looks for a public
directory in the Tomcat root directory, and not under the application context path.
I tried to add a middleware wrapper to determine the context path and from there build the correct save path, but I cannot find any way to access the HttpServlet
or a way to determine if the application is running in the adapter or if it is deployed under a specific context.
Here the wrapper:
(defn wrap-context-info [handler]
(fn [req]
(let [resp (handler req)]
(assoc resp :servlet (:servlet req) :req (:servlet-request req)))))
both :servlet
and :req
are nil
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
查看 ring-servlet 源代码,看来ring servlet 适配器将
HttpServlet
、HttpServletRequest
和HttpServletResponse
对象与ring 请求关联起来相应地映射到:servlet
、:servlet-request
和:servlet-response
键下。为了方便起见,它还会向请求映射添加一个
:servlet-context
条目,其值为(.getServletContext servlet)
。在处理程序中,您可能需要检查请求映射中是否存在这些键,然后从关联的对象中提取所需的更多信息。
Looking at the ring-servlet source, it appears that the ring servlet adapter associates the
HttpServlet
,HttpServletRequest
, andHttpServletResponse
objects with the ring request map under:servlet
,:servlet-request
, and:servlet-response
keys, accordingly.It also adds a
:servlet-context
entry to the request map with the value of(.getServletContext servlet)
for convenience.Inside your handler, you might want to check for the presence of these keys in the request map, and then pull further information that you need from the associated objects.