当前位置: 首页 > 图文教程 > 网络编程 > JSP > Servlet实现动态图文结合输出

JSP
我认为JSP有问题(上)
我认为JSP有问题(下)
jsp“抓”网页代码的程序
关于在bean里面打印html的利弊看法
bean里面如何打印到html页面
jdbc3中的RowSet 接口规范
Apusic Application Server1.0中jsp源代码泄漏漏洞
Unify的eWave ServletExec拒绝服务漏洞
通过提交超长的GET请求导致IBM HTTP Server远程溢出
在HTTP请求中添加特殊字符导致暴露JSP源代码文件
Resin 1.2 重要源代码暴露漏洞
多中WEB服务器的通用JSp源代码暴露漏洞
Tomcat 暴露JSP文件内容
IBM WebSphere Application Server 暴露JSP文件内容
JRun 2.3.x 范例文件暴露站点安全信息
BEA WebLogic 暴露源代码漏洞
IBM WebSphere Application Server 3.0.2 存在暴露源代码漏洞
Tomcat 3.1 存在暴露网站路径问题
Sun Java Web Server 能让攻击者远程执行任意命令
Netscape 修复 JAVA 安全漏洞

JSP 中的 Servlet实现动态图文结合输出


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-04   浏览: 60 ::
收藏到网摘: n/a

   
内容: 
 
先看看我们要解决的问题 
HTML如何显示一张图片 
通过Servlet实现图文结合输出 
实际应用 
继续完善 
附录 
参考资料 
关于作者 
 
 
 
 
黄林榕([email protected])
深圳颖源科技
2001 年 11 月

构建动态网站,灵活性与美观经常会成为一个矛盾。网页设计师从视觉角度考虑,在许多地方采用了图片,有时甚至在动态输出的内容上使用了图片,比如网站的栏目、各类标题等。而这些内容往往要经常变换,需要WEB页面的脚本程序根据数据库中的内容实时输出。传统使用图片的形式显然无法胜任需要经常变换内容的位置,通常是采用折衷的办法,或降低对视觉效果的要求,让设计师改用文字设计,或要求维护人员不时根据实际内容重新制作并更换图片,等等。对此,本文将提供一种更为灵活的解决方案。
如果你是一个WEB开发者,或多或少会遇到这样一种情况:网页设计师在设计网页时,在需要动态输出内容的地方采用图片,如:


而"热点聚焦"这个名称,也许过一两天就要求改成"焦点访谈"等其它字样,到时不得不重新制作一张图片替代。而采用文字加背景,有时不易达到好的效果。采用表格背景图方式,需要精心调整表格的尺寸,而且其它的改动也会有意无意影响到它,需要小心调试。

本人在多个项目开发中遇到网页中需要动态图文结合输出情况,程序员和美工往往最终都是选择了回避和妥协,尽管通常影响不大,但毕竟与尽善尽美的追求有所差距。于是终于产生了本文的解决方法。

先看看我们要解决的问题
我们的问题可以简单总结为:有一张图片,如:


现在我们要动态地将文字比如"热点聚焦"输出到上面,并在网页上得到类似如下的显示:


HTML如何显示一张图片
在HMTL中显示一张图片很简单:<img src="bg.jpg" weight="153" height="25">。

另外我们还知道src属性中的文件类型并没有做限定,也就是说<img src="image.jsp">的写法也是合法的,同样引用Servlet:<img src="/imageServlet">的写法也是合法的,浏览器解析到该语句时,将向目标服务器发送一个HTTP请求。通过了解HTTP协议,可以知道,如果这时imageServlet做出Content-Type为image/jpeg的正确响应(可以通过设置contentType="images/jpeg"来实现),那么也将正确显示一张图片。这个原理也是实现将数据库中的图像数据显示到网页上所用的原理。

进一步利用这个原理,当向imageServlet请求图像时,imageServlet不是简单的发送原图像数据,而是先对原图像数据进行一定的处理,比如在原图片上面的指定位置加上文字,甚至对再做一些处理比如阴影、立体等,然后再将处理后的图像数据流发送出去,那么不就可以得到图文结合后的图像了吗?

根据以上分析,我们得到这样的实现方法:在<img>的src属性中调用实现上述功能的Servlet并传递相关的参数,如背景图片路径、输出文字、文字输出的位置、字体、大小等,由该Servlet进行图文处理,并返回处理后的图像数据,从而在网页上显示出加上文字的图像。

通过Servlet实现图文结合输出
下面根据上面的原理编写一个简单的Servlet实现代码,该Servlet能够根据传递的参数要求,将文字输出到图片上并向浏览器返回图文结合后的图像数据,并在调用的网页上显示出图文结合后的图像(注:该servlet仅实现了JPG格式图像文件的处理,不支持GIF):

package net.xdevelop.merge;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;

import java.awt.*;
import java.awt.image.*;
import com.sun.image.codec.jpeg.*;
import net.xdevelop.util.ParamUtil;

/**
 * 将文字用指定的字体,颜色和大小,嵌入指定图片的指定位置,调用参数:
 * text:     要嵌的文字
 * imageFile:  JPG图片的虚拟路径
 * x:      文字输出的起始X坐标位置
 * y:      文字输出的起始Y坐标位置
 * fontColor:  字体颜色(例fontColor=FFFFFF)
 * fontSize:  字体大小
 * fontStyle:  字体风格(斜体,粗体等)
 * fontName:  字体名称(如仿宋体,宋体等)
 */
