最近,在使用JFinal和JBolt极速开发平台对一个已经搞了许久的C/S项目里进行B/S改造,数据库还是用C/S项目已经存在的SqlServer数据。
整体思路就是,JBolt极速开发平台配置数据源到SqlServer上,然后生成对应Model和BaseModel代码,因为这次改造并不是完整的所有模块CRUD都转到B/S项目里,只需要其中一个模块,所以就不生成CRUD代码了,用到哪个就直接创建Controller和Service就好了。
但是:
中间遇到一个问题,原数据库里图片字段都是使用了SqlServer-image类型,BLOB存储图片,转Model和BaseModel后对应的类型就是byte[]了。
我开发习惯是,B/S项目一般存图片的地址,项目本地上传到项目下的目录或者上传到自建文件服务器以及使用阿里云OSS、七牛云存之类的服务,最终存到字段上的数据就是一个URL网址。
<img src="具体的URL地址"/>
这样在页面上,使用Img标签,给src属性一个图片的可访问地址就行了。
那么:
针对我现在遇到的image格式字段,java里拿到byte[]数据的方式:
这里就用到了html里img标签的另一个特性,src属性除了给一个可以直接访问到图片的URL地址外,还可以返回一个图片格式数据流,浏览器会识别和解析的。
那么,接下来要做的就是把byte[]数据写出到流中,让img的src设置成为一个请求数据流的地址
<img src="http://localhost/admin/xxx/image?id=26"/>
只要我们实现这个action就可以了!
具体实现:
1、从数据库中拿到byte[]数据
2、通过response的outputStream写出
//获取图片流 public void image() { TCltemph tcl=service.findById(get("id")); if(tcl==null||tcl.getPic()==null||tcl.getPic().length==0) { renderNull(); }else { renderImg(tcl.getPic()); } }
//写出图片流 private void renderImg(byte[] picBytes) { HttpServletResponse response=getResponse(); response.setContentType("image/jpeg"); ServletOutputStream outputStream=null; try { outputStream = response.getOutputStream(); outputStream.write(picBytes); outputStream.flush(); }catch (IOException e) { throw new RenderException(e); } finally { if (outputStream != null) { try { outputStream.close(); } catch (IOException e) { throw new RenderException(e); } } } renderNull(); }
这样就搞定了,如果想复用可以放BaseController里,或者自己写一个ByteImageRender。
效果测试:
1、在浏览器中输入地址直接访问
2、项目中使用img标签的src去访问
延伸:
在Img标签的src上方action地址,动态写出图片数据流,这种方式在验证码场景经常用到哦,比如JFinal官网的登录注册使用的验证码,就是这么干的!
推荐文章:
【分享】JFinal调用SqlServer存储过程,带有输出参数的情况怎么处理?
关注JFinal学院公众号(jfinalxueyuan)
加我微信,随时交流:
mumengmeng