java fckeditor 上传图片_修改Fckeditor图片上传功能(java版)

本文介绍了如何针对Fckeditor 2.5版本的图片上传功能进行改造,解决中文乱码、上传Bug,并添加水印功能。通过创建新的Servlet和重写相关方法,将上传图片保存到服务器特定位置,避免工程下文件过大的问题,同时实现图片预览和水印添加功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Fckeditor默认是带图片上传的功能 但是这不能满足我们的要求 比如说有的版本的Fckeditor有中文乱码的问题,我用的这个Fckediotr上传图片还有Bug,另外也没办法给图片加水印,传上去的图片还是放在工程下的将来会导致图片越来越庞大,怎么办呢? 我们自己动手丰衣足食,把fckeditor改造成我们需要的.

我用的Fckeditor的jar包是2.5版本的 这个版本图片没有中文乱码 另外如果有中文乱码的问题我建议也不要把图片名称改为UUID名称,因为当用户把自己的图片传上去的时候 想点浏览在去找这张图片的时候 他发现上面的那么多的名字根本分不清哪个是他这次传上来的.有人会问那图片名字重复了怎么办呢?Fckeditor已经考虑到这个问题了 他检测到服务器上有这个名字的图片他会自动重命名.废话不多说了我们来看我是怎么干的.

我们要解决的几个问题

1.上传图片放到服务器的一个物理位置而不是工程下.

2.解决Fckeditor2.5版本中图片上传 没有flush的问题

3.增加水印功能.

Fckeditor低版本的时候我们需要重写一个Servlet 但是我发现这个版本图片上传功能是放在一个类下的而不是

旧版本中的ConnectorServlet.那既然需要重写一个类 而这个类呢有是ConnectorServlet中调用的那我们是不是得先重写ConnectorServlet 然后在重写这个类,然后再把自己写的ConnectorServlet配置到web.xml中呢?不用那么麻烦我不是那样做的 看下图我是怎么做的 ,并请大家自己思考为什么可以这么做.

6d99592c6ea926f2ac52ea48b096cccd.png

我在工程下建了和fckeditor相同的包结构然后把我需要重写的类从Fckeditor源代码中拷了过来

好了 我们开始修改吧

Dispatcher.java中doPost方法