public class TextIntoImage extends HttpServlet {
    private static final String CONTENT_TYPE = "image/jpeg;charset=GB2312";

    public void init() throws ServletException {
    }
    /** Process the HTTP Get request */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

        doPost(request,response);

    }
    //---------------------------------------------------------------------------------------------
    /** Process the HTTP Post request */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

        response.setContentType(CONTENT_TYPE);

        String text = "";               //要嵌的文字
        String imageFile = "";          //被嵌的图片的虚拟路径
        int x = 0;                      //坐标
        int y = 0;
        String fontColor = "";          //字体颜色
        int fontSize = 0;               //字体大小
        String fontStyle = "";          //字体风格(斜体,粗体等)
        String fontName = "";           //字体名称

        try {
            //取得参数(ParamUtil类请参看后面附的ParamUtil类代码)
            text = ParamUtil.getParameter(request,"text");
            imageFile = ParamUtil.getParameter(request,"imageFile");
            x = ParamUtil.getIntParameter(request,"x",0);
            y = ParamUtil.getIntParameter(request,"y",0);
            fontColor = ParamUtil.getParameter(request,"fontColor");
            fontSize = ParamUtil.getIntParameter(request,"fontSize",16);
            fontStyle = ParamUtil.getParameter(request,"fontStyle");
            fontName = ParamUtil.getParameter(request,"fontName");
        }
        catch(Exception e) {
            e.printStackTrace();
        }

        ServletOutputStream output=response.getOutputStream();

        if(imageFile.toLowerCase().endsWith(".jpeg")||imageFile.toLowerCase().endsWith(".jpg")) {
            imageFile = getServletContext().getRealPath(imageFile);
            InputStream imageIn = new FileInputStream(new File(imageFile));
            JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(imageIn);
            BufferedImage image = decoder.decodeAsBufferedImage();
            Graphics g=image.getGraphics();

            //设置颜色
            g.setColor(new Color(Integer.parseInt(fontColor,16)));

            //设置字体
            Font mFont = new Font(fontName,Font.PLAIN,fontSize);//默认字体
            if(fontStyle.equalsIgnoreCase("italic")) mFont=new Font(fontName,Font.ITALIC,fontSize);
            if(fontStyle.equalsIgnoreCase("bold")) mFont=new Font(fontName,Font.BOLD,fontSize);
            if(fontStyle.equalsIgnoreCase("plain")) mFont=new Font(fontName,Font.PLAIN,fontSize);
            g.setFont(mFont);

            //输出文字
            g.drawString(text,x,y);

            //输出数据流
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(output);
            encoder.encode(image);

            imageIn.close();
        }
        output.close();
    }
}//////////


 



上面获取参数的代码使用了一个工具类,它是扩展了request.getParameter()功能的一个类:package net.xdevelop.util;

import javax.servlet.*;

public class ParamUtil {
  /**
   * 获得request中指定名称的参数值,若有中文乱码问题请增加转码部分
   * @param request ServletRequest对象
   * @param paramName 参数名称
   * @return 如果该变量值存在则返回该值,否则返回""
   */
  public static String getParameter( ServletRequest request, String paramName ) {
    String temp = request.getParameter(paramName);
    if( temp != null && !temp.equals("") ) {
        //若有中文问题,在此添加转码代码,例:temp = new String(temp.getBytes("8859_1"), "GB2312");
        return temp;
    }
    else {
      return "";
    }
  }

  /**
   * 获得request中的int型参数值
   * @param request ServletRequest对象
   * @param paramName 参数名称
   * @param defaultNum 默认值,如果没有返回该值
   * @return 如果该参数值存在则返回其转换为int型的值,否则返回defaultNum
   */
  public static int getIntParameter( ServletRequest request, String paramName, int defaultNum ) {
    String temp = request.getParameter(paramName);
    if( temp != null && !temp.equals("") ) {
      int num = defaultNum;
      try {
          num = Integer.parseInt(temp);
      }
      catch( Exception ignored ) {
      }
      return num;
    }
    else {
      return defaultNum;
    }
  }
}///////////

 



实际应用

在web.xml中声明该Servlet <servlet>
  <servlet-name>textintoimage</servlet-name>
  <servlet-class>net.xdevelop.merge.TextIntoImage</servlet-class>
</servlet>

<servlet-mapping>
  <servlet-name>textintoimage</servlet-name>
  <url-pattern>/TextIntoImage</url-pattern>
</servlet-mapping>

 



将net.xdevelop.merge.TextIntoImage类和net.xdevelop.util.ParamUtil类放入WEB-INF/classes/ 
JSP页面调用,本例中要将bg.jpg文件放入根目录,示例代码: <img border="0" src="/TextIntoImage?text=热点聚焦&imageFile=/bg.jpg&x=20&y=20&fontColor=FFFFFF&fontStyle=bold&fontName=宋体&fontSize=16"> 
继续完善
到此可以暂告一个段落了。不过还有很多地方有待继续完善,例如:加入文字效果处理(阴影、立体、浮雕等),文字竖排,增加对GIF文件支持等。

附录
演示程序(demo.zip)

参考文献

2D Graphics and Imaging of JFC in the JDK(TM)SDK Documentation 


关于作者 
黄林榕,深圳颖源科技高级程序员,经济学学士。一年的J2EE开发经验,是企商平台可视化建站系统的主要设计与开发者,对JAVA及其可复用组件的开发有着浓厚兴趣,您可以在xdevelop.net网站上获得他最新开发的部分组件。