${imageInfo[‘width’]} x ${imageInfo[‘height’]}
“`
这样做的好处很明显:Java逻辑留在Java文件里,JSP页面只做数据渲染,分工清晰,顺便提一句,如果你的项目用的是Spring MVC或Spring Boot,原理完全一样,换成@Controller和@RequestMapping即可。
jsp获取图片尺寸代码异常处理,这三类坑最常见
只写正常流程的代码,任何一个上过线的项目都不敢这么干,根据我平时的经验,以下三类异常出现频率最高,处理方案也比较成熟。
图片文件损坏时返回null
ImageIO.read()遇到不完整或伪造的图片文件,会静默返回null,而不是抛出异常,很多人接着调用getWidth(),直接触发NullPointerException,处理方式是在拿到BufferedImage之后先判断一下:
BufferedImage image = ImageIO.read(imgFile);
if (image == null) {
// 记录日志,返回提示信息,而不是继续执行
return;
}
非标准格式读取失败
常见的jpg、png、gif、bmp格式都在ImageIO内置支持范围内,但遇到CMYK色彩模式的JPG,或者WebP格式时,ImageIO.read()经常返回null,据统计,工作中碰到WebP格式图片导致接口报错的场景越来越多,解决方案是引入TwelveMonkeys库替换默认的图片读取实现,它能兼容大多数扩展格式。
getRealPath()在部署后路径临时变化
Tomcat把WAR包解压到临时目录后,getRealPath()返回的路径可能包含temp字样,服务器重启后路径还会变化,如果图片是运行时上传的,建议不要把文件存到项目部署目录内,而是存到一个固定的外部磁盘目录,比如/data/www/upload,然后用配置项维护这个路径。
把jsp获取图片大小的代码封装成工具类
如果项目中有多个页面需要展示图片信息,每次重写一遍IO读取逻辑会显得很啰嗦,更好的做法是封装一个静态工具方法,需要的时候直接调用。
public class ImageInfoUtil {
public static ImageInfo getImageInfo(String absolutePath) {
File imgFile = new File(absolutePath);
if (!imgFile.exists()) return null;
ImageInfo info = new ImageInfo();
info.setFileSize(imgFile.length());
BufferedImage image = ImageIO.read(imgFile);
if (image != null) {
info.setWidth(image.getWidth());
info.setHeight(image.getHeight());
}
return info;
}
}
ImageInfo这个实体类包含三个字段:fileSize、width、height,并配有对应的getter/setter方法,以后不管在Servlet、Controller还是JSP脚本块里,一行代码就能拿到全部信息:
ImageInfo info = ImageInfoUtil.getImageInfo("/data/upload/hero.jpg");
注意一点:这个方法内部做了文件存在性检查和空值保护,返回的ImageInfo有可能是null,调用方仍要保留判空习惯。
jsp获取图片大小常见问题解答
ImageIO.read()返回null时该怎么办?
先确认文件后缀是否为标准格式,再用图片编辑软件打开该文件看看能否正常显示,因为有些图片只是改了扩展名,内部数据结构完全不对,如果图片能打开但代码返回null,多半是色彩空间或压缩算法不兼容,可尝试引入额外的图片IO库。
在JSP页面里直接写Java代码和写在Servlet里有什么区别?
在JSP的<% %>脚本块里写new File()和ImageIO.read()确实能运行,但这样做会让页面代码和业务逻辑耦合在一起,后期维护时很难受,设想一下,几个月后你需要修改图片大小校验逻辑,在几十个JSP页面里搜索同样一段代码,改动成本相当高,放到Servlet或工具类中,修改一处即可全局生效,行业内的开源项目几乎不会在JSP里直接写这种逻辑,建议你还是把功能下沉到Java类中。
文件大小和像素尺寸之间存在固定换算公式吗?
不存在,相同体积的两张图片,一张是纯色背景,一张是复杂风景照,像素尺寸可能接近,但文件大小相差数倍,文件大小取决于压缩算法、色彩深度、质量参数等因素,像素尺寸只和被解码后的图像宽高有关,需要展示体积就调用File.length(),需要布局计算就用getWidth()和getHeight(),两者各司其职,不要试图互相推算。
在服务器上获取图片大小,归根结底就这两步:用File拿到体积信息,用ImageIO解码后读取宽高,路径问题优先交给ServletContext.getRealPath()处理,代码统一封装成工具类,再做好空值防御,这套方案能覆盖绝大多数业务场景。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/773193.html


