Java Servlet - 将 servlet 映射到除字符串之外的每个 URL

Posted

技术标签:

【中文标题】Java Servlet - 将 servlet 映射到除字符串之外的每个 URL【英文标题】:Java Servlet - Mapping a servlet to every URL but a string 【发布时间】:2015-02-10 11:31:54 【问题描述】:

我有一个配置为处理所有 URL (*) 的 servlet:

<servlet>
    <servlet-name>MyServ</servlet-name>
    <servlet-class>MyServlet</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>MyServ</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

对于以/static/ 开头的 URL,我需要它,它应该从静态 WEB-INF 为它们提供服务。也就是说,MyServ 应该提供所有服务 /static

我该怎么做?


更新:澄清一下,我想要的是:

/*/ - 转到 MyServ/static/dir/file.css - Jetty 从 /dir/ 提供静态 file.css。

我不确定要做什么 web.xml,或者把静态文件放在哪里。

我尝试添加这个:

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/static/*</url-pattern>
</servlet-mapping>

但是,当我访问/static/ URL 时,我会得到:

HTTP ERROR 404

Problem accessing /static/dir/file.css. Reason: 
    Not Found

Powered by Jetty://

我不确定我的 web.xml 是否错误,或者我只是将文件放在错误的位置(我在 src/main/webappsrc/main/webapp/lib/META-INF/resources/ 下尝试过)


码头

我正在使用 Jetty。我想避免任何其他层,例如 nginx、Apache 等。

要赢得赏金,请确保您的回答适用于 Jetty。

【问题讨论】:

***.com/questions/3125296/… 【参考方案1】:

您最好的选择可能是在 * 规则之前有一个静态规则。

URL 路径映射规则:

按以下顺序使用。使用第一个成功的匹配,不再尝试。

    容器将尝试查找请求路径与 servlet 路径的完全匹配。成功匹配选择 servlet。 容器将递归地尝试匹配最长的路径前缀。这是通过使用“/”字符作为路径分隔符一次将路径树下移一个目录来完成的。最长的匹配决定了选择的 servlet。 如果 URL 路径中的最后一段包含扩展(例如 .jsp),则 servlet 容器将尝试匹配处理扩展请求的 servlet。扩展名定义为最后一个“.”字符之后的最后一段。 如果前三个规则都没有导致 servlet 匹配,则容器将尝试提供适合所请求资源的内容。如果为应用程序定义了“默认”servlet,则会使用它。

所以它将匹配/static/ 的规则,并停在那里。

【讨论】:

谢谢 - 但是什么类型的规则会告诉它使用本地资源?它不是 servlet,只是静态文件。【参考方案2】:

您的问题可以通过使用Nginx 来解决。 Nginx 提供静态内容 html 文件、图像(.jpg、.png、.gif)、样式表(.css)和 javascript(.js)。这些文件不需要由 Web 服务器处理。 Nginx 将完成这项工作。

server 
  listen          80;
  server_name     YOUR_DOMAIN;
  root            /PATH/TO/YOUR/WEB/APPLICATION;
  location / 
    index index.jsp;
  
  location ~ \.jsp$ 
    proxy_pass              http://localhost:8080;
  
  location ^~/servlets/* 
    proxy_pass              http://localhost:8080;
  

【讨论】:

【参考方案3】:

要提供静态内容,您甚至不需要 servlet。您可以将静态内容放在可通过服务器直接访问的文件夹中。

例如,如果您的应用程序名称是TestApp,那么您可以将您的内容放在TestApp/static/dir 目录中。基于此,您的目录结构将是:

TestApp
   |
   |_____ WEB-INF
   |
   |_____ static
             |
             |____ dir

通过上述目录结构,所有静态内容,例如Sample.css 可通过以下 URL 访问:

/TestApp/static/dir/Sample.css

请查看此问题以获取更多信息How to serve static content from tomcat

请注意,通过这样做,您的静态目录将不受任何限制地向所有人开放,这意味着任何人都可以在没有任何身份验证的情况下访问您的静态内容。但作为你的静态内容,除非你有任何理由,否则我猜它很好。

【讨论】:

【参考方案4】:

首先,位于“WEB-INF”目录中的文件不能直接通过网络访问。

另外,我注意到您的条目“src/main/webapp/lib/META-INF/resources/”不包含提取的 WAR 目录,即 Web 应用程序文件夹。

示例: src/main/webapp/[WAR 文件夹]/lib/META-INF/resources/

我假设您使用的是 Tomcat。因此,在创建 WAR 文件后,将其放入“webapp”目录,然后启动 Tomcat。 WAR 文件应提取到与 WAR 文件同名的 Web 应用程序文件夹中。现在,您应该可以通过浏览器访问“WEB-INF”之外的任何文件。

示例: localhost:8080/[web app folder name]/[some file]

希望这会有所帮助,

【讨论】:

【参考方案5】:

只需将您的静态内容放入 webapp 目录即可。 那部分可以直接访问。使用 localhost:port/yourAppName/ResourceName

【讨论】:

【参考方案6】:

根据我的经验(正如 Srinivasu Talluri 已经建议的那样),反向代理是您问题的答案。

您可以使用 Nginx See detail configuration 或将 Apache 配置为反向代理。

通过 Nginx 提供静态内容的详细配置可以找到 here

当静态内容将由 Web 服务器本身处理时,您的 servlet 配置可以按原样使用。因此,您的 servlet 将只提供动态资源。

希望对你有帮助。

【讨论】:

以上是关于Java Servlet - 将 servlet 映射到除字符串之外的每个 URL的主要内容,如果未能解决你的问题,请参考以下文章

发布一个java Servlet (静态发布)

Java Socket 编程推送 servlet - 将 Servlet 部署到服务器后未初始化

Java学习servlet 的引入

java web-----servlet

java servlet

我将如何匹配此 Java servlet 中数据库中的用户名和密码。 JDBC 和 Servlet