使用httpclient下载图片时,url中含有中文字符,导致下载失败的解决方法

先说解决方法吧:

修改tomcat的server.xml文件,在Connector标签中加上URLEncoding参数

<Connector port="8080" maxThreads="150" minSpareThreads="25"
maxSpareThreads="75" enableLookups="false" redirectPort="8443"
acceptCount="100" debug="99" connectionTimeout="20000"
disableUploadTimeout="true" URIEncoding="UTF-8"/>
原因:

经过分析,应该是Tomcat在解析参数的时候没有使用正确的编码格式(UTF-8)去解码。

查看$TOMCAT_HOME/webapps/tomcat-docs/config/http.html这个说明文档,有如下说明:
URIEncoding:This specifies the character encoding used to decode the URI bytes, after %xx decoding the URL. If not specified, ISO-8859-1 will be used.

也就是说,如果没有设置URIEncoding, Tomcat默认是按ISO-8859-1进行URL解码,ISO-8859-1并未包括中文字符,这样的话中文字符肯定就不能被正确解析了。


如果包含中文,应当把中文字符变成字节(利用GB18030或者UTF-8等编码)。

客户端转换的方式必须和服务器相同,比如服务器认为URL中的中文按照UTF-8编码,你的客户端就不能按照GB18030编码。

如果服务器是你的,你应该知道它用哪种方法编码URL。如果是Tomcat,你需要修改server.xml。上网用“tomcat URIEncoding”关键字搜索,修改一个叫URIEncoding的东西。

客户端,你可以构造一个java.net.URI(构造的时候会用UTF-8编码),然后转换成URL。也可咦用Apache HTTP Client中提供的方法进行转义。 

package com.zteits.atms.tgs.common.util;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import com.zteits.atms.util.file.FileOperater;
import flex.messaging.util.URLEncoder;

public class DownLoadImgeUtil
{

    /**
     * 生成文件路径
     * @return
     * @throws Exception
     */
    public static String getPath() throws Exception
    {

        int len = DownLoadImgeUtil.class.getResource("").getPath().indexOf("WEB-INF");
        String filepath = DownLoadImgeUtil.class.getResource("").getPath().substring(0, len) + "picTemp";

        FileOperater fo = new FileOperater();
        fo.newFolder(filepath);
        return filepath;
    }

    /**
     * 下载图片
     * @param fileimgpath 文件名称
     * @param imageList 图片路径
     * @return  是否下载成功
     * @throws Exception
     */
    public static int downLoadImge(String fileimgpath, List imageList) throws Exception
    {
        String filerootpath = getPath();
        System.out.println("filerootpath: " + filerootpath);
        String filepath = filerootpath + "\\" + fileimgpath;
        System.out.println("filepath: " + filepath);
        OutputStream os = new FileOutputStream(filepath + ".zip");
        ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(os));
        HttpClient hc = new HttpClient();
        GetMethod getMethod = null;
        String filename1;
        try
        {
            for(int i = 0; i < imageList.size(); i++)
            {
                System.out.println("======== " + i);
                try
                {
                	String fullURl = (String)imageList.get(i);
                	//现场发布的图片路径,支持中文
                    String strurl = tranformStyle(fullURl.substring(fullURl.lastIndexOf("$http")+1));                   
                    getMethod = new GetMethod(strurl);
                    int randomNum = (int) (Math.random()*9000+1000);
                    String path;
                    path = fullURl.substring((fullURl.lastIndexOf(".")+1),fullURl.length());
                    // 重命名
                    filename1 = fullURl.substring(0, (fullURl.lastIndexOf("$http")+1))+String.valueOf(randomNum)+"."+path;
                    hc.executeMethod(getMethod);
                    
                    out.putNextEntry(new ZipEntry(filename1));                   
                    out.write(getMethod.getResponseBody());
//                    out.setEncoding("gbk");

                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }

            }
            // 释放连接
            getMethod.releaseConnection();
            out.flush();
            out.close();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        return 1;
    }

