最初 node 版本在这里。

源码下载,单 jsp 文件 http://pan.baidu.com/s/1gfoDy0r (百度云提供)

App 客户端加载图片的时候,在服务端需要进行相关的优化,否则会给流量和占用内存带来消耗和压力。起初想到了利用 node 搭建一个简易的图片服务器来完成。遗憾的是,因为 Centos 平台上 node-images 二进制包的问题,导致不能顺利使用 node 方案。于是迫不得已,改用 Java 来完成。及后,考虑到逻辑不复杂和部署的简易,特意将 Java 改成 JSP 页面调用,而非 Servlet。JSP 大家都比较熟悉,这里再提一提它的优点:1、可以“过程式”编码,不用考虑包等的问题。虽然面向对象 OO 必须强调,但某些时候“过程式”足矣,结构简单明晰;2、无须重启服务器,修改立刻看到效果,减少运维的工作。有同学说过,JSP 问题:一、混搭 HTML 代码不好看,这个确实是如果开发者可以注意下,也是能够规避的;二、写起来太慢。噢~我现在不是第一时间在 JSP 里面写 Java,而是在 Java 类里面写好了、测试好了再 copy 到 JSP(原 Java 文件在这里),稍微改动下,有点像手动打包的过程,呵呵。

值得一提的是,Tomcat 7 下 JSP 默认的 Java 语法仍旧是 1.6 的。在 JSP 里面嵌入 Java 1.7 特性的代码会抛出“Resource specification not allowed here for source level below 1.7”的异常。于是需要修改 Tomcat/conf/web.xml 里面的配置文件,找到 <servlet> 节点,加入下面粗体部分才可以。注意是 jsp 节点,不是 default 节点(很相似)。

 <servlet><servlet-name>jsp</servlet-name><servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class><init-param><param-name>fork</param-name><param-value>false</param-value></init-param><init-param><param-name>xpoweredBy</param-name><param-value>false</param-value></init-param>
        <init-param><param-name>compilerSourceVM</param-name><param-value>1.7</param-value></init-param><init-param><param-name>compilerTargetVM</param-name><param-value>1.7</param-value></init-param><load-on-startup>3</load-on-startup></servlet>

调用例子:

img_resize.jsp?url=http://desk.fd.zol-img.com.cn/t_s1920x1200c5/g5/M00/0F/04/ChMkJ1dGqWOITU3xAA5PBuQ0iRMAAR6mAAAAAAADk8e103.jpg&h=400

先说说图片处理的流程。

  1. 首先从 url 参数获取图片地址,该参数必填
  2. 通过 HTTP HEAD 请求检测是否 404,以及图片文件大小
  3. 如果小于 100kb (1024 * 100)则无须压缩,响应对象发出 302 重定向 url 地址
  4. 如果大于 100kb,则读取文件流,输入到 java.awt.Image 对象
  5. 如果没有指定高、宽,那么直接在浏览器输出图片(原尺寸输出)
  6. 若 w / h 指定其一则按图片比例缩放,w:int = 宽度,可选,h:init = 高度,可选。
  7. 通过图片原尺寸计算出比例,求得 w / h
  8. 通过 setResize(Image img, int height, int width) 方法设置图片大小

可能还有考虑不周的情况,望大家指点提拨。

JSP 页面调用方式就是:

<%@page pageEncoding="utf-8" import="java.io.*, java.net.*, javax.imageio.ImageIO, java.awt.Image, java.awt.image.*"%>
<%// JSP 实用程序之简易图片服务器 // http://blog.csdn.net/zhangxin09/article/details/51523489// sp42 2016-5-30String url = request.getParameter("url");if(url == null){out.println("缺少 url 参数!");return;}try{getImg(url, request, response);//清除输出流,防止释放时被捕获异常out.clear();out = pageContext.pushBody(); } catch(Exception e) {out.println("Error:" + e);}
%>

依赖函数仅仅是以下几个:

