java.io.IOException: Server returned HTTP response code: 400 for URL 问题定位与解决

一、前言

        今天在做数据迁移时,项目旧数据迁移至新数据仓库中,有网络资源下载 重传的需求,于是在整理的过程中,出现了上述问题, java.io.IOException: Server returned HTTP response code: 400 for URL。

        当时使用的是  org.apache.commons.io.FileUtils 封装的文件下载包,一个很简单的调用,如下:

       try {
            
            String url = "https://XXX.com/audio/15359421531172 He was a boy! ..mp3";
            //String url2 = "https://XXX.com/audio/15359421531172 He was a boy.mp3";
            String dir = "/tmp/test/";
            String fileName = "12.mp3";
            URL resourceUrl = new URL(url);
            File dirFile = new File(dir);
            if (!dirFile.exists()) {
                dirFile.mkdirs();
            }
            FileUtils.copyURLToFile(resourceUrl, new File(dir + fileName));
        } catch (Exception e) {
            e.printStackTrace();
        }

         其他的url在下载时候并没有出现上述问题,但在上述的url在下载的时候,爆出了错误400。可以明显的看出,这个url有些诡异,出现了各种符号,包括! . 以及空格,但是如果我们将这个url输入到浏览器访问的时候,却是通的。

二、问题定位

         根据差异性的规则,上面的url2并没有出现错误,因此问题肯定出在了这些诡异的符号上了,感叹号,空格以及 . ,java也有一个类库正好是做url编码规范的,java.net.URLEncoder,将 url输入即可进行格式化为正常的访问规则,如下:

            String url = "www.231124214.com/3214 !..mp3";
            url = URLEncoder.encode(url, "UTF-8");//值变为 www.231124214.com%2F3214+%21..mp3

         可以看出来上面url的规则已经被转码成为utf-8格式的url,而相应的诡异的符号已经被替换转义。但需要注意的是,规则转义标准化 url 字符串之前,需要将字符串中的 “http://” 这些协议前缀去掉,不然里面的 : 和 // 同样会被转义,这样格式化出来的url依旧不能用。

 

         当然除了上述使用url encoder的做法,我发现还可以使用简单粗暴的方式去格式化不规则的url,将这些不规则的url直接输入至浏览器,浏览器会对这些不规则的url中的符号进行转义,比如我们的 “www.231124214.com/3214 !..mp3” 便会被转义为“http://www..com/3214%20!..mp3”,可以看出,只有空格被转义为了 “%20” ,就可以访问了,因此我们也可以直接对url字符串中的空格进行替换即可; 

                        url = url.replaceAll(" ", "%20");

三、解决方案

          出现上述异常的结果可能有以下几种:

  • 资源的确不存在,报错
  • url没有进行格式化,解决方法如上

你可能感兴趣的:(Java)