在 Python 中 URL 的这种操作,请问在 Java 中有吗? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Adia
V2EX    Java

在 Python 中 URL 的这种操作,请问在 Java 中有吗?

  •  
  •   Adia 2017-03-09 15:22:13 +08:00 4974 次点击
    这是一个创建于 3146 天前的主题,其中的信息可能已经有所发展或是发生改变。

    项目中要用 Java 去 get 到下载的 URL ,然后交给 linux 去 wget 。那么带着()之类的符号是不可以的。

    在 Python 中可以这么做

    from urllib import quote from urllib import quote #URL 是瞎给的 cli_url ="http://down1.chinaunix.net/distfiles/lrzsz-(0)1220.tar.gz" url_0 = cli_url.split('://')[0] url_1 = cli_url.split('://')[1] new_url = url_0+'://'+quote(url_1) cli_url = new_url #http://down1.chinaunix.net/distfiles/lrzsz-%280%2912.20.tar.gz print cli_url 

    但是在 Java 中似乎并不是这么好做的,

     public static void main(String[] args) throws URISyntaxException, MalformedURLException, UnsupportedEncodingException { String _url = "http://down1.chinaunix.net/distfiles/lrzsz-(0)12.20.tar.gz"; String url=URLEncoder.encode(_url, "UTF-8"); System.out.println(url); //http%3A%2F%2Fdown1.chinaunix.net%2Fdistfiles%2Flrzsz-%280%2912.20.tar.gz //先不管 http://还没有分割。蛋疼的是这里的 url 连 /都被编码了 } 

    想在 Java 中得到从http://down1.chinaunix.net/distfiles/lrzsz-(0)12.20.tar.gz变成http://down1.chinaunix.net/distfiles/lrzsz-%280%2912.20.tar.gz的效果。 url 是不规则的,用正则应该不行..求各位大神指教。

    25 条回复    2017-03-13 21:04:46 +08:00
    langmoe
        1
    langmoe  
       2017-03-09 15:26:03 +08:00
    加个单引号不就好了吗
    Adia
        2
    Adia  
    OP
       2017-03-09 15:27:47 +08:00
    @langmoe 什么?
    Duolingo
        3
    Duolingo  
       2017-03-09 15:29:12 +08:00 via iPhone
    java 的那个地址也能直接访问的吧……
    langmoe
        4
    langmoe  
       2017-03-09 15:29:59 +08:00
    @Adia 交给 linux 去 wget 的时候,网址加个单引号,不是就不用转义了吗
    Adia
        5
    Adia  
    OP
       2017-03-09 15:32:11 +08:00
    @langmoe 不..还有一系列很复杂的原因。之前试过
    Adia
        6
    Adia  
    OP
       2017-03-09 15:33:34 +08:00
    @codingadog 的确可以。但是 wget 的时候会恢复成()....所以还是 wget 不下来
    xiaoai
        7
    xiaoai  
       2017-03-09 15:41:47 +08:00
    java.net.URLEncoder.encode(url)
    python urllib.parse 中也有对应的方法_(:з∠)_
    Adia
        8
    Adia  
    OP
       2017-03-09 15:44:11 +08:00
    @xiaoai 不行..结果还是一样
    cute
        9
    cute  
       2017-03-09 18:15:31 +08:00
    wget "$(echo 'aHR0cDovL2Rvd24xLmNoaW5hdW5peC5uZXQvZGlzdGZpbGVzL2xyenN6LSgwKTEyLjIwLnRhci5nego='|base64 -D)"
    eimsteim
        10
    eimsteim  
       2017-03-09 21:24:46 +08:00
    这个需求好奇怪, Java 直接下载不就行了吗?为什么一定要交给 Linux 去 wget?
    SoloCompany
        11
    SoloCompany  
       2017-03-09 22:05:29 +08:00
    你这思路真是奇葩

    还是拿 python 来说是吧

    正常的程序
    subprocess.call(["curl", "http://baidu.com/&123"])

    2b 的程序
    os.system("curl " + "http://" + quote("baidu.com/&123"))
    Infernalzero
        12
    Infernalzero  
       2017-03-09 23:10:02 +08:00
    用 URL 和 URI 类,或者 apache 何 spring 都有封装好的类似 URIBuilder 这样的类
    至于“()”,其实不是必须转义的,所以 URI 的 toASCIIString 不会把()转成%28%29
    原因:( ) 不是保留字符
    Thus, only alphanumerics, the special characters "$-_.+!*'(),", and
    reserved characters used for their reserved purposes may be used
    unencoded within a URL.
    http://www.ietf.org/rfc/rfc1738.txt
    misaka19000
        13
    misaka19000  
       2017-03-10 01:13:11 +08:00
    先给 URL 进行编码,之后再加协议不就行了
    ren2881971
        14
    ren2881971  
       2017-03-10 09:30:12 +08:00
    需要这么复杂么。。 随便找个符号 替换下( ?
    Adia
        15
    Adia  
    OP
       2017-03-10 09:56:32 +08:00
    @eimsteim 一个分布式系统,核心是 Java , agent 那边是用 python 写的,然后调用下去所以变成 shell 了
    @SoloCompany 所以说解决问题最好的方法是否定问题是吗?
    Adia
        16
    Adia  
    OP
       2017-03-10 09:56:51 +08:00
    @ren2881971 哪个符号?
    SoloCompany
        17
    SoloCompany  
       2017-03-10 10:04:27 +08:00
    @Adia #15 shell argument 的问题为什么要用 url escape 方式来解决,典型的 AB 问题
    Adia
        18
    Adia  
    OP
       2017-03-10 10:58:19 +08:00
    @SoloCompany 那么你认为该如何解决?
    SoloCompany
        19
    SoloCompany  
       2017-03-10 11:01:42 +08:00   1
    @Adia 光从这个问题描述来看,即使要 escape 也是用 shell 的 escape 规则, php 的话有个 escapeshellarg 方法,没有的话自己写一个也很简单,前面已经有人告诉你用单引号了,那么剩下的就是参数里面带单引号的怎么解决,那就是把单引号替换成 '\''
    为什么这样替换可以你自己做一下实验就知道了
    SoloCompany
        20
    SoloCompany  
       2017-03-10 11:05:16 +08:00
    多扯一句

    php 就是个 2b 语言,所以宁愿发明个 escapeshellarg 也没有 exec($cmd, $arg …) ?
        21
    picasso250  
       2017-03-10 14:08:06 +08:00
    @SoloCompany 你以为 python 底层是怎么做的?
    所以不是 宁愿发明,而是 我就 wrap 一下 c 的接口。剩下的你自己解决。
    picasso250
    SoloCompany
        22
    SoloCompany  
       2017-03-10 14:28:35 +08:00
    @picasso250 #21 我不清楚 python 或者 c 是怎么实现的,但我清楚 java 是怎么实现的,请参考

    https://github.com/frohoff/jdk8u-jdk/blob/jdk8u60-b10/src/solaris/classes/java/lang/ProcessImpl.java#L83

    79~83 行的内容很清楚的显示 unixprocess 调用的 argBlock 的结构是怎么样的,每一个 arg 都是一个 \0 终结的 CString ,请问和 shell escape 有任何关系吗?
    cloudzhou
        23
    cloudzhou  
       2017-03-10 15:53:08 +08:00
    @Adia 如果怎么样,能使用 wget 或者 curl ,那就走标准的 http 协议啊,这样调用 shell ,一个是效率低下,不安全,并且平台相关。
    picasso250
        24
    picasso250  
       2017-03-13 20:35:12 +08:00
    @SoloCompany #22 真不幸,你至少应该找到 java 的 UNIXProcess 类,如果你有点 sense ,应该对着 forkAndExec 方法陷入沉思。
    显然,你应该想到 popen 之类的系统调用。这就是 PHP 的 wrap 。或许 PHP 不会把东西变得更好,但 PHP 也不会把东西变得更糟。而且 escapeshellarg 显然让事情比原来( c 语言时)变得更好了。

    如果你现在还不清楚这和 shell escape 有什么关系,我建议你……不要参与程序员话题的讨论了。
    SoloCompany
        25
    SoloCompany  
       2017-03-13 21:04:46 +08:00
    @picasso250 恭喜你找到了编程的真谛,已 block 不谢
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     904 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 19:12 PVG 03:12 LAX 12:12 JFK 15:12
    Do have faith in what youre 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