<%!/*** 主要的函数*/public static void getImg(String url, HttpServletRequest request,  HttpServletResponse response) throws IOException {System.out.println("请求地址:" + url);URL urlObj = new URL(url);HttpURLConnection conn = (HttpURLConnection) urlObj.openConnection();int imgSize = getSize(conn, urlObj.getHost());if (imgSize < (1024 * 100)) {response.sendRedirect(url);// 发送重定向return;} else {//      System.out.println("BigImg");String imgType = getImgType(url);response.setContentType(getContentType(imgType));try (InputStream is = new URL(url).openStream();ServletOutputStream op = response.getOutputStream();){String height = request.getParameter("h"), width = request.getParameter("w");if (height != null && width != null) {BufferedImage bufImg = setResize(ImageIO.read(is), Integer.parseInt(height), Integer.parseInt(width));ImageIO.write(bufImg, imgType, op);} else if (height != null) {Image img = ImageIO.read(is);// 将输入流转换为图片对象int[] size = resize(img, Integer.parseInt(height), 0);BufferedImage bufImg = setResize(img, size[0], size[1]);ImageIO.write(bufImg, imgType, op);} else if (width != null) {Image img = ImageIO.read(is);// 将输入流转换为图片对象int[] size = resize(img, 0, Integer.parseInt(width));BufferedImage bufImg = setResize(img, size[0], size[1]);ImageIO.write(bufImg, imgType, op);} else {// 直接写浏览器byte[] buf = new byte[1024];int len = is.read(buf, 0, 1024);while (len != -1) {op.write(buf, 0, len);len = is.read(buf, 0, 1024);}} }  }}/*** 返回 Content type* @param imgType* @return*/private static String getContentType(String imgType) {switch (imgType) {case "jpg":return "image/jpeg";case "gif":return "image/gif";case "png":return "image/png";default:return null;}}/*** 获取 url 最后的 .jpg/.png/.gif* @param url* @return*/private static String getImgType(String url) {String[] arr = url.split("/");arr = arr[arr.length - 1].split("\\.");String t = arr[1];return t.replace('.', ' ').trim().toLowerCase();}/*** 缩放比例* * @param img*            图片对象* @param height*            高* @param width*            宽* @return*/public static int[] resize(Image img, int height, int width) {int oHeight = img.getHeight(null), oWidth = img.getWidth(null);double ratio = (new Integer(oHeight)).doubleValue() / (new Integer(oWidth)).doubleValue();if(width != 0) {height =  (int) (ratio * width); }else {width = (int) ( height / ratio);} return new int[]{height, width};} /*** 完成设置图片大小* * @param img*            图片对象* @param height*            高* @param width*            宽* @return 缓冲的图片对象*/public static BufferedImage setResize(Image img, int height, int width) {BufferedImage bufImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);bufImg.getGraphics().drawImage(img, 0, 0, width, height, null);return bufImg;}/*** * @param conn* @param referer* @return*/public static int getSize(HttpURLConnection conn, String referer) {try {conn.setRequestMethod("HEAD");conn.setInstanceFollowRedirects(false); // 必须设置false,否则会自动redirect到Location的地址conn.addRequestProperty("Accept-Charset", "UTF-8;");conn.addRequestProperty("User-Agent","Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.8) Firefox/3.6.8");conn.addRequestProperty("Referer", referer);conn.setConnectTimeout(5000);// 设置超时conn.setReadTimeout(30000);InputStream body = null;try {body = conn.getInputStream();} catch (UnknownHostException e) {throw new RuntimeException("未知地址!" + conn.getURL().getHost() + conn.getURL().getPath());} catch (FileNotFoundException e) {throw new RuntimeException("404 地址!" + conn.getURL().getHost() + conn.getURL().getPath());} catch (SocketTimeoutException e) {throw new RuntimeException("请求地址超时!" + conn.getURL().getHost() + conn.getURL().getPath());}body.close();// if (conn.getResponseCode() > 400) // 如果返回的结果是400以上,那么就说明出问题了// LOGGER.warning("Err when got responseCode :" +// conn.getResponseCode() + getUrlStr());// conn.connect();也就是打开流} catch (IOException e) {e.printStackTrace();return -1;}String sizeStr = conn.getHeaderField("content-length");return Integer.parseInt(sizeStr);}
%>

开发过程值得记住的几点:

  • Url 和 Connection 貌似不能重复使用,于是两次请求(同一地址)得有两个 url 对象
  • 调整图片比例函数比较简单,但编码有时得晓得不是写算术。
  • 设定好正确的 图片ContentType
  • 不知道动图 gif 压缩后是否只剩一帧?

不足之处,敬请大家提出。

JSP 实用程序之简易图片服务器相关推荐

  1. Python中使用Flask、MongoDB搭建简易图片服务器

    转自:http://www.ctolib.com/topics-43840.html 1.前期准备 通过 pip 或 easy_install 安装了 pymongo 之后, 就能通过 Python ...

  2. 简易图片服务器项目说明

    目录 一. 项目背景 二.项目使用技术栈与环境 三.项目功能 四.项目具体实现 4.1:数据库.表的设计 4.2:pom.xml文件中引入依赖 4.3:服务器端封装数据库的的设计 4.4:服务器端se ...

  3. 使用 Nginx 搭建图片服务器

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试资料 作者 | ITDragon龙 链接 | cnblogs.com/i ...

  4. Nginx 搭建图片服务器

    本章内容通过Nginx 和 FTP 搭建图片服务器.在学习本章内容前,请确保您的Linux 系统已经安装了Nginx和Vsftpd. Nginx 安装 http://www.cnblogs.com/i ...

  5. JSP中访问本地图片

    图片不放在工程路径下    在JSP 文件中 <img src="C:/Users/fx/Pictures/test.jpg"/> 这样是引不到图片的.因为,JSP页面 ...

  6. 使用nginx作图片服务器的访问权限控制

    说到访问权限控制,很多看了nginx相关文章的朋友都会自然联想到X-Accel-Redirect这个头.这个头有个缺陷,就是所有的访问都会先经过一个fastcgi来判断权限.在下载系统上,用这个方法是 ...

  7. CentOS7设置静态IP、搭建单机版FastDFS图片服务器、使用FastDFS-Client客户端进行简单测试、实现图片上传、实现商品添加修改删除

    CentOS7设置静态IP.搭建单机版FastDFS图片服务器.使用FastDFS-Client客户端进行简单测试.实现图片上传.实现商品添加修改删除 CentOS7设置静态IP而且还可以上网 192 ...

  8. Apache Server搭建图片服务器

    Apache Server搭建图片服务器 导读:公司来了几个应届生,经常问我图片应该上传到哪里,是直接在工程下面创建一个upload_image文件夹,然后将图片上传到这个upload_image文件 ...

  9. 淘淘商城第三天—完成商品添加功能 商品类目选择 图片上传 图片服务器搭建 kindEditor富文本编辑器的使用 商品添加功能

    1.实现商品类目选择功能 1.1需求 在商品添加页面,点击"选择类目"显示商品类目列表: 请求初始化树形控件的url:/item/cat/list 1.2 EasyUI tree数 ...

  10. javaweb项目创建图片服务器

    javaweb项目,创建tomcat图片服务器,用于保存用户上传的头像等图片信息.前期项目的新建和正常访问的调试不再说明,本文章仅讲解如何创建一个图片服务器. 1.WebContent下新建imgFi ...

最新文章

  1. 占失物,笔记本电脑电池
  2. 扫盲:关于Android手机内存ROM、RAM还有SD卡的解释
  3. Linux-鸟菜-4-关机的正确姿势
  4. VTK:图片之ImageLaplacian
  5. 虚拟机克隆Linux操作系统后解决MAC地址冲突
  6. php的配置工具,星外php自动配置工具
  7. 【若依(ruoyi)】按钮样式
  8. 厉害了,在Pandas中用SQL来查询数据,效率超高
  9. sql注入pythonpoco_.NET EF(Entity Framework)详解
  10. fun(int **p)的使用
  11. Linux Shell脚本入门教程系列之(八)Shell printf命令详解
  12. 【华为云技术分享】深度详解GaussDB bufferpool缓存策略
  13. 仿新浪新闻中异步替换关键字
  14. git常用命令与常见问题解决办法
  15. 常用编程语言开发工具
  16. 微信小程序标签样式的优先级
  17. Acwing 1402. 星空之夜(搜索+哈希)
  18. CVPR2021 | CVPR2021最全整理,CVPR2021下载链接,CVPR2021全部论文代码
  19. Android wps自定义功能,完美兼容安卓4.2新增多项功能 WPS移动版升级至5.2
  20. python绘制人物关系图_文本分析之制作网络关系图——Python

热门文章

  1. Python Turtle绘图基础(一)——Turtle简介、绘图窗体与绘图区域
  2. Jeg lurer p? om vi skulle v?re ? parajumpers jakke tenke p? hva som kan
  3. 为求一层栈,追踪八万里
  4. php 调用 百度句法分析,【原创源码】百度新版翻译API调用使用范例
  5. 解决浏览器下载速度慢的问题
  6. 安卓初始画面去黑色背景
  7. QT如何去掉布局(Layout)内控件之间的空隙
  8. JScriptJQuery学习
  9. JSCRIPT如何调试
  10. 看传智播客刘龙宾老师的Vue.js学习笔记