LongYan360全景相机得配置好不好

freemarker内置日期标签_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
freemarker内置日期标签
上传于|0|0|暂无简介
你可能喜欢> 博客详情
摘要: freemarker intelliJ
使用freemarker模板,展示一个时间字段,数据库保存的是毫秒。在网上找了许多文章,发现都是针对date或者是直接类似“”这样已经成型字符串进行操作的,心中不禁万马奔腾。本来已经放弃准备自己调js脚本解决了,不过随手试了一下,结果发现了一个方法:number_to_date,试了一下可用,心中不由感慨intelliJ的强大索引功能。大概这个函数是高版本freemarder新增的功能,所以老文章里都没有提到。
除了number_to_date还有number_to_datetime,配合页头声明使用,因为我尝试在方法中增加参数,类似“yyyy-MM-dd",全都报错,虽然索引中显示支持参数,但是不了解格式。页头声明就简单一些了:
&#setting&datetime_format="yyyy-MM-dd&HH:mm"/&
如果字段是字符串格式,就要先转换为number,支持链式调用
${profile.createTime?number?number_to_datetime}
人打赏支持
码字总数 5758
支付宝支付
微信扫码支付
打赏金额: ¥
已支付成功
打赏金额: ¥ueditor文件上传研究 - 勤奋的asialee的博客 - ITeye技术网站
博客分类:
之前写过一版本的ueditor的使用方式,感觉后来ueditor升级很快,转眼间又升级了,今天有一个人问这块相关的问题,正好又熟悉下。
首先最基本的用法我就不讲了,只讲文件上传的这块。
首先,文件上传这块和之前的变化很大,先慢慢的讲讲用法。
1. java版本的在jsp目录的文件结构如下:
从这地方可以看出来,有一个controller.jsp, 一个config.json,一堆jar文件, 这个和之前版本是不一致的。
2. maven工程的jar包的引用
如果没有使用jar包,很容易,直接copy文件就可以,但是maven的方式,这个jar又在网上没有,索幸maven提供了system方式的依赖方式:
& dependency&
& groupId& com.baidu.ueditor &/groupId &
& artifactId& ueditor &/artifactId &
& version& 1.1.1 &/version &
& scope& system &/scope &
& systemPath& ${basedir}/ src/main/webapp /WEB-INF/lib/ ueditor-1.1.1.jar &/systemPath &
&/ dependency&
maven的jar包的放置位置如下:
其他的jar我就不多讲了,都很容易找。
3. controller.jsp文件阅读
&%@ page language="java" contentType="text/ charset=UTF-8"
import="com.baidu.ueditor.ActionEnter"
pageEncoding="UTF-8"%&
&%@ page trimDirectiveWhitespaces="true" %&
request.setCharacterEncoding( "utf-8" );
response.setHeader("Content-Type" , "text/html");
String rootPath = application.getRealPath( "/" );
out.write( new ActionEnter( request, rootPath ).exec() );
从代码来看,rootPath其实就是项目的根路径,构建了ActionEnter,并调用了exec函数。
我们来看下ActionEnter的代码:
package com.baidu.
import com.baidu.ueditor.define.ActionM
import com.baidu.ueditor.define.BaseS
import com.baidu.ueditor.define.S
import com.baidu.ueditor.hunter.FileM
import com.baidu.ueditor.hunter.ImageH
import com.baidu.ueditor.upload.U
import java.util.M
import javax.servlet.http.HttpServletR
import org.json.JSONO
public class ActionEnter
private HttpServletRequest request =
private String rootPath =
private String contextPath =
private String actionType =
private ConfigManager configManager =
public ActionEnter(HttpServletRequest request, String rootPath)
this.request =
this.rootPath = rootP
// 对action进行赋值。
this.actionType = request.getParameter("action");
this.contextPath = request.getContextPath();
// 构建configManager类
this.configManager = ConfigManager.getInstance(this.rootPath, this.contextPath, request.getRequestURI());
public String exec()
// 这个是处理jsonp的形式,一般都是不跨域的。
String callbackName = this.request.getParameter("callback");
if (callbackName != null)
if (!validCallbackName(callbackName)) {
return new BaseState(false, 401).toJSONString();
return callbackName + "(" + invoke() + ");";
return invoke();
public String invoke()
// 判断action是否合法,如果不合法返回一个非法状态
if ((this.actionType == null) || (!ActionMap.mapping.containsKey(this.actionType))) {
return new BaseState(false, 101).toJSONString();
// 如果找不到configManager也报错
if ((this.configManager == null) || (!this.configManager.valid())) {
return new BaseState(false, 102).toJSONString();
State state =
// 取得actionCode
int actionCode = ActionMap.getType(this.actionType);
Map conf =
switch (actionCode)
return this.configManager.getAllConfig().toString();
// 处理上传文件
conf = this.configManager.getConfig(actionCode);
state = new Uploader(this.request, conf).doExec();
conf = this.configManager.getConfig(actionCode);
String[] list = this.request.getParameterValues((String)conf.get("fieldName"));
// 处理在线编辑
state = new ImageHunter(conf).capture(list);
conf = this.configManager.getConfig(actionCode);
int start = getStartIndex();
// 处理文件list
state = new FileManager(conf).listFile(start);
return state.toJSONString();
public int getStartIndex()
String start = this.request.getParameter("start");
return Integer.parseInt(start); } catch (Exception e) {
public boolean validCallbackName(String name)
if (name.matches("^[a-zA-Z_]+[\\w0-9_]*$")) {
我们慢慢的来看这个函数:首先在构造函数里面调用了request.getContextPath()和request.getRequestURI()函数。
假设我们的项目的contextPath为:test,那么下面两个函数的返回值则如下:
request.getContextPath
request.getRequestURI
/test/resources/ueditor/jsp/controller.jsp
我们还是先来看下ConfigManager类吧。
package com.baidu.
import java.io.BufferedR
import java.io.F
import java.io.FileInputS
import java.io.FileNotFoundE
import java.io.IOE
import java.io.InputStreamR
import java.io.UnsupportedEncodingE
import java.util.HashM
import java.util.M
import org.json.JSONA
import org.json.JSONO
public final class ConfigManager
private final String rootP
private final String originalP
private final String contextP
private static final String configFileName = "config.json";
private String parentPath =
private JSONObject jsonConfig =
private static final String SCRAWL_FILE_NAME = "scrawl";
private static final String REMOTE_FILE_NAME = "remote";
private ConfigManager(String rootPath, String contextPath, String uri)
throws FileNotFoundException, IOException
rootPath = rootPath.replace("\\", "/");
this.rootPath = rootP
this.contextPath = contextP
// 这个地方要特别注意,originalPath其实就是controller.jsp所在的路径
if (contextPath.length() & 0)
this.originalPath = (this.rootPath + uri.substring(contextPath.length()));
this.originalPath = (this.rootPath + uri);
initEnv();
public static ConfigManager getInstance(String rootPath, String contextPath, String uri)
return new ConfigManager(rootPath, contextPath, uri); } catch (Exception e) {
public boolean valid()
return this.jsonConfig !=
public JSONObject getAllConfig()
return this.jsonC
public Map&String, Object& getConfig(int type)
Map conf = new HashMap();
String savePath =
// 根据不同的code来解析config.json的配置文件
switch (type)
conf.put("isBase64", "false");
conf.put("maxSize", Long.valueOf(this.jsonConfig.getLong("fileMaxSize")));
conf.put("allowFiles", getArray("fileAllowFiles"));
conf.put("fieldName", this.jsonConfig.getString("fileFieldName"));
savePath = this.jsonConfig.getString("filePathFormat");
conf.put("isBase64", "false");
conf.put("maxSize", Long.valueOf(this.jsonConfig.getLong("imageMaxSize")));
conf.put("allowFiles", getArray("imageAllowFiles"));
conf.put("fieldName", this.jsonConfig.getString("imageFieldName"));
savePath = this.jsonConfig.getString("imagePathFormat");
conf.put("maxSize", Long.valueOf(this.jsonConfig.getLong("videoMaxSize")));
conf.put("allowFiles", getArray("videoAllowFiles"));
conf.put("fieldName", this.jsonConfig.getString("videoFieldName"));
savePath = this.jsonConfig.getString("videoPathFormat");
conf.put("filename", "scrawl");
conf.put("maxSize", Long.valueOf(this.jsonConfig.getLong("scrawlMaxSize")));
conf.put("fieldName", this.jsonConfig.getString("scrawlFieldName"));
conf.put("isBase64", "true");
savePath = this.jsonConfig.getString("scrawlPathFormat");
conf.put("filename", "remote");
conf.put("filter", getArray("catcherLocalDomain"));
conf.put("maxSize", Long.valueOf(this.jsonConfig.getLong("catcherMaxSize")));
conf.put("allowFiles", getArray("catcherAllowFiles"));
conf.put("fieldName", this.jsonConfig.getString("catcherFieldName") + "[]");
savePath = this.jsonConfig.getString("catcherPathFormat");
conf.put("allowFiles", getArray("imageManagerAllowFiles"));
conf.put("dir", this.jsonConfig.getString("imageManagerListPath"));
conf.put("count", Integer.valueOf(this.jsonConfig.getInt("imageManagerListSize")));
conf.put("allowFiles", getArray("fileManagerAllowFiles"));
conf.put("dir", this.jsonConfig.getString("fileManagerListPath"));
conf.put("count", Integer.valueOf(this.jsonConfig.getInt("fileManagerListSize")));
conf.put("savePath", savePath);
conf.put("rootPath", this.rootPath);
// 加载config.json配置文件
private void initEnv()
throws FileNotFoundException, IOException
File file = new File(this.originalPath);
if (!file.isAbsolute()) {
file = new File(file.getAbsolutePath());
this.parentPath = file.getParent();
String configContent = readFile(getConfigPath());
JSONObject jsonConfig = new JSONObject(configContent);
this.jsonConfig = jsonC
} catch (Exception e) {
this.jsonConfig =
private String getConfigPath()
return this.parentPath + File.separator + "config.json";
private String[] getArray(String key)
JSONArray jsonArray = this.jsonConfig.getJSONArray(key);
String[] result = new String[jsonArray.length()];
int i = 0; for (int len = jsonArray.length(); i & i++) {
result[i] = jsonArray.getString(i);
// 读取config.json里面的内容
private String readFile(String path)
throws IOException
StringBuilder builder = new StringBuilder();
InputStreamReader reader = new InputStreamReader(new FileInputStream(path), "UTF-8");
BufferedReader bfReader = new BufferedReader(reader);
String tmpContent =
while ((tmpContent = bfReader.readLine()) != null) {
builder.append(tmpContent);
bfReader.close();
catch (UnsupportedEncodingException localUnsupportedEncodingException)
return filter(builder.toString());
private String filter(String input)
return input.replaceAll("/\\*[\\s\\S]*?\\*/", "");
我们再来看Uploader函数,其实很简单:
package com.baidu.ueditor.
import com.baidu.ueditor.define.S
import java.util.M
import javax.servlet.http.HttpServletR
public class Uploader
private HttpServletRequest request =
private Map&String, Object& conf =
public Uploader(HttpServletRequest request, Map&String, Object& conf) {
this.request =
this.conf =
public final State doExec() {
String filedName = (String)this.conf.get("fieldName");
State state =
if ("true".equals(this.conf.get("isBase64")))
state = Base64Uploader.save(this.request.getParameter(filedName),
this.conf);
state = BinaryUploader.save(this.request, this.conf);
这个很好理解,我们接着来看BinaryUploader类:
package com.baidu.ueditor.
import com.baidu.ueditor.PathF
import com.baidu.ueditor.define.BaseS
import com.baidu.ueditor.define.FileT
import com.baidu.ueditor.define.S
import java.io.IOE
import java.io.InputS
import java.util.A
import java.util.L
import java.util.M
import javax.servlet.http.HttpServletR
import mons.fileupload.FileItemI
import mons.fileupload.FileItemS
import mons.fileupload.FileUploadE
import mons.fileupload.disk.DiskFileItemF
import mons.fileupload.servlet.ServletFileU
public class BinaryUploader
// 使用fileupload来处理文件上传
public static final State save(HttpServletRequest request, Map&String, Object& conf)
FileItemStream fileStream =
boolean isAjaxUpload = request.getHeader("X_Requested_With") !=
if (!ServletFileUpload.isMultipartContent(request)) {
return new BaseState(false, 5);
ServletFileUpload upload = new ServletFileUpload(
new DiskFileItemFactory());
if (isAjaxUpload) {
upload.setHeaderEncoding("UTF-8");
FileItemIterator iterator = upload.getItemIterator(request);
while (iterator.hasNext()) {
fileStream = iterator.next();
if (!fileStream.isFormField())
fileStream =
if (fileStream == null) {
return new BaseState(false, 7);
String savePath = (String)conf.get("savePath");
String originFileName = fileStream.getName();
String suffix = FileType.getSuffixByFilename(originFileName);
originFileName = originFileName.substring(0,
originFileName.length() - suffix.length());
savePath = savePath +
long maxSize = ((Long)conf.get("maxSize")).longValue();
if (!validType(suffix, (String[])conf.get("allowFiles"))) {
return new BaseState(false, 8);
savePath = PathFormat.parse(savePath, originFileName);
String physicalPath = (String)conf.get("rootPath") + saveP
// 调用存储类来处理文件存储
InputStream is = fileStream.openStream();
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 storageS
} catch (FileUploadException e) {
return new BaseState(false, 6);
} catch (IOException localIOException) {
return new BaseState(false, 4);
private static boolean validType(String type, String[] allowTypes) {
List list = Arrays.asList(allowTypes);
return list.contains(type);
StorageManager我们就不看了,无非就是做一些文件存储的一些事情,下面我们来分析下这种实现方式的问题。
最后我稍微总结下看这个代码得收获和对作者的建议:
从这个地方来看,无法将图片放置在外部路径,因为这种实现就决定了只能放到项目路径下,这个最大的问题就是,有可能不小心,重新上下线,内容全部丢了。
从实现来看,大量的使用静态调用,基本上无法二次开发,不能灵活的继承它来处理个性化的东西,比如如果存储到fastDFS里面,这个就需要改里面的代码,不能通过扩展的方式来进行
config.json里面的配置项转换的时候,进行了重命名,这个地方就要求读者要记两个变量名,比如:imagePathFormat变成了savePath, 感觉好像挺好理解,但是这种明显不是好的方式,如果里面存在一个这个逻辑,最好显式的说明,而不是硬编码
源代码不开放,无法进行扩展和修改,建议作者开发这个jar到github里面,社区一块维护
下载次数: 346
下载次数: 453
浏览 42959
楼主,小弟实在不明白,ActionMap里的Map&String, Integer& mapping = new HashMap() {};是什么意思?这算什么初始化方法呢?实在看不懂,如果是匿名内部类,我还是看不懂还有getType()方法,Type都是ActionMap的成员变量,也没见哪里设置进mapping了,mapping.get(key)方法是如果运作的?还请楼主大人为小弟解除疑惑这个应该是反编译的有问题,我看了下官方现在也开源了,代码如下:感谢你的认真,我感觉你会成长进步的。
package com.baidu.ueditor.
import java.util.M
import java.util.HashM
* 定义请求action类型
@SuppressWarnings("serial")
public final class ActionMap {
public static final Map&String, Integer&
// 获取配置请求
public static final int CONFIG = 0;
public static final int UPLOAD_IMAGE = 1;
public static final int UPLOAD_SCRAWL = 2;
public static final int UPLOAD_VIDEO = 3;
public static final int UPLOAD_FILE = 4;
public static final int CATCH_IMAGE = 5;
public static final int LIST_FILE = 6;
public static final int LIST_IMAGE = 7;
mapping = new HashMap&String, Integer&(){{
put( "config", ActionMap.CONFIG );
put( "uploadimage", ActionMap.UPLOAD_IMAGE );
put( "uploadscrawl", ActionMap.UPLOAD_SCRAWL );
put( "uploadvideo", ActionMap.UPLOAD_VIDEO );
put( "uploadfile", ActionMap.UPLOAD_FILE );
put( "catchimage", ActionMap.CATCH_IMAGE );
put( "listfile", ActionMap.LIST_FILE );
put( "listimage", ActionMap.LIST_IMAGE );
public static int getType ( String key ) {
return ActionMap.mapping.get( key );
我想问一下,之前的ueditor版本是可以配置上传图片到项目外部路径么?????可以,现在得修改代码,但是有没有开源代码,之前是写在jsp里面的。
感谢前辈,受益匪浅过奖了,不知道解决你的问题了没有?
求源码ueditor-1.1.1.jar好的,我将反编译的上传下
浏览: 752442 次
来自: 北京
感觉LogManager打开了所有的LogSegment(文件 ...
大神 你好 我再使用ueditor 进行编辑的时候发现他会在我 ...

我要回帖

 

随机推荐