springboot+ueditor+前后端分离

  • 简介
  • 1. 官网下载ueditor资源,完整版
  • 2. 把相应文件拷贝到前端项目(net,php,jsp文件夹这里用不到)
  • 3. 把jsp下面的源码,以及config.json文件拷贝到后台项目
  • 4. 修改前台配置
  • 4.1 页面
  • 4.2 config.js路径配置
  • 4.3 修改ueditor.config.js
  • 4.4 修改ueditor.all.js
  • 5. 修改后台配置
  • 5.1 配置application-dev.yml中路径
  • 5.2 SystemConfig工具类读取dev配置文件中的路径
  • 5.3 修改ConfigManager
  • 5.4 修改BinaryUploader中的save方法
  • 5.5 修改config.json
  • 5.6UeditorController
  • 5.7 pom文件添加相关依赖
  • 5.8 LocalUploader
  • 5.9 IUploader
  • 5.10 FileUtil
  • 5.11 DateUtil
  • 6. bug汇总
  • 6.1 单图上传提示"上传错误",但是图片已经上传成功


简介

  • 项目采用前后端分离,故通过jsp+java的方式实现UEditor的集成

1. 官网下载ueditor资源,完整版

2. 把相应文件拷贝到前端项目(net,php,jsp文件夹这里用不到)

java判断当前时间是否是八点到九点 java判断时间格式是否为mmss_上传

3. 把jsp下面的源码,以及config.json文件拷贝到后台项目

java判断当前时间是否是八点到九点 java判断时间格式是否为mmss_上传_02

4. 修改前台配置

4.1 页面

<script type="text/javascript" src="lib/config.js"></script>
<script type="text/javascript" charset="utf-8" src="lib/ueditor/1.4.3/ueditor.config.js"></script>
<script type="text/javascript" charset="utf-8" src="lib/ueditor/1.4.3/ueditor.all.js"></script>
<script type="text/javascript" charset="utf-8" src="lib/ueditor/1.4.3/lang/zh-cn/zh-cn.js"></script>
<div class="formControls col-xs-8">
    <input name="text" id="text" value="" type="hidden"/>
     <script id="editor" type="text/plain"></script>
</div>

初始化

<script>
   var content = "";
   var editor;
   UE.Editor.prototype._bkGetActionUrl = UE.Editor.prototype.getActionUrl;
   UE.Editor.prototype.getActionUrl = function(action) {
   	//只有在自己写后台代码实现的时候才需要这一块儿
       if (action == 'uploadimage' /*|| action == 'uploadscrawl'*/ ) {
           return domainDb + "operate-db/ueditor/uploadimage";
       } else {
           return this._bkGetActionUrl.call(this, action);
       }
   }
   $(function () {
       $("input[name='operator']").val(userName);
       editor = UE.getEditor('editor');    //获取富文本
       //初始化编辑器 (该处用于设置编辑器回显值)
       editor.ready(function () {
           editor.setContent(content);
       });
   })
   </script>

4.2 config.js路径配置

//UEditor图片上传用到
var domainPage = "http://localhost:63342/operate-page/";
var domainDb = "http://localhost:8081/";

4.3 修改ueditor.config.js

java判断当前时间是否是八点到九点 java判断时间格式是否为mmss_ide_03

4.4 修改ueditor.all.js

//设置图片最大宽度,以免撑出滚动条
 'img{max-width:100%;}' +

java判断当前时间是否是八点到九点 java判断时间格式是否为mmss_json_04

5. 修改后台配置

5.1 配置application-dev.yml中路径

systemconfig:
##服务器路径
#static_server_path: /usr/local/operate/static
#static_server_domain: http://118.126.142.184:8080/static
#config_json_path: /usr/local/tomcat-1/webapps/operate-db/WEB-INF/classes/config.json
##本地路径
##上传路径
static_server_path: D:\java\apache-tomcat-7.0.91\webapps\tenxSteel4\pages\static
##读取路径
static_server_domain: http://localhost:8085/tenxSteel4/pages/static
config_json_path: src/main/resources/config.json

5.2 SystemConfig工具类读取dev配置文件中的路径

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import tenx.operate.common.util.StringUtils;

import java.util.ResourceBundle;

@Configuration
public class SystemConfig {
   // 抽数据URL
  	public static String URL;
   /**
   * 数据库名称
   */
   public static String STATIC_SEVER_PATH;
   public static String STATIC_SEVER_DOMAIN;
   public static String CONFIG_JSON_PATH;
   @Value("${systemconfig.static_server_path}")
   public void setStaticServerPath(String staticServerPath) {
       SystemConfig.STATIC_SEVER_PATH = staticServerPath;
   }

   @Value("${systemconfig.config_json_path}")
   public void setConfigJsonPath(String configJsonPath) { SystemConfig.CONFIG_JSON_PATH = configJsonPath;
   }

   @Value("${systemconfig.static_server_domain}")
   public void setStaticSeverDomain(String staticServerDomain) { SystemConfig.STATIC_SEVER_DOMAIN = staticServerDomain;
   }

