Jive
提供了强大的论坛功能,但是有些功能离实际需求还是有一定的距离,例如论坛是用于信息交流讨论的场所。而信息不只是文字,有时还包括图片或一些
PDF
等类型的文件,那么如何在
Jive
中实现这样的功能呢?
6.1
图片上传处理
在
HTML
中,使用表单
Form
主要是用来向服务器提交数据,格式如下:
<
FORM ACTION="URL"
METHOD="GET|POST"
ENCTYPE="…" TARGET="..."
>
. . .
<
/FORM
>
enctype
指定了表单提交给服务器时的内容形式(
Content-Type
),默认值是
"application/x-www-form-urlencoded"
,这时,表单信息一般采用
URL
编码制。
但是,当向服务器传送图片或文件这样包含非
ASCII
字符或二进制数的数据时,根据
RFC1867
规定,就必须使用“
multipart/form-data
”内容类型。
其实无论是默认表单信息,还是图片文件,这些内容都是装载在
HTTP
协议的正文内容部分,都可以看成
HTTP
协议携带的对象,只是两种正文内容形式不一样。前者是
String
字符串类型,而后者则是一个通用的数据对象类型(
Object
)。在以后章节中将专门讨论
HTTP
协议装载数据对象的底层细节。
使用“
multipart/form-data
”上传文件的格式写法如下:
<
FORM ACTION="URL" METHOD="GET|POST" ENCTYPE=" multipart/form-data "
>
<INPUT TYPE
=
FILE NAME
=
file1>
<
/FORM
>
文件通过
HTTP
协议传送到服务器端后,需要在服务器端对该文件进行专门的接受。
HttpServletRequest
没有提供直接获取文件数据的方法,因此需要开发专门的服务器文件处理组件。
目前有两种上传文件处理组件:一种是基于完全
JSP
结构的,使用
JSP
来处理上传的文件,以
SmartUpload
(
http://www.jspsmart.com
)最常用;还有一种是完全的
JavaBeans
组件:
Cos
文件上传组件包(
http://www.servlets.com/cos/index.html
),
Cos
可以使用在
JSP
中,也可以使用在
Servlet
或
Servlet Filter
中。
由于在实际应用中,文件上传功能往往和其他正常表单参数一起混合使用,而不是独立使用的。因此,可以设定一个
Servlet
专门用来处理这类混合表单的请求,在将文件接受处理后,自动导向到处理表单正常参数的
JSP/Servlet
去处理。
表单调用示例如下:
<form action="<%=request.getContextPath()%>/multipartformserv"
method="post" enctype="multipart/form-data">
<input type="hidden" name="FORWARDNAME" value="login.jsp" >
<input type="file" name="file1" >
<input type="hidden" name="maxwidth" value="120" >
<input type="hidden" name="maxheight" value="60" >
<input type="text" name="username" >
<input type="text" name="password" >
</form>
在这个表单中,既有文件提交,也有
username
这样正常的参数需要提交,提交的
Servlet
名为
multipartformserv
。由
multipartformserv
来处理上传的文件,然后再自动转交到
FORWARDNAME
的值
login.jsp
进行
username
等正常参数的处理。
在表单中,如果设定
maxwidth
和
maxiheight
,那么表示如果上传的图片超过这个尺寸,服务器将缩小图片到这个尺寸。
编制一个专门用来统一处理
Jive
系统中所有文件处理的
Servlet
,这样有利于简化系统。编制
MultipartFormServ
如下:
public class MultipartFormServ extends HttpServlet {
static final private String CONTENT_TYPE = "text/html";
//
文件上传处理
private static MultipartFormHandle mf = MultipartFormHandle.getInstance();
//
文件上传后存放的临时目录
private String dirName;
private ServletContext context;
public void init() throws ServletException {
//
从
web.xml
中读取上传目录参数
dirName = mf.getUploaddir();
if (dirName == null) {
throw new ServletException("Please supply uploadDir parameter");
}
}
//
处理带有文件内容的请求
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
mf.init(dirName,request); //
调用文件上传处理器处理
//
得到
FORWARDNAME
参数值
String forward=mf.getForwardProgram();
if (forward.equals(""))
{
errorMessage("no forward program", response);
return;
}
String param=mf.getForwardProgramParam();
mf.clear();
//
引导分流到
forward
参数值进行其他文本参数处理
getServletConfig().getServletContext().
getRequestDispatcher("/"+forward+"?"+param).forward(request, response);
}catch (Exception Ex) {
throw new ServletException(Ex.getMessage());
}
}
图
3-8
上传文件处理框架
|
}
MultipartFormHandler
主要调用
Cos
组件处理上传文件,对上传文件图形大小进行处理,然后将图形搬迁到指定的目录;同时也将请求信号中的正常参数提取出来,以作为转发使用。
这样一个图形或文件上传系统已经形成了一个框架结构,可以重复使用在任何需要图片或文件上传处理的系统中,如图
3-8
所示。
图
3-8
中上传文件处理额
Servlet
相当于请求信号
Request
的一个过滤器,既然正常的
Request
处理机制不能从
Request
提取携带的文件,那么,使用一个过滤器先将文件提取出来,剩余的再通过正常
Request
处理机制去处理。
6.2
服务器端图形处理
Java
最初是以
Applet
等客户端图形处理为技术起点的,而本节讨论的是如何在
Servlet/JSP
中实现图形处理。
在
Jive
中,图片可以用来显示用户的头像,用户在上传自己头像图片时,该图片的大小可能不一,但是由于版面原因,显示的头像图片又有大小限制,那么就需要在用户上传图片时对图片大小做一个检查。如果超过规定大小,就进行一定的缩放处理。
缩放处理有两种方式:是在
HTML
显示时,使用
image
语法的
width
和
height
来
限制大小,但是这样做只是解决了表面问题,无法解决大字节图片传送到客户端带来的性能影响,这个图片因为是用户发言的头像,将会在每个帖子里面显示。如果
头像都是巨大图片,对帖子显示速度的影响是很大,因此必须在服务器端进行缩小后,再传送到客户端,这样提高了论坛系统性能。
服务器端的图形处理需要使用到
Java
的图形处理技术,而且图形处理是在服务器端的
Web
容器中进行的。和以往
Java
在客户端进行图形处理稍微有所不同,相同的是都要使用计算机的底层图形支持资源。
J2SE 1.4
提供新的增强的图形处理功能,
JDK1.4
中最新的
javax.imageio.ImageIO
对图片进行读写操作,而使用
java.awt.geom.AffineTransform
对图片进行尺寸缩放处理。
import java.io.File;
import java.awt.image.BufferedImage;
import java.awt.Image;
import java.awt.image.AffineTransformOp;
import javax.imageio.ImageIO;
import java.awt.geom.AffineTransform;
public class UploadImg{
/**
*
参数设置
* @param fromdir
图片的原始目录
* @param todir
处理后的图片存放目录
* @param imgfile
原始图片
* @param sysimgfile
处理后的图片文件名前缀
*/
public void init(String fromdir,String todir,String imgfile,String sysimgfile)
{
this.fromdir=fromdir;
this.todir=todir;
this.imgfile=imgfile;
this.sysimgfile=sysimgfile;
}
…
public boolean CreateThumbnail() throws Exception
{
//ext
是图片的格式
gif
、
JPG
或
png
String ext=""
double Ratio=0.0;
File oldFile = new File(fromdir,imgfile);
if (!F.isFile()) //
检查是否存在此图片文件
throw new Exception(F+" is not image file error in CreateThumbnail!");
//
首先判断上传的图片是
gif
还是
JPG ImageIO
,只能将
gif
转换为
png
if (isJpg(imgfile)){
ext="jpg";
}else{
ext="png";
}
File newFile = new File(todir,sysimgfile+"."+ext);
BufferedImage Bi = ImageIO.read(oldFile); //
读取原始图片
if ((Bi.getHeight()>120) || (Bi.getWidth()>120)){
if (Bi.getHeight()>Bi.getWidth())
Ratio = 120.0/Bi.getHeight();
else
Ratio = 120.0/Bi.getWidth();
}
//
进行图片转换
AffineTransformOp op =
new AffineTransformOp(AffineTransform.getScaleInstance(Ratio, Ratio), null);
Image itemp = op.filter(Bi, null);
try { //
写入转换后的图片
ImageIO.write((BufferedImage) itemp, ext, newFile);
}catch (Exception ex) {
throw new Exception(ex.getMessage());
}
return (true);
}
}
该类中由于使用到了
Java
的
AWT
,虽然没有实际显示,但
Linux
系统下需要
X11 Windows
的支持(安装
Linux
时需安装
XFree86
,
Linux
完全安装方式包括安装
XFree86
)。
该缩放功能是在图片上传到服务器后再进行的处理,可以对
JPG
进行缩小放大;对上传是
GIF
的图片,缩放后变成
PNG
图片格式文件。