servlet(容器?规范?实现?)为啥会在 url 路径这个问题上设计的如此古怪? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
abcbuzhiming
V2EX    Java

servlet(容器?规范?实现?)为啥会在 url 路径这个问题上设计的如此古怪?

  •  1
     
  •   abcbuzhiming May 16, 2017 3928 views
    This topic created in 3267 days ago, the information mentioned may be changed or developed.
    我是最近才注意到这一点,其他有 http 实现的语言(框架),基本上,在 http 地址解析这个问题上,会倾向于把域名根路径“/”之后开始的部分视为一个整体,嗯,最多就是可能会把路径的最后部分如果有后缀名的话视为文件本身。比如 http://www.v2ex.com/aaa/bbb/ccc/ddd/123.txt。那么请求路径就是 /aaa/bbb/ccc/ddd/。这是一个整体,一般不会再拆分。但是在 servlet 的实现上,有两个东西,1 个叫 servletPath ( request.getServletPath()),一个叫 pathinfo ( request.getPathInfo())。而且很有意思的是,这两个东西的值是和 web.xml 配置文件中的 url-pattern 所采用的模式有关,我想了很长时间,没想明白这样的意义在哪里,为啥 servlet 在设计上没有把 /aaa/bbb/ccc/ddd/视为一个整体,而专门搞了 ServletPath,PathInfo。这应该是有某种作用的
    12 replies    2017-05-17 23:47:33 +08:00
    sagaxu
        1
    sagaxu  
       May 16, 2017 via Android
    因为一个 webserver 上要跑多个 webapps 啊,/app1/path,/app2/path,...
    abcbuzhiming
        2
    abcbuzhiming  
    OP
       May 16, 2017
    @sagaxu 然而你说的这个 app 其实指的是 ContextPath

    http://blog.csdn.net/cooljia/article/details/187882
    你可以看这篇文章,说的很详细,
    Context Path + servlet path + path info = request uri
    这里的关键就是为啥会分 servlet path 和 path info。把 Context Path 单独列出来是可以理解的,作为隔离应用的措施,但是后两者是干嘛的呢
    echo1937
        3
    echo1937  
       May 16, 2017
    这个问题我在学习 Servlet 时也发现了,当时有类似想法,但没有深究。
    cheneydog
        4
    cheneydog  
       May 16, 2017
    区分 api 请求和静态文件请求的一种方式。
    SoloCompany
        5
    SoloCompany  
       May 16, 2017
    有什么问题吗?
    REQUEST_URI = /a/b/c.php/d/e/f?x=1
    SCRIPT_NAME = /a/b/c.php
    PATH_INFO = /d/e
    _GET = [ “ x ” => 1 ]

    是什么让你会觉得这是 java 发明的?
    abcbuzhiming
        6
    abcbuzhiming  
    OP
       May 17, 2017
    @cheneydog 如何个区分法,说明白一点,我专门去研究了 tomcat 对静态文件的默认处理,发现它默认是通过“/”这个路径映射的 servlet 处理的,此时整个静态文件地址都是 servletPath,pathinfo 为空了。如果按 servletPath 存在就按 api 请求理解的话,好像没有 servletpath 不存在的时候
    abcbuzhiming
        7
    abcbuzhiming  
    OP
       May 17, 2017
    @SoloCompany 你这有点强词夺理了,你提的 php 中的这个 pathinfo 是 CGI 中的标准,它最初的含义指的是描述你所调用的这个 php 文件在服务器上的真实位置。然而后来大部分 php 框架利用这点,把它当成了地址映射。CGI 和 servlet 是一回事吗? servlet 里的这个 pathinfo 可不是出现在 jsp 后面的,你要能证明 CGI 中的这个 pathinfo 和 servlet 存在渊源或者有原理设计上的类似,请给出证据
    SoloCompany
        8
    SoloCompany  
       May 17, 2017
    @abcbuzhiming #7 我用得着去证明吗?是不是一回事你自己不会判断?就你这语气本来不想再回复了,算是知道什么叫做永远叫不醒一个自以为是的人。这是最后一条回复,你自己爱怎么理解就怎么理解吧

    <servlet>
    <servlet-name>c.jsp</servlet-name>
    <jsp-file>/a/b/c.jsp</jsp-file>
    </servlet>

    <servlet-mapping>
    <servlet-name>c.jsp</servlet-name>
    <url-pattern>/a/b/c.jsp/*</url-pattern>
    </servlet-mapping>

    自己去看一下早期 jsp 引擎是怎么实现的
    以及后来 jsp 的默认 mapping 怎么又被规范为了 *.jsp, 而规范不支持 *.jsp/* 这种类型的 mapping 只能通过手工加入
    abcbuzhiming
        9
    abcbuzhiming  
    OP
       May 17, 2017
    @SoloCompany 首先,我为我的语气道歉,你是对的,我找了一圈,pathinfo 就是对应的 CGI 变量 pathinfo。这一点在 orcale 的文档里有描述,虽然我还是没找到这样设计的理由。貌似有点吸引早期的 CGI 程序的开发者的意思。另外你说的最后一句话,早期 jsp 引擎实现和后来被规范成*.jsp,我没有找到相关的资料,请不吝赐教
    SoloCompany
        10
    SoloCompany  
       May 17, 2017
    @abcbuzhiming 早期 jsp 引擎的实现和 php 是比较类似的,就是类似 *.jsp/* 都会被 jsp 引擎处理,只要路径中包含 jsp (并且文件存在),就会被映射
    但是会存在歧义
    比如 /1.jsp/2.jsp/3 并且这两个路径下的 jsp 文件都存在
    那应该是映射为 servletPath=/1.jsp, pathInfo=/2.jsp/3 呢
    还是 servletPath=/1.jsp/2.jsp, path=/3
    完全依赖引擎的实现, Servlet 规范里面并没有这种定义的支持.

    Servlet 规范的 mapping 只支持一个 *,即要么按文件名后缀 map ( pathInfo 永远是 null) 要么按前缀来 map, 而且必须是 ‘/*’ (/* 代表的就是 pathInfo)

    默认的 jsp servlet mapping 的定义是写在 CATALINA_BASE/web.xml 里面, 就是 *.jsp, 通过这个 mapping 的请求也一定没有 path info

    默认配置还有一个 DefaultServlet, 用来服务静态文件

    至于 tomcat 的 jsp 引擎什么时候变更为和规范一致,我已经不记得了,只记得很早的时候是可以 (带 path) 的,后来就不可以了,也很可能是 tomcat 一直都默认不可以带 path 而是其它引擎( resin / jetty 之类的) 可以
    搜了一下也只能找到这个帖子 http://tomcat.10.x6.nabble.com/troubleshooting-getPathInfo-in-jsp-files-td2158648.html

    最后,无论是哪个语言的 HTTP 服务引擎, 所面对的概念都没有什么太大差别, 基本上都遵循 CGI 的定义,你看 javadoc 的时候没看到 request.getXXX 的说明很多都有说明是相当于 CGI 的哪个环境变量吗?
    abcbuzhiming
        11
    abcbuzhiming  
    OP
       May 17, 2017
    @SoloCompany 最后那段话的意思,是不是可以说现有的 Http 服务器的技术源头,或者说鼻祖都来源于 CGI ?都受到 CGI 的历史影响?那这个地球上有没有完全和 CGI 无关的 Http 服务器实现啊?
    SoloCompany
        12
    SoloCompany  
       May 17, 2017
    @abcbuzhiming 我不觉得这算是什么技术源头吧,因为 CGI 是最早的服务器编程方式,所有人都熟悉,专家也熟悉,制订标准的时候肯定也会参考,但同时也会做一些修改,比如 CGI 的 SCRIPT_NAME 环境变量在 Servlet 里面就改名为了 ServletPath, javadoc 里面都相关映射的说明
    About     Help     Advertise     Blog     API     FAQ     Solana     1028 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 38ms UTC 23:05 PVG 07:05 LAX 16:05 JFK 19:05
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86