   /**
    * 转换静态资源路径
    * @param path
    * @return
    */
   public static String convertToUrl(String path){

       if(StringUtils.isNullOrEmpty(path)){
           return path;
       }
       return path.replaceAll("fs:",STATIC_SEVER_DOMAIN);
   }

   public static String convertToFile(String path){

       if(StringUtils.isNullOrEmpty(path)){
           return path;
       }
       return path.replaceAll("fs:",STATIC_SEVER_PATH);
   }
}

5.3 修改ConfigManager

  • 修改rootPath为dev中配置的图片上传路径
    originalPath为dev中配置的config.json所在的路径
    注:Linux为/usr/local/tomcat-1/webapps/operate-db/WEB-INF/classes/config.json
    本地环境为:src/main/resources/config.json

5.4 修改BinaryUploader中的save方法

  • 如果不做修改的话上传会报错(未找到上传数据)
    原因:SpringMVC框架对含字节流的request进行了处理,此处传的是处理过的request,故获取不到字节流。
    故修改原有代码,采用SpringMVC框架的解析器multipartResolver
public static final State save(HttpServletRequest request, Map<String, Object> conf) {
	// FileItemStream fileStream = null;
	// boolean isAjaxUpload = request.getHeader( "X_Requested_With" ) != null;

	if (!ServletFileUpload.isMultipartContent(request)) {
		return new BaseState(false, AppInfo.NOT_MULTIPART_CONTENT);
	}

	// ServletFileUpload upload = new ServletFileUpload(
	// 	new DiskFileItemFactory());
	//
	// if ( isAjaxUpload ) {
	//     upload.setHeaderEncoding( "UTF-8" );
	// }

	try {
		// FileItemIterator iterator = upload.getItemIterator(request);
		//
		// while (iterator.hasNext()) {
		// 	fileStream = iterator.next();
		//
		// 	if (!fileStream.isFormField())
		// 		break;
		// 	fileStream = null;
		// }
		//
		// if (fileStream == null) {
		// 	return new BaseState(false, AppInfo.NOTFOUND_UPLOAD_DATA);
		// }
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		MultipartFile multipartFile = multipartRequest.getFile(conf.get("fieldName").toString());
		if(multipartFile==null){
			return new BaseState(false, AppInfo.NOTFOUND_UPLOAD_DATA);
		}

		String savePath = (String) conf.get("savePath");
		//String originFileName = fileStream.getName();
		String originFileName = multipartFile.getOriginalFilename();
		String suffix = FileType.getSuffixByFilename(originFileName);

		originFileName = originFileName.substring(0,
				originFileName.length() - suffix.length());
		savePath = savePath + suffix;

		long maxSize = ((Long) conf.get("maxSize")).longValue();

		if (!validType(suffix, (String[]) conf.get("allowFiles"))) {
			return new BaseState(false, AppInfo.NOT_ALLOW_FILE_TYPE);
		}

		savePath = PathFormat.parse(savePath, originFileName);

		String physicalPath = (String) conf.get("rootPath") + savePath;

		//InputStream is = fileStream.openStream();
		InputStream is = multipartFile.getInputStream();
		State storageState = StorageManager.saveFileByInputStream(is,
				physicalPath, maxSize);
		is.close();

		if (storageState.isSuccess()) {
			storageState.putInfo("url", PathFormat.format(savePath));
			storageState.putInfo("type", suffix);
			storageState.putInfo("original", originFileName + suffix);
		}

		return storageState;
		// } catch (FileUploadException e) {
		// 	return new BaseState(false, AppInfo.PARSE_REQUEST_ERROR);
	} catch (IOException e) {
	}
	return new BaseState(false, AppInfo.IO_ERROR);
}

5.5 修改config.json