UploadResponse doPost(final HttpServletRequest request) {

logger.debug("Entering Dispatcher#doPost");

//String type = null;

Context context = ThreadLocalData.getContext();

context.logBaseParameters();

UploadResponse uploadResponse = null;

// check permissions for user actions

if (!RequestCycleHandler.isEnabledForFileUpload(request))

uploadResponse = UploadResponse.getFileUploadDisabledError();

// check parameters

else if (!Command.isValidForPost(context.getCommandStr()))

uploadResponse = UploadResponse.getInvalidCommandError();

else if (!ResourceType.isValidType(context.getTypeStr()))

uploadResponse = UploadResponse.getInvalidResourceTypeError();

else if (!UtilsFile.isValidPath(context.getCurrentFolderStr()))

uploadResponse = UploadResponse.getInvalidCurrentFolderError();

else {

// call the Connector#fileUpload

ResourceType type = context.getDefaultResourceType();

FileItemFactory factory = new DiskFileItemFactory();

ServletFileUpload upload = new ServletFileUpload(factory);

try {

List items = upload.parseRequest(request);

// We upload just one file at the same time

FileItem uplFile = items.get(0);

// Some browsers transfer the entire source path not just the

// filename

String fileName = FilenameUtils.getName(uplFile.getName());

logger.debug("Parameter NewFile: {}", fileName);

// check the extension

if (type.isNotAllowedExtension(FilenameUtils

.getExtension(fileName)))

uploadResponse = UploadResponse.getInvalidFileTypeError();

// Secure image check (can't be done if QuickUpload)

else if (type.equals(ResourceType.IMAGE)

&& PropertiesLoader.isSecureImageUploads()

&& !UtilsFile.isImage(uplFile.getInputStream())) {

uploadResponse = UploadResponse.getInvalidFileTypeError();

} else {

String sanitizedFileName = UtilsFile

.sanitizeFileName(fileName);

//修改为UUID文件名称 我这里注释掉了 如下代码可以把上传的图片名称改为UUID

//sanitizedFileName = UUID.randomUUID().toString()+sanitizedFileName.substring(sanitizedFileName.lastIndexOf("."), sanitizedFileName.length());

logger.debug("Parameter NewFile (sanitized): {}",

sanitizedFileName);

String newFileName = connector.fileUpload(type, context

.getCurrentFolderStr(), sanitizedFileName, uplFile

.getInputStream());

String fileUrl = UtilsResponse.fileUrl(RequestCycleHandler

.getUserFilesPath(request), type, context

.getCurrentFolderStr(), newFileName);

//Fckeditor上传有两种 一种是上传图片 一种是上传附件

//如果是图片的话 我用这个action来预览图片

if(type.equals(ResourceType.IMAGE))

{

fileUrl = "tumbnail.action?fileName="+sanitizedFileName;

}

//如果是上传附件的话 用如下的action来下载附件

else if(type.equals(ResourceType.FILE)){

sanitizedFileName = URLEncoder.encode(sanitizedFileName, "utf-8");

fileUrl = request.getContextPath()+"/attachmentDownload.action?fileName="+sanitizedFileName;

}

if (sanitizedFileName.equals(newFileName))

uploadResponse = UploadResponse.getOK(fileUrl);

else {

uploadResponse = UploadResponse.getFileRenamedWarning(fileUrl, newFileName);

logger.debug("Parameter NewFile (renamed): {}",

newFileName);

}

}

uplFile.delete();

} catch (InvalidCurrentFolderException e) {

uploadResponse = UploadResponse.getInvalidCurrentFolderError();

} catch (WriteException e) {

uploadResponse = UploadResponse.getFileUploadWriteError();

} catch (IOException e) {

uploadResponse = UploadResponse.getFileUploadWriteError();

} catch (FileUploadException e) {

uploadResponse = UploadResponse.getFileUploadWriteError();

}

}

logger.debug("Exiting Dispatcher#doPost");

return uploadResponse;

}

AbstractLocalFileSystemConnector.java 中 fileUpload方法