    /**
     * 下载图片(根据路口分类放在不同文件夹)
     * @param fileimgpath 文件名称
     * @param imageList 图片路径
     * @return  是否下载成功
     * @throws Exception
     */
    public static int downLoadImge1(String fileimgpath, List imageList) throws Exception
    {
        String filerootpath = getPath();
        String filepath = filerootpath + "\\" + fileimgpath;      
        OutputStream os = new FileOutputStream(filepath + ".zip");
        ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(os));
        HttpClient hc = new HttpClient();
        GetMethod getMethod = null;
        String filename1;
        try
        {
            for(int i = 0; i < imageList.size(); i++)
            {
                System.out.println("======== " + i);
                try
                {
                	String fullURl = (String)imageList.get(i); 
                	//现场发布的图片路径,支持中文
                    String strurl = tranformStyle(fullURl.substring(fullURl.lastIndexOf("$http")+1));
                    getMethod = new GetMethod(strurl);
                    int randomNum = (int) (Math.random()*9000+1000);
                    String path;
                    path = fullURl.substring((fullURl.lastIndexOf(".")+1),fullURl.length());// .jpg
                    // 重命名
                    filename1 = fullURl.substring(0, (fullURl.lastIndexOf("$http")+1))+String.valueOf(randomNum)+"."+path;
                    String fileCatergory = fullURl.substring(0,fullURl.indexOf("$"));
                    hc.executeMethod(getMethod);
                    File file =new File("\\" + fileCatergory);
                    // 如果文件夹不存在创建文件夹,并且把图片放入文件夹
                    if(!file.exists()){
                    	file.mkdir();                    
                    	URL url = new URL(strurl);  
                        HttpURLConnection conn = (HttpURLConnection)url.openConnection();  
                        InputStream is = conn.getInputStream();
                        byte[] buffer=new byte[1024];
                     	int len=0;                   	  
                     	while((len=is.read(buffer))!=-1){
                     	   os.write(buffer, 0, len);
                     	}
                	}       
                    out.putNextEntry(new ZipEntry(fileCatergory + "/" + filename1.trim()));
                    out.write(getMethod.getResponseBody());
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }

            }
            // 释放连接
            getMethod.releaseConnection();
            out.flush();
            out.close();
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        return 1;
    }
    
    /**
     * 对中文字符进行UTF-8编码
     * @param source 要转义的字符串
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String tranformStyle(String source) throws UnsupportedEncodingException
    {
        char[] arr = source.toCharArray();
        StringBuilder sb = new StringBuilder();
        for(int i = 0; i < arr.length; i++)
        {
            char temp = arr[i];
            if(isChinese(temp))
            {
                sb.append(URLEncoder.encode("" + temp, "UTF-8"));
                continue;
            }
            sb.append(arr[i]);
        }
        return sb.toString();
    }

    /**
     * 获取字符的编码值
     * @param s
     * @return
     * @throws UnsupportedEncodingException
     */
    public static int getValue(char s) throws UnsupportedEncodingException
    {
        String temp = (URLEncoder.encode("" + s, "GBK")).replace("%", "");
        if(temp.equals(s + ""))
        {
            return 0;
        }
        char[] arr = temp.toCharArray();
        int total = 0;
        for(int i = 0; i < arr.length; i++)
        {
            try
            {
                int t = Integer.parseInt((arr[i] + ""), 16);
                total = total * 16 + t;
            }
            catch(NumberFormatException e)
            {
                e.printStackTrace();
                return 0;
            }
        }
        return total;
    }

    /**
     * 判断是不是中文字符
     * @param c
     * @return
     */
    public static boolean isChinese(char c)
    {

        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);

        if(ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS

        || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS

        || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A

        || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION

        || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION

        || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS)
        {

            return true;

        }

        return false;

    }

}




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值