/* 前后端通信相关的配置,注释只允许使用多行方式 */
{
   /*服务器路径:http://118.126.142.184:8080/static*/
   /*本地路径:http://localhost:8085/tenxSteel4/pages/static*/
   /* 上传图片配置项 */
   "imageActionName": "uploadimage", /* 执行上传图片的action名称 */
   "imageFieldName": "upfile", /* 提交的图片表单名称 */
   "imageMaxSize": 2048000, /* 上传大小限制,单位B */
   "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
   "imageCompressEnable": true, /* 是否压缩图片,默认是true */
   "imageCompressBorder": 600, /* 图片压缩最长边限制 */
   "imageInsertAlign": "none", /* 插入的图片浮动方式 */
   "imageUrlPrefix": "http://localhost:8085/tenxSteel4/pages/static", /* 图片访问路径前缀 */
   "imagePathFormat": "/attachment/image/{yyyy}/{mm}/{dd}/{hh}/{ii}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
   /* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */
   /* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */
   /* {time} 会替换成时间戳 */
   /* {yyyy} 会替换成四位年份 */
   /* {yy} 会替换成两位年份 */
   /* {mm} 会替换成两位月份 */
   /* {dd} 会替换成两位日期 */
   /* {hh} 会替换成两位小时 */
   /* {ii} 会替换成两位分钟 */
   /* {ss} 会替换成两位秒 */
   /* 非法字符 \ : * ? " < > | */
   /* 具请体看线上文档: fex.baidu.com/ueditor/#use-format_upload_filename */

   /* 涂鸦图片上传配置项 */
   "scrawlActionName": "uploadscrawl", /* 执行上传涂鸦的action名称 */
   "scrawlFieldName": "upfile", /* 提交的图片表单名称 */
   "scrawlPathFormat": "/attachment/image/{yyyy}/{mm}/{dd}/{hh}/{ii}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
   "scrawlMaxSize": 2048000, /* 上传大小限制,单位B */
   /*"scrawlUrlPrefix": "http://localhost:8085/tenxSteel4/pages/tenxSteel4/pages/static/",*/ /* 图片访问路径前缀 */
   "scrawlUrlPrefix": "http://localhost:8085/tenxSteel4/pages/static", /* 图片访问路径前缀 */
   "scrawlInsertAlign": "none",

   /* 截图工具上传 */
   "snapscreenActionName": "uploadimage", /* 执行上传截图的action名称 */
   "snapscreenPathFormat": "/static/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
   "snapscreenUrlPrefix": "http://localhost:8085/tenxSteel4/pages/static", /* 图片访问路径前缀 */
   "snapscreenInsertAlign": "none", /* 插入的图片浮动方式 */

   /* 抓取远程图片配置 */
   "catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"],
   "catcherActionName": "catchimage", /* 执行抓取远程图片的action名称 */
   "catcherFieldName": "source", /* 提交的图片列表表单名称 */
   "catcherPathFormat": "/attachment/image/{yyyy}/{mm}/{dd}/{hh}/{ii}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
   "catcherUrlPrefix": "http://localhost:8085/tenxSteel4/pages/static", /* 图片访问路径前缀 */
   "catcherMaxSize": 2048000, /* 上传大小限制,单位B */
   "catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 抓取图片格式显示 */

   /* 上传视频配置 */
   "videoActionName": "uploadvideo", /* 执行上传视频的action名称 */
   "videoFieldName": "upfile", /* 提交的视频表单名称 */
   "videoPathFormat": "/attachment/image/{yyyy}/{mm}/{dd}/{hh}/{ii}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
   "videoUrlPrefix": "http://localhost:8085/tenxSteel4/pages/static", /* 视频访问路径前缀 */
   "videoMaxSize": 102400000, /* 上传大小限制,单位B,默认100MB */
   "videoAllowFiles": [
       ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
       ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"], /* 上传视频格式显示 */

   /* 上传文件配置 */
   "fileActionName": "uploadfile", /* controller里,执行上传视频的action名称 */
   "fileFieldName": "upfile", /* 提交的文件表单名称 */
   "filePathFormat": "/attachment/image/{yyyy}/{mm}/{dd}/{hh}/{ii}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
   "fileUrlPrefix": "http://localhost:8085/tenxSteel4/pages/static", /* 文件访问路径前缀 */
   "fileMaxSize": 51200000, /* 上传大小限制,单位B,默认50MB */
   "fileAllowFiles": [
       ".png", ".jpg", ".jpeg", ".gif", ".bmp",
       ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
       ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
       ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
       ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
   ], /* 上传文件格式显示 */

   /* 列出指定目录下的图片 */
   "imageManagerActionName": "listimage", /* 执行图片管理的action名称 */
   /*"imageManagerListPath": "/static/upload/image/",*/ /* 指定要列出图片的目录 */
   "imageManagerListPath": "/attachment/image/{yyyy}/{mm}/{dd}/{hh}/{ii}/{time}{rand:6}", /* 指定要列出图片的目录 */
   "imageManagerListSize": 20, /* 每次列出文件数量 */
   "imageManagerUrlPrefix": "http://localhost:8085/tenxSteel4/pages/static", /* 图片访问路径前缀 */
   "imageManagerInsertAlign": "none", /* 插入的图片浮动方式 */
   "imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 列出的文件类型 */

   /* 列出指定目录下的文件 */
   "fileManagerActionName": "listfile", /* 执行文件管理的action名称 */
   /*"fileManagerListPath": "/static/upload/file/",*/ /* 指定要列出文件的目录 */
   "fileManagerListPath": "/attachment/image/{yyyy}/{mm}/{dd}/{hh}/{ii}/{time}{rand:6}", /* 指定要列出文件的目录 */
   "fileManagerUrlPrefix": "http://localhost:8085/tenxSteel4/pages/static", /* 文件访问路径前缀 */
   "fileManagerListSize": 20, /* 每次列出文件数量 */
   "fileManagerAllowFiles": [
       ".png", ".jpg", ".jpeg", ".gif", ".bmp",
       ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
       ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
       ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
       ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
   ] /* 列出的文件类型 */
}

5.6UeditorController

package tenx.operate.db.controller;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;

import com.baidu.ueditor.ActionEnter;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import tenx.operate.db.config.SystemConfig;
import tenx.operate.db.config.upload.IUploader;

/**
 * @author: dyf
 * @version: v1.0
 * @date:2019/4/9 18:10
 */
@Controller
@CrossOrigin
@RequestMapping("/ueditor")
public class UeditorController {
    @Autowired
    private IUploader uploader;

