作为一个资深表情包爱好者,一直打算创建一个表情包的收录、在线制作、搜索的网站,因为对jpress非常熟悉,所以一开始尝试用jpress来做,先说说我的需求,主要包括如下几个:
1、可以上传、下载表情包。
2、能对表情包进行标签tag标注。
3、用户可以搜索。
4、微信支持。
5、在线制作表情包(能够进行模板管理、制作上传下载)。
6、CDN云存储。
前期需求主要就是这些,后期扩展出用户登录注册、收藏等常见功能。
很明显,对于jpress需要做一些定制,这边顺便说下表情包网站的几个特点:
1、小图片多,一期总量预估大概在50G左右,大概75万张。
2、tag标签,预计一张图片对1:3的话,那就是有225w个tag(很多相同的)总量20万左右。
但是一开始还是非常倾向jpress定制,所以第一版本的撸表情是基于jpress开发的,但是上线半个月之后问题就突显出来了,特别是数据真正开始变多的时候,需要对jpress后台进行大改动。
所以最终选择jfinal重头写。。。
写出来分享给大家,如果有用jpress做图片站需要注意的几个地方:
1、图片自动压缩部分需要定制
2、图片转存cdn
3、tag标签非常多的情况下,归类检索效率缓存需要定制策略
4、然后就是tag的全文检索,模糊匹配问题,搜索效率不高。
这边在分享一个jpress防盗链的hander,可以直接拿去用,代码如下:
public class PicHandler extends Handler {
@Override
public void handle(String target, HttpServletRequest request,HttpServletResponse response, boolean[] isHandled) {
String ctx = WebContextUtil.getContextPath(request); //获取网站的根路径
String uri = request.getRequestURI(); //获取请求的uri
if (uri.contains(".jpg") || uri.contains(".jpeg") || uri.contains(".png") || uri.contains(".gif")) {
//获取图片请求的来源地址,如果是直接在浏览器中输入图片地址请求的,返回null;如果是来源于本站的,会返回当前页面的地址;如果来源于外部网站,会返回外部网站的url地址。
String referer = request.getHeader("referer");
if (StrKit.notBlank(referer) && !referer.contains(ctx)) {
//如果不为空,且请求的来源地址里面不包含本站域名,那么说明就是通过外部网站请求的,图片外部网站被请求使用。
try {
//将请求转发掉,转发出一个根目录images文件夹下的一个默认图:guardAgainst.png,这样所有外站引用的图片,就全部都返回guardAgainst.png这张图片了。
request.getRequestDispatcher("/images/guardAgainst.png").forward(request, response);
//不再让tomcat或者jetty处理该请求
isHandled[0] = true ;
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}else {
next.handle(target, request, response, isHandled);
}
}else {
next.handle(target, request, response, isHandled);
}
}
}
特别注意,else里面的next.handle(target, request, response, isHandled); 一定要写到else里面,当图片请求来源是本站时,不转发请求,将请求交给jFinal处理。只有不是本站的请求的时候,才进行请求转发,在请求转发以后, writer 关闭 ,所以不可以再讲请求交给jfinal或者tomcat/jetty处理,否则会抛出java.lang.IllegalStateException: Committed 的异常。
第二步:在配置中配置这个Handler。
public class SystemConfig extends JFinalConfig {
public void configHandler(Handlers me) {
me.add(new PicHandler()); //配置图片资源的Handler
}
}
另附一个上面用到的小工具类:
public class WebContextUtil {
/**
* 获取上下文URL全路径
* @param request
* @author nbjgl
*/
public static String getContextPath(HttpServletRequest request) {
StringBuilder sb = new StringBuilder();
int port = request.getServerPort();
if(80==port){
sb.append(request.getScheme()).append("://").append(request.getServerName()).append(request.getContextPath());
}else{
sb.append(request.getScheme()).append("://").append(request.getServerName()).append(":").append(port).append(request.getContextPath());
}
String path = sb.toString();
return path;
}
}
全局handler,拿去直接用就可以了。
最后撸表情体验地址:http://www.lubiaoqing.com ,欢迎加入码农交流群:84894149,jpress水友群:582035381。