美文网首页
java 加载https/http/本地类型路径的图片

java 加载https/http/本地类型路径的图片

作者: 安易学车 | 来源:发表于2019-03-29 14:09 被阅读0次

    原文地址:https://blog.csdn.net/csdn_terence/article/details/79244768

    一个读取网络路径和本地路径 图片的例子(亲测可用)

    需求:

    1.读取https、http类型,以及本地类型的图片。

    其中,加载https类型的图片时不能沿用http的获取方法,否则会报“unable to find valid certification path to requested target ”的错误。

    具体原因是,因为https(http+SSL)简单讲是http的安全版,即http下加入SSL层,https的安全基础是SSL,因此加密的详细内容就需要SSL。

    解决办法:此处使用https的Get请求来解决证书验证的问题。

    2.用日志记录相关信息(引入commons-logging-1.1.jar包)

    3.为了安全 ,对结果数据进行编码、解码,

    问题:

    首先为什么BASE64Encoder和BASE64Decoder在Eclipse中不能使用?

           编码解码使用sun包下的BASE64Encoder和BASE64Decoder两个工具把任意序列的8位字节描述为一种不易被人直接识别的形式;但不能使用是因为他们是Sun公司专用的API,在Eclipse后来的版本中都不能直接使用,但是直接使用文本编辑器编写代码,然后使用javac编译,java去执行是没有问题的。

    怎么设置才可以在Eclipse中使用BASE64Encoder和BASE64Decoder?

           右击项目 --> Properties --> Java Build Path --> 点开JRE SystemLibrary --> 点击Access rules --> Edit --> Add --> Resolution选择Accessible--> Rule Pattern 填** --> OK

    import java.io.ByteArrayOutputStream;

    import java.io.File;

    import java.io.FileInputStream;

    import java.io.IOException;

    import java.io.InputStream;

    import java.net.URL;

    import org.apache.commons.logging.Log;

    import org.apache.commons.logging.LogFactory;

    import sun.misc.BASE64Decoder;

    import sun.misc.BASE64Encoder;

    public class TestReadImgWithUrlOrPath {

    public static Log log=LogFactory.getLog(TestReadImgWithUrlOrPath.class);

    public static void main(String s[]) throws IOException

    {

    String urlOrPath="C:\\Users\\files\\Pictures\\kaola.jpg";

    //String urlOrPath="http://pic4.nipic.com/20091217/3885730_124701000519_2.jpg";

    System.out.println(urlOrPath);

    System.out.println(readImg(urlOrPath));

    }

    /*

    * 读取远程和本地文件图片

    */

    public static String readImg(String urlOrPath){

            InputStream in = null;

            try {

              byte[] b ;

          //加载https途径的图片(要避开信任证书的验证)

            if(urlOrPath.toLowerCase().startsWith("https")){

                b=HttpsUtils.doGet(url);

            }else if(urlOrPath.toLowerCase().startsWith("http")){

              //加载http途径的图片

                URL url = new URL(urlOrPath);

        in = url.openStream();             

                }else{ //加载本地路径的图片

                    File file = new File(urlOrPath);

                    if(!file.isFile() || !file.exists() || !file.canRead()){

                        log.info("图片不存在或文件错误");

                        return "error";

                    }               

                    in = new FileInputStream(file);

                }

                b = getByte(in); //调用方法,得到输出流的字节数组

    return base64ToStr(b);    //调用方法,为防止异常 ,得到编码后的结果

            } catch (Exception e) {

            log.error("读取图片发生异常:"+ e);

            return "error";

            }

        }

    public static byte[] getByte(InputStream in) throws IOException {

    ByteArrayOutputStream out = new ByteArrayOutputStream();

    try {

    byte[] buf=new byte[1024]; //缓存数组

    while(in.read(buf)!=-1){ //读取输入流中的数据放入缓存,如果读取完则循环条件为false;

    out.write(buf); //将缓存数组中的数据写入out输出流,如果需要写到文件,使用输出流的其他方法

    }

    out.flush();

    return out.toByteArray(); //将输出流的结果转换为字节数组的形式返回 (先执行finally再执行return )

    } finally{

    if(in!=null){

    in.close();

    }

    if(out!=null){

    out.close();

    }

    }

    }

    /*

    * 编码

    * Base64被定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式

    */

    public static String base64ToStr(byte[] bytes) throws IOException {

    String content = "";

    content = new BASE64Encoder().encode(bytes);

    return content.trim().replaceAll("\n", "").replaceAll("\r", ""); //消除回车和换行

    }

    /*

    * 解码

    */

    public static byte[] strToBase64(String content) throws IOException {

    if (null == content) {

    return null;

    }

    return new BASE64Decoder().decodeBuffer(content.trim());

    }

    }

    import javax.net.ssl.*;

    import java.io.*;

    import java.net.URL;

    import java.security.KeyManagementException;

    import java.security.NoSuchAlgorithmException;

    import java.security.SecureRandom;

    import java.security.cert.CertificateException;

    import java.security.cert.X509Certificate;

    /**

    * @desc: 实现https请求,可用于加载https路径的存储图片,避开信任证书的验证。

    */

    public class HttpsUtils {

      private static final class DefaultTrustManager implements X509TrustManager {

    @Override

    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

    }

    @Override

    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

    }

    @Override

    public X509Certificate[] getAcceptedIssuers() {

      return null;

    }

      }

      private static HttpsURLConnection getHttpsURLConnection(String uri, String method) throws IOException {

    SSLContext ctx = null;

    try {

      ctx = SSLContext.getInstance("TLS");

      ctx.init(new KeyManager[0], new TrustManager[]{new DefaultTrustManager()}, new SecureRandom());

    } catch (KeyManagementException e) {

      e.printStackTrace();

    } catch (NoSuchAlgorithmException e) {

      e.printStackTrace();

    }

    SSLSocketFactory ssf = ctx.getSocketFactory();

    URL url = new URL(uri);

    HttpsURLConnection httpsConn = (HttpsURLConnection) url.openConnection();

    httpsConn.setSSLSocketFactory(ssf);

    httpsConn.setHostnameVerifier(new HostnameVerifier() {

      @Override

      public boolean verify(String arg0, SSLSession arg1) {

    return true;

      }

    });

    httpsConn.setRequestMethod(method);

    httpsConn.setDoInput(true);

    httpsConn.setDoOutput(true);

    return httpsConn;

      }

      private static byte[] getBytesFromStream(InputStream is) throws IOException {

    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    byte[] kb = new byte[1024];

    int len;

    while ((len = is.read(kb)) != -1) {

      baos.write(kb, 0, len);

    }

    byte[] bytes = baos.toByteArray();

    baos.close();

    is.close();

    return bytes;

      }

      private static void setBytesToStream(OutputStream os, byte[] bytes) throws IOException {

    ByteArrayInputStream bais = new ByteArrayInputStream(bytes);

    byte[] kb = new byte[1024];

    int len;

    while ((len = bais.read(kb)) != -1) {

      os.write(kb, 0, len);

    }

    os.flush();

    os.close();

    bais.close();

      }

      public static byte[] doGet(String uri) throws IOException {

    HttpsURLConnection httpsConn = getHttpsURLConnection(uri, "GET");

    return getBytesFromStream(httpsConn.getInputStream());

      }

      public static byte[] doPost(String uri, String data) throws IOException {

    HttpsURLConnection httpsConn = getHttpsURLConnection(uri, "POST");

    setBytesToStream(httpsConn.getOutputStream(), data.getBytes());

    return getBytesFromStream(httpsConn.getInputStream());

      }

    }

    ---------------------

    作者:Terence_Jing

    来源:CSDN

    原文:https://blog.csdn.net/csdn_terence/article/details/79244768

    版权声明:本文为博主原创文章,转载请附上博文链接!

    相关文章

      网友评论

          本文标题:java 加载https/http/本地类型路径的图片

          本文链接:https://www.haomeiwen.com/subject/caelbqtx.html