    @RequestMapping("/config")
    public void config(HttpServletRequest request,HttpServletResponse response) throws UnsupportedEncodingException, JSONException{
        response.setContentType("application/json");
        String rootPath = request.getSession().getServletContext().getRealPath("/");
        try {
            //
            ActionEnter actionEnter = new ActionEnter(request, rootPath);
            String exec=actionEnter.exec();
            PrintWriter writer = response.getWriter();
            writer.write(exec);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        };
    }
   @RequestMapping("/uploadimage")
   @ResponseBody
   public Map<String,Object> uploadImage(HttpServletRequest request, @RequestParam(value = "upfile",required = true) MultipartFile multipartFile){
       Map<String,Object> res = new HashMap<>();
       try{
           //封装的图片上传方法
           String path = this.uploader.upload(multipartFile.getInputStream(), SystemConfig.STATIC_SEVER_PATH,"image",
                   multipartFile.getOriginalFilename());
           String path1 = SystemConfig.convertToUrl(path);
           res.put("url", path1);//上传的图片路径
           res.put("state", "SUCCESS");
           res.put("title", multipartFile.getOriginalFilename());
           res.put("original", multipartFile.getOriginalFilename());
           return res ;
       }catch(Exception e){
           e.printStackTrace();
           return res;
       }
   }
}

5.7 pom文件添加相关依赖

<!-- 上传组件包 -->
   <dependency>
       <groupId>commons-fileupload</groupId>
       <artifactId>commons-fileupload</artifactId>
       <version>1.3.1</version>
   </dependency>
   <dependency>
       <groupId>commons-io</groupId>
       <artifactId>commons-io</artifactId>
       <!--<version>1.3.2</version>-->
       <version>2.4</version>
   </dependency>
   <dependency>
       <groupId>commons-codec</groupId>
       <artifactId>commons-codec</artifactId>
       <version>1.9</version>
   </dependency>
   <dependency>
       <groupId>org.json</groupId>
       <artifactId>json</artifactId>
       <version>20180813</version>
   </dependency>

5.8 LocalUploader

import org.springframework.stereotype.Service;
import tenx.operate.common.util.DateUtil;
import tenx.operate.common.util.FileUtil;
import tenx.operate.common.util.StringUtils;

import java.io.InputStream;
import java.util.Calendar;
import java.util.Date;

/**
 * 文件上传具体实现类
 */
@Service("uploader")
public class LocalUploader implements IUploader {
    @Override
    public String upload(InputStream stream,String static_server_path, String subFolder, String fileName) {
        /**
         * 参数校验
         */
        if(stream==null || subFolder == null){
            throw new IllegalArgumentException("file or filename object is null");
        }
        if(!FileUtil.isAllowUpImg(fileName)){
            throw new IllegalArgumentException("不被允许的上传文件类型");
        }
        /**
         * 组合文件名
         */
        String ext = FileUtil.getFileExt(fileName);
        fileName = DateUtil.toString(new Date(), "mmss") + StringUtils.getRandStr(4) + "." + ext;
        String filePath =  static_server_path + "/attachment/";
        if(subFolder!=null){
            filePath+=subFolder +"/";
        }
        String timePath=this.getTimePath();
        String path  ="fs:"+ "/attachment/" +(subFolder==null?"":subFolder)+"/"+timePath+"/"+fileName;
        filePath +=timePath;
        filePath += fileName;
        /**
         * 写入文件
         */
        FileUtil.write(stream, filePath);
        return path;
    }
    /**
     * 上传app
     */
    @Override
    public String uploadApk(InputStream stream,String static_server_path,String subFolder,
                            String fileName) {
        /**
         * 参数校验
         */
        if(stream==null){
            throw new IllegalArgumentException("file or filename object is null");
        }
        if(subFolder == null){
            throw new IllegalArgumentException("subFolder is null");
        }

        // String name = null;
        String filePath = "";
        // String ext = FileUtil.getFileExt(fileName);
        // name = DateUtil.toString(new Date(), "mmss") + StringUtils.getRandStr(4) + "." + ext;

        filePath = static_server_path+ "/attachment/";
        if(subFolder!=null){
            filePath+=subFolder +"/";
        }
        String timePath=this.getTimePath();
        String path  ="fs:"+ "/attachment/" +(subFolder==null?"":subFolder)+"/"+timePath+"/"+fileName;
        filePath += timePath;
        filePath += fileName;
        FileUtil.createFile(stream, filePath);
        return path;
    }
    private String getTimePath(){
        Calendar now = Calendar.getInstance();
        int year=now.get(Calendar.YEAR);
        int month=now.get(Calendar.MONTH) + 1;
        int date=now.get(Calendar.DAY_OF_MONTH);
        //Calendar.HOUR 12小时制  Calendar.DAY_OF_MONTH 24小时制
        int hour=now.get(Calendar.HOUR_OF_DAY);
        int minute=now.get(Calendar.MINUTE);
        String filePath="";
        if(year!=0){
            filePath+=year+"/";
        }
        if(month!=0){
            filePath+=(month<10?("0"+month):month)+"/";
        }
        if(date!=0){
            filePath+=(date<10?("0"+date):date)+"/";
        }
        if(hour!=0){
            filePath+=(hour<10?("0"+hour):hour)+"/";
        }
        if(minute!=0){
            filePath+=(minute<10?("0"+minute):minute)+"/";
        }
        return  filePath;
    }
}