public String fileUpload(final ResourceType type, final String currentFolder, final String fileName, final InputStream inputStream) throws InvalidCurrentFolderException, WriteException {

String absolutePath = getRealUserFilesAbsolutePath(RequestCycleHandler.getUserFilesAbsolutePath(ThreadLocalData.getRequest()));

File typeDir = getOrCreateResourceTypeDir(absolutePath, type);

File currentDir = new File(typeDir, currentFolder);

if (!currentDir.exists() || !currentDir.isDirectory())

throw new InvalidCurrentFolderException();

File newFile = new File(currentDir, fileName);

File fileToSave = UtilsFile.getUniqueFile(newFile.getAbsoluteFile());

OutputStream outputStream = null;

try {

outputStream = new FileOutputStream(fileToSave);

IOUtils.copyLarge(inputStream, outputStream);

} catch (IOException e) {

throw new WriteException();

} finally {

try {

if (outputStream != null) {

//这里解决这个版本中图片上传没有flush的bug

outputStream.flush();

IOUtils.closeQuietly(outputStream);

}

IOUtils.closeQuietly(inputStream);

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

String format = fileToSave.getName().substring(fileToSave.getName().lastIndexOf(".") + 1, fileToSave.getName().length());

//下面给图片加水印

//如果是图片的话 加水印

if (ImageUtils.isPicture(format)) {

ImageUtils.pressImage(servletContext.getRealPath("themes/cms/image/") +"\\"+ "sxgajj.png", newFile.getAbsoluteFile().getAbsolutePath());

}

return fileToSave.getName();

}

另外还有图片预览的action 和 加水印的代码

图片预览的action代码

public class FckImgPreviewAction {

private String fileName;

public String execute() {

if (fileName != null) {

//图片在服务器上的物理存放路径

String path = ResourceBundle.getBundle("sysConfig").getString("userFilePath.image");

File file = new File("/" + path + fileName);

HttpServletResponse resp = ServletActionContext.getResponse();

OutputStream os = null;

InputStream is = null;

if (file.exists()) {

try {

is = new FileInputStream(file);

os = resp.getOutputStream();

IOUtils.copyLarge(is, os);

} catch (IOException e) {

e.printStackTrace();

}finally{

try {

IOUtils.closeQuietly(is);

if(os != null)

{

os.flush();

IOUtils.closeQuietly(os);

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

return null;

}

public String getFileName() {

return fileName;

}

public void setFileName(String fileName) {

this.fileName = fileName;

}

}

/**

* @param pressImg 水印文件路径

* @param targetImg 目标文件路径

*/

public final static void pressImage(String pressImg, String targetImg) {

FileOutputStream out = null;

try {

File _file = new File(targetImg);

Image src = ImageIO.read(_file);

int wideth = src.getWidth(null);

int height = src.getHeight(null);

BufferedImage image = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB);

Graphics g = image.createGraphics();

g.drawImage(src, 0, 0, wideth, height, null);

// 水印文件

File _filebiao = new File(pressImg);

Image src_biao = ImageIO.read(_filebiao);

int wideth_biao = src_biao.getWidth(null);

int height_biao = src_biao.getHeight(null);

g.drawImage(src_biao, wideth - wideth_biao, height - height_biao, wideth_biao, height_biao, null);

// /

g.dispose();

out = new FileOutputStream(targetImg);

JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);

encoder.encode(image);

} catch (Exception e) {

e.printStackTrace();

}finally{

if(out!=null)

{

try {

out.flush();

out.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

还有个重要的类差点忘了  GetResponse.java  GetResponse方法

让fck在上传完图片后 fck图片预览图片url正确的显示

public GetResponse(Command command, ResourceType type,

String currentFolder, String constructedUrl) {

try {

DocumentBuilderFactory factory = DocumentBuilderFactory

.newInstance();

DocumentBuilder builder = factory.newDocumentBuilder();

document = builder.newDocument();

} catch (ParserConfigurationException e) {

throw new RuntimeException(e);

}

Element root = document.createElement("Connector");

document.appendChild(root);

root.setAttribute("command", command.getName());

root.setAttribute("resourceType", type.getName());

Element currentFolderElement = document.createElement("CurrentFolder");

currentFolderElement.setAttribute("path", currentFolder);

if(type.equals(ResourceType.IMAGE))

{

constructedUrl = "tumbnail.action?fileName=";

}

else if(type.equals(ResourceType.FILE)){

constructedUrl = "attachmentDownload.action?fileName=";

}

currentFolderElement.setAttribute("url", constructedUrl);

//System.out.println(constructedUrl);

root.appendChild(currentFolderElement);

}

ok了 看下效果

26e9002d3bba54e9a70a1e5dad336698.png

2bdb7e82a14af08c66af3312a4945bd4.png

54216edef15646fee30bb4c6e326846b.png

587035dc8538ad60ba2941fa8554f059.png

大小: 16.6 KB

5886edf163760a6390972ed30b126cf6.png

大小: 20 KB

7c272611ec289118e1d6961b57ab1063.png

大小: 40.1 KB

4b32312d4b75c0b86ac106c96c860205.png

大小: 86.2 KB

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2010-04-15 16:36

浏览 5541

评论

2 楼

beritha

2010-08-21

这个好抽象啊,初学者看不懂,博主请指教哈

1 楼

leoizumi

2010-05-14

学到东西了...谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值