读书人

用servlet实现图片自动换(用一个.jpg

发布时间: 2012-03-28 15:40:03 作者: rapoo

用servlet实现图片自动换(用一个.jpg结尾的URL获得一张可变图片),求教如何在每次被外链引用时按顺序更换图片
每次刷新页面,同样一个图片URL显示的图片不一样。曾经有不少网站搞过这东西,魔幻图片夹、天使表情网等等,因为未知原因一一关闭。于是想自己尝试制作出类似的效果。该效果常用于百度贴吧骗回帖,论坛动态签名头像等。看到不少人问过类似问题,但给的答案都是用jsp页面或者flash实现,这样返回的内容不能当作图片URL被外链。看到有PHP的实现方法,但是URL是以.php的形式表现,不具备足够的隐蔽性。

详细需求说明:
1.输入输出效果与jpg图片URL完全类似,即输入一个后缀为.jpg的URL,获得一个图片文件。URL不能用.php,.jsp或者.do带参数等形式,否则影响隐蔽效果;返回的内容不能是一个使用img标签的页面,否则此url放入img标签将不能被正常显示。
2.按顺序或者随机的显示方式,当用户每次刷新时,返回的图片将产生相应的变化。

我现在的实现方法是:
1.配置web.xml,添加如下代码,用于将某特定的jpg请求转向到servlet处理:

XML code
<servlet>    <servlet-name>PicChange</servlet-name>    <servlet-class>PicChange</servlet-class>  </servlet>  <servlet-mapping>    <servlet-name>PicChange</servlet-name>    <url-pattern>/orz.jpg</url-pattern>  </servlet-mapping>


2.创建对应的servlet,名为PicChange.java,输出写法是参考了验证码图片
Java code
import java.io.File;import java.io.IOException;import java.io.OutputStream;import javax.imageio.ImageIO;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;public class PicChange extends HttpServlet {  public void doGet(HttpServletRequest request, HttpServletResponse response)   throws ServletException, IOException {  doPost(request,response); } /*mir  Mar 31, 2009*/ public void doPost(HttpServletRequest request, HttpServletResponse response)   throws ServletException, IOException {  response.setContentType("image/jpeg");  response.setHeader("Pragma", "No-cache");  response.setHeader("Cache-Control", "no-cache");  response.setDateHeader("Expires", 0);    OutputStream out = response.getOutputStream();  //显示方式暂时采用传入的参数,可从数据库或者配置文件中获取定义  String orderOrRandom = (String)request.getParameter("random");  if(orderOrRandom==null||"".equals(orderOrRandom)){   orderOrRandom = "order";  }else if("true".equals(orderOrRandom)){   orderOrRandom = "random";  }  String img = request.getSession().getServletContext().getRealPath("image");  File imgPath = new File(img);  File[] imgList = imgPath.listFiles();//获得图片文件夹下的所有图片File    Integer num;    if("order".equals(orderOrRandom)){   HttpSession session = request.getSession();   num = (Integer)session.getAttribute("num");   if(num==null||num>=imgList.length){    num=0;   }   session.setAttribute("num", num+1);     }else{   num = ((Double)(Math.random()*(imgList.length))).intValue();     }  ImageIO.write(ImageIO.read(imgList[num]),"JPEG",out); }}




预览效果:



好了问题来了……之前测试的时候发现,貌似图片仅仅在外链被引用时并不会产生session。本打算默认的变化方式是按顺序,用户每次提交时在session中取一个累加计数器来返回不同的图片。
结果每次刷新时都只会显示第一张图片。只有当用户将这个URL放入地址栏访问过后才会生效,这时点击刷新就会按顺序更换了,并且此时保持浏览器不关闭,访问其他的论坛中外链的这张图片,也能够看到变化效果。

在这个问题没解决的情况下,我现在已设置为随机更换图片效果。随机不会出现这种问题……
我想知道是否有更好的办法来实现顺序更换,或者有更好更节省资源的算法?第一次发帖,希望各位高手不吝赐教,谢谢……

[解决办法]
不太懂~mark~学习~
[解决办法]
request.getSession() 可以创建一个
[解决办法]
如果session没有效。那只能暂时用IP判断了。
[解决办法]
1、不改WEB.XML你要的效果绝对达不到,除非你自己写个TOMCAT
2、IP可以用REQUEST得到,在HTTP协议中,每个访问者都带着自己的IP来的。
------解决方案--------------------


外链的时候为什么session会取不到值呢,我在一个应用加上iframe src="另一个应用的servlet" 可以正常取到session里的attribute啊
[解决办法]
帮顶
[解决办法]
楼主可以试一下 使用过滤器,大体思路是根据请求是不是你要进行变换的图片,
如果不是则放行,如果是则进行处理,然后跳转到随机产生“魔术的”图片的url
主要大体代码如下

Java code
//执行过滤的核心方法    public void doFilter(ServletRequest request,        ServletResponse response, FilterChain chain)        throws IOException,ServletException    {        //---------下面代码用于对用户请求执行预处理---------        //获取ServletContext对象,用于记录日志        ServletContext context = this.config.getServletContext();         long before = System.currentTimeMillis();        System.out.println("开始过滤...");        //将请求转换成HttpServletRequest请求        HttpServletRequest hrequest = (HttpServletRequest)request;        //截取所有图片请求        if(hrequest.getServletPath().equals("你的魔术图片的url"))        {          //生成随机数,产生随机url,进行魔术变换,相应的业务逻辑写到这里,                    //最后调用context.getRequestDispatcher将图片请求的url转发                    context.getRequestDispatcher("/img/daolian.gif").forward(request, response);        }        //Filter只是链式处理,请求依然放行到目的地址                chain.doFilter(request, response);            }
[解决办法]
感觉不需要这么复杂~~~你可以用javascript或<% %>嵌入java代码得到一个0—10的随机数,然后进行url拼接,比如:
Random r = new Random();
int a = r.nextInt(10);a为0-9这10个数
现实图片的url="/images/picture"+<%=a%>+".jpg" 把10张图片分别命名为picture0.jpg-picture9.jpg,每刷新一下都会得到一个随机数,而url也会变,图片也会变,而且不管多少张图片都可以~~

[解决办法]
你可以这样试一下,把 刷新更换 这个链接的url用encode编码一下,这样就把sessionId放到请求头信息中了,这样或许会得到上一次的Session
[解决办法]

[解决办法]
这么多解决办法,人多办法多。
[解决办法]
学习哦。。。
[解决办法]
学习,虽然偶不太懂。。。
[解决办法]
有结果了没?
[解决办法]
我觉得哈

既然你是想要一个顺序的图片结果集,那图片的filename生成 就是一个单独的生成器来生成的,可以定义一个全局的static变量来维护,而和你的session是没有关系的。
[解决办法]
你应该先获取当前的picname吧,获取的了然后往下面累加,如果picname为空,就是第一个开始便利,感觉你程序写的怪怪的
[解决办法]
学习中,帮顶
[解决办法]
帮顶

[解决办法]
学习.....
[解决办法]
学习中!
[解决办法]
学习了~~~~~~~~~
[解决办法]
学习一下
[解决办法]
探讨
网上搜索了下,貌似response.getOutputStream()会由服务器自动关闭,不用手动关。

总结下现在的问题……
1.

response.setContentType("image/jpeg")是否必要?注释掉以后发现图片还是一样可以显示的,不放这行代码是否会有什么潜在问题?
2.

response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");


response.setDateHeader("Expires", 0);
这3行是否必要?注释掉后…


[解决办法]
图片类型有jpg、gif、png等格式,目前不加response.setContentType("image/jpeg")的话都可以显示,加上了也确实没什么影响,
如果写死了jpeg而实际文件类型是gif或其他格式,如果是<img src=...>的方式使用,不会引起冲突,如果是另存为客户端本地文件,或<a href=xxx>方式引用这个URL,鼠标点击打开时,浏览器会根据
response.setContentType("image/bmp"); // bmp类型文件
response.setContentType("image/gif"); // gif类型文件
response.setContentType("image/jpeg"); // jpeg类型文件
response.setContentType("image/tiff"); // tif类型文件
response.setContentType("image/x-pcx"); // pcx类型文件
response.setContentType("text/xml"); // xml类型文件
response.setContentType("application/pdf"); // pdf类型文件
......
设置代码的不同,确定保存时默认的扩展名,或使用相应扩展名默认的打开软件来打开这个文件
-----------
不知道这样说楼主是否明白1些

response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
是禁止客户端缓存,是针对浏览器发送的协议头信息,建议对每次访问都需要动态更新的URL,都使用这些代码。
[解决办法]
如果对jpg类型,用设置时用了
response.setContentType("application/pdf"); // pdf类型文件

另存时会默认为.pdf 文件类型,打开时,会自动用 pdf reader来打开,但会失败
当然你另`存后再改扩展名为 .jpg,文件还是能正常使用的。

只是针对 windows 操作系统来说,服务器给了一个默认的设置,你不遵守这个规则,自己随便写,再通过改扩展名的方式,一样可以使用下载的文件(如果客户不怕麻烦、开发人员也不怕客户骂, 哈哈)。
[解决办法]
和验证码的产生原理一样,不过一个是随即产生数字,一个是随便选取图片url··
[解决办法]
学习。。。
[解决办法]
顶一下
[解决办法]
学习了,谢谢了
[解决办法]
学习了,谢谢各位高手
[解决办法]
进来学习学习!
[解决办法]
mark
[解决办法]
mark!
[解决办法]
最大的问题是缓存,其他皆是小节。

读书人网 >Java Web开发

热点推荐