5.9 IUploader

public interface IUploader {
   /**
    *
    * @param stream	文件流
    * @param  static_server_path 地址
    * @param subFolder	子文件夹
    * @param fileName	 图片名称
    * @return
    */
   public String upload(InputStream stream, String static_server_path, String subFolder, String fileName);
   /**
    * 上传app安装包
    * @param stream 文件流
    * @param static_server_path 地址
    * @param subFolder 子文件夹
    * @param fileName 文件名称
    * @return
    */
   public String uploadApk(InputStream stream, String static_server_path, String subFolder, String fileName);
}

5.10 FileUtil

import org.springframework.web.multipart.MultipartFile;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import org.apache.commons.io.FileUtils;
/**
 * 上传工具类
 */
public class FileUtil {

    private FileUtil() {
    }

    public static BufferedImage toBufferedImage(Image image) {
        if (image instanceof BufferedImage) {
            return (BufferedImage) image;
        }

        // This code ensures that all the pixels in the image are loaded
        image = new ImageIcon(image).getImage();

        // Determine if the image has transparent pixels; for this method's
        // implementation, see e661 Determining If an Image Has Transparent
        // Pixels
        // boolean hasAlpha = hasAlpha(image);

        // Create a buffered image with a format that's compatible with the
        // screen
        BufferedImage bimage = null;
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        try {
            // Determine the type of transparency of the new buffered image
            int transparency = Transparency.OPAQUE;
			/*
			 * if (hasAlpha) { transparency = Transparency.BITMASK; }
			 */

            // Create the buffered image
            GraphicsDevice gs = ge.getDefaultScreenDevice();
            GraphicsConfiguration gc = gs.getDefaultConfiguration();
            bimage = gc.createCompatibleImage(image.getWidth(null),image.getHeight(null), transparency);
        } catch (HeadlessException e) {
            // The system does not have a screen
        } catch (Exception e){
            e.printStackTrace();
        }

        if (bimage == null) {
            // Create a buffered image using the default color model
            int type = BufferedImage.TYPE_INT_RGB;
            // int type = BufferedImage.TYPE_3BYTE_BGR;//by wang
			/*
			 * if (hasAlpha) { type = BufferedImage.TYPE_INT_ARGB; }
			 */
            bimage = new BufferedImage(image.getWidth(null),image.getHeight(null), type);
        }

        // Copy image to buffered image
        Graphics g = bimage.createGraphics();

        // Paint the image onto the buffered image
        g.drawImage(image, 0, 0, null);
        g.dispose();

        return bimage;
    }


