JFinal大牛的干货分享,和我一样的小白们,快搬小板凳来向这里看齐~~~
第一步:新建一个Handler,用于拦截所有的图片资源请求,通过判断图片资源的请求来源,来分辨该请求是否来源于本站,如果不是来源于本站的请求,那么就返回一个默认的图片。
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;
}
}
if (picSet.contains(...))
是需要控制的图片