servlet 映射_棘手的servlet映射!

servlet 映射

上周,我通过对学生的作业进行评分,讲述了一个可以使用过滤器创意用途 。 关于,还有一个经常出现的问题,值得关注的博客文章:servlet映射。 尽管从表面上看servlet映射似乎很容易,但有时它们可​​能是造成巨大麻烦的原因。

问题

在上述作业中,学生必须创建一个模拟的电子商务商店应用程序。 主页显示标题,简介短语以及醒目的图像。 问题是未显示图像。

此时,学生可以发挥创造力-毕竟这是一项作业。 他们要么放弃显示图像的要求,要么使用在线托管的图像-热链接。 后者效果惊人!

同样,找不到JavaScript和CSS文件。 为了使它们起作用,它们会内联。

让我们看看是什么原因。

分析

JavaEE Web应用程序提供了两种路径映射方法:

  1. servlet映射一个,可以在web.xml Web部署描述符中配置,也可以通过类上的@WebServlet注释配置。
    @WebServlet("/foo")
    publicclassFooServletextendsHttpServlet{...}

    现在可以在/foo路径下访问该servlet。

  2. 资源一:可以直接访问WEB-INF文件夹中没有的任何内容。
    sample.war
    |__ image
    |   |__ a.jpg
    |   |__ b.jpg
    |__ script
    |   |__ a.js
    |__ style
    |   |__ a.css
    |___ WEB-INF
        |__ web.xml

    根据上述结构,将公开以下路径:

    • /image/a.jpg
    • /image/a.jpg
    • /script/a.js
    • /style/a.css

最终用户不知道路径是由servlet还是由静态资源提供的。 Servlet可以映射到/foo.html 。 同样,可以实现一个提供动态图像的servlet并将其映射到*.jpg

现在很重要。 当请求路径时,服务器首先寻找匹配的servlet映射。 如果未找到,则尝试按路径查找相关的静态资源。 因此,如果两个servlet映射都匹配同一路径,则它会覆盖静态资源

在以上问题中,罪魁祸首确实是一个servlet,更确切地说是一个映射到/映射的servlet。

@WebServlet("/")
publicclassHomePageServletextendsHttpServlet{...}

通过在调试模式下运行JVM,并在所述servlet的service()方法内设置一个断点,可以很容易地证明这一点。 很明显,它遮盖了每个静态资源。

这个怎么运作

Servlet规范的一部分专门介绍映射和路径匹配。 摘录如下:

  1. 容器将尝试查找请求路径与Servlet路径的精确匹配。 成功匹配将选择servlet。
  2. 容器将递归地尝试匹配最长的路径前缀。 这是通过使用/字符作为路径分隔符,一次将路径树下移到一个目录来完成的。 最长的匹配决定了所选的servlet。
  3. 如果URL路径中的最后一段包含扩展名( 例如 .jsp ),则Servlet容器将尝试匹配处理该扩展名请求的servlet。 扩展定义为last段之后的last段的一部分. 字符。
  4. 如果前三个规则均未导致servlet匹配,则容器将尝试提供适合于所请求资源的内容。 如果为应用程序定义了“默认” servlet,则将使用它。 许多容器提供了一个隐式默认servlet来提供内容。
— Java Servlet规范

请注意提到默认服务 。 该默认servlet是映射到/默认servlet,它的确会匹配其他servlet未匹配的每个路径,因为最长的路径匹配规则。

该解决方案还可以在规范中找到:

空字符串(“”)是一种特殊的URL模式,它精确地映射到应用程序的上下文根, ,形式为http://host:port/<context-root>/请求。 在这种情况下,路径信息为/ ,而servlet路径和上下文路径为空字符串(“”)。

— Java Servlet规范

解决方法是仅删除映射到主页的servlet中的/

@WebServlet("")
publicclassHomePageServletextendsHttpServlet{...}

结论

细节决定成败。 一个额外的角色可能破坏一个人的应用程序,并使开发人员陷入疯狂的不良解决方法中。 大多数时候,阅读文档(或规格)可以找到正确的解决方案。

更进一步:

翻译自: https://blog.frankel.ch/tricky-servlet-mappings/

servlet 映射

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值