    public static void createFile(InputStream in, String filePath) {
        if(in==null) throw new RuntimeException("create file error: inputstream is null");
        int potPos = filePath.lastIndexOf('/') + 1;
        String folderPath = filePath.substring(0, potPos);
        createFolder(folderPath);
        FileOutputStream outputStream = null;
        try {
            outputStream = new FileOutputStream(filePath);
            byte[] by = new byte[1024];
            int c;
            while ((c = in.read(by)) != -1) {
                outputStream.write(by, 0, c);
            }
        } catch (IOException e) {
            e.getStackTrace().toString();
        }
        try {
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 是否是允许上传文件
     *
     * @param logoFileName
     * @return
     */
    public static boolean isAllowUp(String logoFileName) {
        logoFileName = logoFileName.toLowerCase();
        String allowTYpe = "gif,jpg,jpeg,bmp,swf,png,rar,doc,docx,xls,xlsx,pdf,zip,ico,txt,mp4";
        if (!logoFileName.trim().equals("") && logoFileName.length() > 0) {
            String ex = logoFileName.substring(logoFileName.lastIndexOf(".") + 1, logoFileName.length());
			//return allowTYpe.toString().indexOf(ex) >= 0;
            //lzf edit 20110717
            //解决只认小写问题
            //同时加入jpeg扩展名/png扩展名
            return allowTYpe.toUpperCase().indexOf(ex.toUpperCase()) >= 0;
        } else {
            return false;
        }
    }
    /**
     * 是否是允许上传的图片
     * @param imgFileName
     * @return
     */
    public static boolean isAllowUpImg(String imgFileName){
        imgFileName = imgFileName.toLowerCase();
        String allowTYpe = "jpg,png,jpeg";
        if (!imgFileName.trim().equals("") && imgFileName.length() > 0) {
            String ex = imgFileName.substring(imgFileName.lastIndexOf(".") + 1, imgFileName.length());
            return allowTYpe.toUpperCase().indexOf(ex.toUpperCase()) >= 0;
        } else {
            return false;
        }
    }
    /**
     * 是否是允许上传app安装包
     * @param apkFileName
     * @return
     */
    public static boolean isAllowUpApk(String apkFileName){
        apkFileName = apkFileName.toLowerCase();
        String allowTYpe = "apk";
        if (!apkFileName.trim().equals("") && apkFileName.length() > 0) {
            String ex = apkFileName.substring(apkFileName.lastIndexOf(".") + 1, apkFileName.length());
            return allowTYpe.toUpperCase().indexOf(ex.toUpperCase()) >= 0;
        } else {
            return false;
        }
    }
    /**
     * 是否是允许上传Excel
     *
     * @param logoFileName
     * @return
     */
    public static boolean isAllowUpExcel(String logoFileName) {
        logoFileName = logoFileName.toLowerCase();
        String allowTYpe = "xls";
        if (!logoFileName.trim().equals("") && logoFileName.length() > 0) {
            String ex = logoFileName.substring(logoFileName.lastIndexOf(".") + 1, logoFileName.length());
			return allowTYpe.toString().indexOf(ex) >= 0;
            //lzf edit 20110717
            //解决只认小写问题
            //同时加入jpeg扩展名/png扩展名
            return allowTYpe.toUpperCase().indexOf(ex.toUpperCase()) >= 0;
        } else {
            return false;
        }
    }
    /**
     * 把内容写入文件
     *
     * @param filePath
     * @param fileContent
     */
    public static void write(String filePath, String fileContent) {

        try {
            FileOutputStream fo = new FileOutputStream(filePath);
            OutputStreamWriter out = new OutputStreamWriter(fo, "UTF-8");

            out.write(fileContent);

            out.close();
        } catch (IOException ex) {

            System.err.println("Create File Error!");
            ex.printStackTrace();
        }
    }


    /**
     * 将inputstream写入文件
     * @param file 文件
     * @param path 要写入的文件路径
     */
    public static void write(MultipartFile file, String path){
        try {
            FileUtils.copyInputStreamToFile(file.getInputStream(), new File(path));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    /**
     * 将inputstream写入文件
     * @param stream 文件流
     * @param path 要写入的文件路径
     */
    public static void write(InputStream stream,String path){
        try {
            FileUtils.copyInputStreamToFile(stream, new File(path));
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    /**
     * 读取文件内容 默认是UTF-8编码
     *
     * @param filePath
     * @return
     */
    public static String read(String filePath, String code) {
        if (code == null || code.equals("")) {
            code = "UTF-8";
        }
        String fileContent = "";
        File file = new File(filePath);
        try {
            InputStreamReader read = new InputStreamReader(new FileInputStream(
                    file), code);
            BufferedReader reader = new BufferedReader(read);
            String line;
            while ((line = reader.readLine()) != null) {
                fileContent = fileContent + line + "\n";
            }
            read.close();
            read = null;
            reader.close();
            read = null;
        } catch (Exception ex) {
            ex.printStackTrace();
            fileContent = "";
        }
        return fileContent;
    }

    /**
     * 删除文件或文件夹
     *
     * @param filePath
     */
    public static void delete(String filePath) {
        try {
            File file = new File(filePath);
            if (file.exists()){
                if(file.isDirectory()){
                    FileUtils.deleteDirectory(file);
                }else{
                    file.delete();
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static boolean exist(String filepath) {
        File file = new File(filepath);

        return file.exists();
    }

    /**
     * 创建文件夹
     *
     * @param filePath
     */
    public static void createFolder(String filePath) {
        try {
            File file = new File(filePath);
            if (!file.exists()) {
                file.mkdirs();
            }
        } catch (Exception ex) {
            System.err.println("Make Folder Error:" + ex.getMessage());
        }
    }

    /**
     * 重命名文件、文件夹
     * @param from
     * @param to
     */
    public static void renameFile(String from, String to) {
        try {
            File file = new File(from);
            if(file.exists()){
                file.renameTo(new File(to));
            }
        }catch (Exception ex) {
            System.err.println("Rename File/Folder Error:" + ex.getMessage());
        }
    }

    /**
     * 得到文件的扩展名
     *
     * @param fileName
     * @return
     */
    public static String getFileExt(String fileName) {

        int potPos = fileName.lastIndexOf('.') + 1;
        String type = fileName.substring(potPos, fileName.length());
        return type;
    }

    /**
     * 通过File对象创建文件
     *
     * @param file
     * @param filePath
     */
    public static void createFile(File file, String filePath) {
        int potPos = filePath.lastIndexOf('/') + 1;
        String folderPath = filePath.substring(0, potPos);
        createFolder(folderPath);
        FileOutputStream outputStream = null;
        FileInputStream fileInputStream = null;
        try {
            outputStream = new FileOutputStream(filePath);
            fileInputStream = new FileInputStream(file);
            byte[] by = new byte[1024];
            int c;
            while ((c = fileInputStream.read(by)) != -1) {
                outputStream.write(by, 0, c);
            }
        } catch (IOException e) {
            e.getStackTrace().toString();
        }
        try {
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            fileInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static String readFile(String resource) {
        InputStream stream = getResourceAsStream(resource);
        String content = readStreamToString(stream);

        return content;

    }

    public static InputStream getResourceAsStream(String resource) {
        String stripped = resource.startsWith("/") ? resource.substring(1)
                : resource;

        InputStream stream = null;
        ClassLoader classLoader = Thread.currentThread()
                .getContextClassLoader();
        if (classLoader != null) {
            stream = classLoader.getResourceAsStream(stripped);

        }

        return stream;
    }

    public static String readStreamToString(InputStream stream) {
        String fileContent = "";

        try {
            InputStreamReader read = new InputStreamReader(stream, "utf-8");
            BufferedReader reader = new BufferedReader(read);
            String line;
            while ((line = reader.readLine()) != null) {
                fileContent = fileContent + line + "\n";
            }
            read.close();
            read = null;
            reader.close();
            read = null;
        } catch (Exception ex) {
            fileContent = "";
        }
        return fileContent;
    }

    /**
     * delete file folder
     *
     * @param path
     */
    public static void removeFile(File path) {

        if (path.isDirectory()) {
            try {
                FileUtils.deleteDirectory(path);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    public static void copyFile(String srcFile,String destFile){
        try {
            if(FileUtil.exist(srcFile)){
                FileUtils.copyFile(new File(srcFile),new File( destFile ));
            }
        } catch (IOException e) {

            e.printStackTrace();
        }
    }

    public static void copyFolder(String sourceFolder, String destinationFolder)
    {
        System.out.println("copy " + sourceFolder + " to " + destinationFolder);
        try{
            File sourceF = new File(sourceFolder);
            if (sourceF.exists())
                FileUtils.copyDirectory(new File(sourceFolder), new File(
                        destinationFolder));
        }catch(Exception e){
            e.printStackTrace();
            throw new RuntimeException("copy file error");
        }
    }


    /**
     * 拷贝源文件夹至目标文件夹
     * 只拷贝新文件
     * @param sourceFolder
     * @param targetFolder
     */
    public static void copyNewFile(String sourceFolder, String targetFolder){
        try{
            File sourceF = new File(sourceFolder);

            if(!targetFolder.endsWith("/")) targetFolder=targetFolder+"/";

            if (sourceF.exists()){
                File[] filelist = sourceF.listFiles();
                for(File f:filelist){
                    File targetFile = new File(targetFolder+f.getName());

                    if(  f.isFile()){
                        //如果目标文件比较新,或源文件比较新,则拷贝,否则跳过
                        if(!targetFile.exists() || FileUtils.isFileNewer(f, targetFile)){
                            FileUtils.copyFileToDirectory(f, new File(targetFolder));
                            System.out.println("copy "+ f.getName());
                        }else{
                            //	//System.out.println("skip  "+ f.getName());
                        }
                    }
                }
            }


        }catch(Exception e){
            e.printStackTrace();
            throw new RuntimeException("copy file error");
        }
    }

	/*
	public static void unZip(String zipPath,String targetFolder,boolean cleanZip){
		File folderFile =new File(targetFolder);
		File zipFile = new File(zipPath);
		Project prj = new Project();
		Expand expand = new Expand();
		expand.setEncoding("UTF-8");
		expand.setProject(prj);
		expand.setSrc(zipFile);
		expand.setOverwrite(true);
		expand.setDest(folderFile);
		expand.execute();

		if(cleanZip){
			//清除zip包
			Delete delete = new Delete();
			delete.setProject(prj);
			delete.setDir(zipFile);
			delete.execute();
		}
	}
	*/
}

5.11 DateUtil

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 日期工具类
 */
public class DateUtil {
    /**
     * 获取某个日期days天后的日期
     * @param date 日期
     * @param days 时间间隔 天数
     * @return
     */
    public static Date getDateAfterDays(Date date,int days){
        Calendar  calendar  =  Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE,days);
        return calendar.getTime();
    }

    /**
     * 获取今天凌晨日期
     * @return date类型
     */
    public static Date getToday(){
        Date now =new Date();
        Calendar c = Calendar.getInstance();
        c.setTime(now);
        c.set(Calendar.HOUR_OF_DAY,0);
        c.set(Calendar.MINUTE,0);
        c.set(Calendar.SECOND,0);
        c.set(Calendar.MILLISECOND,0);
        // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return c.getTime();
    }

    /**
     * 转换字符串为日期格式
     * @param dateStr 时间字符串
     * @param pattern 格式化标准
     * @return
     */
    public static Date toDate(String dateStr,String pattern){
        if (StringUtils.isNullOrEmpty(dateStr)){
            return null;
        }
        if (pattern == null){
            pattern ="yyyy-MM-dd HH:mm:ss";
        }
        Date date = null;
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        try {
            date =  sdf.parse(dateStr);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return date;
    }

    /**
     * 把日期转换成字符串型
     * @param date 日期
     * @param pattern 格式化标准
     * @return
     */
    public static String toString(Date date, String pattern){
        if(date == null){
            return "";
        }
        if(pattern == null){
            pattern = "yyyy-MM-dd";
        }
        String dateString = "";
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        try {
            dateString = sdf.format(date);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return dateString;
    }

    /**
     * 拿time1和time2比较</br>
     * time1和time2比较 : <1分钟时显示为刚刚;</br>
     * time1和time2比较 : ≥1分钟,<1小时时,显示为:*分钟前;</br>
     * time1和time2比较 : ≥1小时,<1天时,显示为:*小时前;</br>
     * time1和time2比较 : ≥1天时,显示格式:YY-MM-DD
     * @param time1 一般是评论日期,文章日期
     * @param time2 一般是当前时间
     * @return 指定的时间
     */
    public static String compare(Date time1, Long time2){
        Long diff = time2 - time1.getTime();
        if(diff >=3600000L && diff < 86400000L){
            return (diff/3600000L)+"小时前";
        } else if (diff >= 60000L && diff <3600000L){
            return (diff/60000L)+"分钟前";
        } else if (diff < 60000L){
            return "刚刚";
        } else {
            return new SimpleDateFormat("yyyy-MM-dd").format(time1);
        }
    }

    private static void convertWeekByDate(Date time) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); //设置时间格式 Calendar cal = Calendar.getInstance(); cal.setTime(time); //判断要计算的日期是否是周日,如果是则减一天计算周六的,否则会出问题,计算到下一周去了 int dayWeek = cal.get(Calendar.DAY_OF_WEEK);//获得传入日期是一个星期的第几天 if(1 == dayWeek) { cal.add(Calendar.DAY_OF_MONTH, -1); } System.out.println("要计算日期为:"+sdf.format(cal.getTime())); //输出要计算日期 cal.setFirstDayOfWeek(Calendar.MONDAY);//设置一个星期的第一天,按中国的习惯一个星期的第一天是星期一 int day = cal.get(Calendar.DAY_OF_WEEK);//获得传入日期是一个星期的第几天 cal.add(Calendar.DATE, cal.getFirstDayOfWeek()-day);//根据日历的规则,给传入日期减去星期几与一个星期第一天的差值 String Monday = sdf.format(cal.getTime()); System.out.println("所在周星期一的日期:"+Monday); cal.add(Calendar.DATE, 1); String Tuesday = sdf.format(cal.getTime()); System.out.println("所在周星期二的日期:"+Tuesday); cal.add(Calendar.DATE, 1); String Wednesday = sdf.format(cal.getTime()); System.out.println("所在周星期三的日期:"+Wednesday); cal.add(Calendar.DATE, 1); String Thursday = sdf.format(cal.getTime()); System.out.println("所在周星期四的日期:"+Thursday); cal.add(Calendar.DATE, 1); String Friday = sdf.format(cal.getTime()); System.out.println("所在周星期五的日期:"+Friday); cal.add(Calendar.DATE, 1); String Saturday = sdf.format(cal.getTime()); System.out.println("所在周星期六的日期:"+Saturday); cal.add(Calendar.DATE, 1); String Sunday = sdf.format(cal.getTime()); System.out.println("所在周星期日的日期:"+Sunday); }

    }


        public static void main(String[] args) throws Exception{
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d1 = sdf.parse("2018-01-15 01:08:00");
        Date d2 = sdf.parse("2018-01-16 18:57:20");
        System.out.println(compare(d1,d2.getTime()));
    }

}

6. bug汇总

6.1 单图上传提示"上传错误",但是图片已经上传成功

  • 定位如下
  • 全局搜索"上传错误",定位到simpleupload.loadError,form表单提交出现跨域的情况导致的,父页面http://localhost:63342/jianbang-page/hotSpot.html,子页面:http://localhost:8088/jianbang-report/ueditor/config?action=uploadimage。
    因为浏览器的保护机制,在跨域的情况下是不能读取iframe里的内容的。这是为了防止一个网站读取另一个网站里的信息。所以这就造成了UEditor在上传的时候因为读不到iframe内容而提示“上传错误”这种错觉,但实际上已经上传成功了。故此时通过iframe.contentWindow.document是读取不到子页面上传结果信息的。
  • 解决方案:舍弃callback回调,通过ajax提交的方式,在success中做上传后的处理逻辑
    注释掉原来form提交逻辑
// domUtils.on(iframe, 'load', callback);
// form.action = utils.formatUrl(imageActionUrl + (imageActionUrl.indexOf('?') == -1 ? '?':'&') + params);
// form.submit();
  • 添加ajax提交方式
var params = utils.serializeParam(me.queryCommandValue('serverparam')) || '';
var action = utils.formatUrl(imageActionUrl + (imageActionUrl.indexOf('?') == -1 ? '?' : '&') + params);
var formData = new FormData();
formData.append("upfile", form[0].files[0] );
$.ajax({
    url: action,
    type: 'POST',
    cache: false,
    data: formData,
    processData: false,
    contentType: false,
    success: function (data) {
        // data = JSON.parse(data);
        var link, loader,
            body = (iframe.contentDocument || iframe.contentWindow.document).body,
            result = body.innerText || body.textContent || '';
        link = me.options.imageUrlPrefix + data.url;

        if(data.state == 'SUCCESS' && data.url) {
            loader = me.document.getElementById(loadingId);
            loader.setAttribute('src', link);
            loader.setAttribute('_src', link);
            loader.setAttribute('title', data.title || '');
            loader.setAttribute('alt', data.original || '');
            loader.removeAttribute('id');
            domUtils.removeClasses(loader, 'loadingclass');
        } else {
            showErrorLoader && showErrorLoader(data.state);
        }
    	form.reset();
 }
});
  • 此外,也可以通过重定向的方法,参考