当前位置: 移动技术网 > IT编程>开发语言>Jsp > JSP 实用程序之简易页面编辑器

JSP 实用程序之简易页面编辑器

2018年09月30日  | 移动技术网IT编程  | 我要评论

需求:提供一页面,放置“帮助”、“版权”文字内容,特点:静态页面,无须读,只是应付字眼上频繁的修改;没有复杂的交互,无须 javascript;没有图片,不需要文件上传。

给出的方案:提供一页面和简易的后台管理,功能单一,只是编辑页面(只是修改字体、大小、粗体、斜体等的功能)。

实现思路:纯 jsp 展示,管理界面用 http basic 登入,通过一个 js 写成 html 编辑器修改页面内容。直接修改服务器磁盘文件。

界面如下,右图是后台编辑。

\

\
<喎?https: www.2cto.com/kf/ware/vc/"="" target="_blank" class="keylink">vcd48cd7wtbxd0rvm4bxeysejrfrvbwnhdca3im/cieptucdermjptcqgsmf2ysdt77eoyns+ycrhideunic1xkgj1nogslnqimdvw+bhtsjriephdmegms43imzy0ns1xlt6wuu74cxxs/ahsfjlc291cmnlihnwzwnpzmljyxrpb24gbm90igfsbg93zwqgagvyzsbmb3igc291cmnligxldmvsigjlbg93ideun6gxtcts7lojoapt2srh0ojsqtdeumqgvg9ty2f0l2nvbmyvd2vilnhtbcda78pmtctf5nbdzss8/qos1dk1vsa8c2vydmxldd4gvdq146osvnpi68/cw+a01szlsr+31rlfv8ns1kgj16ls4srhigpzccc92rxjo6yyu8rhigrlzmf1bhqgvdq146ooutzp4mvgo6mhozwvcd48chjlignsyxnzpq=="brush:java;"> org.apache.jer.servlet.jspservlet fork false xpoweredby false compilersourcevm 1.7 compilertargetvm 1.7 3

访问的 jsp 其实只有两个 /index.jsp 和 /admin/index.jsp,分别是静态页面和后台编辑页面。/admin/action.jsp 用于接收保存的 action,数据由表单 post 过来。functions.jsp 就是全部的业务逻辑代码,通过 <%@include file="functions.jsp"%>,它不能单独给外界 url 访问。

我们先看看 /index.jsp。


	
		帮助
		
		   
		
		
html {
	font-size: 15px;
}

body {
	padding: 0;
	margin: 0 auto;
	max-width: 600px;
	-webkit-font-smoothing: antialiased;
	font-family: "microsoft yahei", "ff-tisa-web-pro-1", "ff-tisa-web-pro-2",
		"lucida grande", "hiragino sans gb", "hiragino sans gb w3", arial;
	background-color: #ebebeb;
}

h1 {
	text-align: center;
	font-size: 1.5rem;
	letter-spacing: 2px;
	color: #864c24;
	border-bottom: #e0c494 solid 1px;
	padding: 2% 0;
}

h2 {
	font-size: 1rem;
	letter-spacing: 1px;
	color: #4c4c4c;
	padding-bottom:0;
	margin: 0;
}

p {
	text-align: justify;
	font-size: 1rem;
	color: #818181;
	margin: 1% 0;
	margin-top:0;
}

ol {
	padding: 0;
	margin: 0;
}

ol {
	
}

ol>li>:first-child {
	/* make firefox put the list marker inside */
	/* https://bugzilla.mozilla.org/show_bug.cgi?id=36854 "if list-style-position is inside, bullet takes own line" */
	display: inline;
}

ol>li>:first-child:after {
	/* add the margin that was lost w/ display: inline */
	/* firefox 10 displays this as block */
	/* safari 5.1.2 and chrome 17.0.963.56 don't */
	content: "";
	display: block;
}

li {
	padding: 5% 2%;
	list-style-position: inside;
	border-bottom: 1px solid #dddddb;
}

.text {
	color: #a8a8a8;
	font-size: 1rem;
	font-weight: bold;
	padding: 2%;
}

	
	
				帮助
		常见问题

power tv的资费是怎样收取的?

12元power tv手机电视包月,产品代码88888888,12元/月;省内用户省内使用配送3g/月定向流量,流量仅用于使用power tv,超过定向流量部分按标准资费收取;

power tv的资费是怎样收取的?

12元power tv手机电视包月,产品代码88888888,12元/月;省内用户省内使用配送3g/月定向流量,流量仅用于使用power tv,超过定向流量部分按标准资费收取;

power tv的资费是怎样收取的?

12元power tv手机电视包月,产品代码88888888,12元/月;省内用户省内使用配送3g/月定向流量,流量仅用于使用power tv,超过定向流量部分按标准资费收取;

power tv的资费是怎样收取的?

12元power tv手机电视包月,产品代码88888888,12元/月;省内用户省内使用配送3g/月定向流量,流量仅用于使用power tv,超过定向流量部分按标准资费收取;

power tv的资费是怎样收取的?

12元power tv手机电视包月,产品代码88888888,12元/月;省内用户省内使用配送3g/月定向流量,流量仅用于使用power tv,超过定向流量部分按标准资费收取;

power tv的资费是怎样收取的?

12元power tv手机电视包月,产品代码88888888,12元/月;省内用户省内使用配送3g/月定向流量,流量仅用于使用power tv,超过定向流量部分按标准资费收取;

power tv的资费是怎样收取的?

12元power tv手机电视包月,产品代码88888888,12元/月;省内用户省内使用配送3g/月定向流量,流量仅用于使用power tv,超过定向流量部分按标准资费收取;

这份 jsp 与一般 jsp 并无特异,只不过大家有没有留意到两段注释: 和 ——这就是我们约定的“可编辑”范围。当然,使用自定义的 html tag 也可以,只要定义了一个范围即可。一份网页,无非是 html。对于其中欲编辑的东西,我们定义一个范围指明哪些地方需要编辑,就可以了。至于为什么不让全部的页面可以编辑?是因为我们不想用户对页面其它部分进行编辑,万一修改了的关键地方造成了错误,那可不好。

好了,怎么让这个 /index.jsp 编辑呢?就是利用 java 读取磁盘的方法来做的。在这个之前,得先登录到 /admin/index.jsp。这里我们通过 http basic authorization 来做用户认证,无须数据库。如果需要修改 账号密码,打开 admin/functions.jsp,编辑头部分即可:
<%!
public static final string userid = "admin", pwd = "123123";
....
%>

不过笔者 http basic authorization 遇到了个小问题,就是弹出的对话框,不知怎么修改其中的提示文字,试过几种方法,要么不显示,要么乱码。如果知道的童鞋还请告知一二!

action.jsp 也要作认证的限制,不然等于是个可以让别人 post 任何数据到页面。


<%

if (checkauth(request.getheader("authorization"), userid, pwd)) {
  request.setcharacterencoding("utf-8"); 
	if (request.getmethod().equalsignorecase("post")) {
		string contentbody = request.getparameter("contentbody"), path = mappath(geteditjsp(request));
		system.out.println("path:::" + path);
		save_jsp_filecontent(path, contentbody);
		out.println("<script>alert('修改成功!');window.location = document.referrer;</script>");
	} else {
		out.println("method error");
	}
} else {
	%>
	
	
		非法登录!
	
	
	<%
}
%>

修改下页面,点击保存就可以修改页面了。

至于 html 如何编辑?这个答案想必大家都清楚,使用 html 可视化编辑器即可,在线的哦,而不是什么 dreamweaver、frontpage、vs web 之类啦。老人们用过的就是有 呀、,近几年好像喜欢用国产了,我就不知道了。现在这个用的是我自己写,功能比较单一的。

核心逻辑是通过下面的代码搞定的。

<%!
public static final string userid = "admin", pwd = "86006966";
// 检查 http basic 认证

	/**
	 * 是否空字符串
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isemptystring(string str) {
		return str == null || str.trim().isempty();
	}

	/**
	 * 是否不合法的数组
	 * 
	 * @param arr
	 * @return
	 */
	public static boolean isbadarray(string[] arr) {
		return arr == null || arr.length != 2;
	}

	/**
	 * 
	 * @param authorization
	 *            认证后每次http请求都会附带上 authorization 头信息
	 * @param username
	 *            用户名
	 * @param password
	 *            密码
	 * @return true = 认证成功/ false = 需要认证
	 */
	public static boolean checkauth(string authorization, string username, string password) {
		if (isemptystring(authorization))
			return false;

		string[] basicarray = authorization.split("\\s+");
		if (isbadarray(basicarray))
			return false;

		string idpass = null;
		try {
			byte[] buf = new base64decoder().decodebuffer(basicarray[1]);
			idpass = new string(buf, "utf-8");
		} catch (ioexception e) {
			e.printstacktrace();
			return false;
		}

		if (isemptystring(idpass))
			return false;

		string[] idpassarray = idpass.split(":");
		if (isbadarray(idpassarray))
			return false;

		return username.equalsignorecase(idpassarray[0]) && password.equalsignorecase(idpassarray[1]);
	}

	/**
	 * 可编辑标识开始
	 */
	private final static string starttoken = "";

	/**
	 * 可编辑标识结束
	 */
	private final static string endtoken = "";

	/**
	 * 根据 页面中可编辑区域之标识,取出来。
	 * 
	 * @param fullfilepath
	 *            完整的 jsp 文件路径
	 * @return 可编辑内容
	 * @throws ioexception
	 */
	public static string read_jsp_filecontent(string fullfilepath) throws ioexception {
		string jsp_filecontent = readfile(fullfilepath);

		int start = jsp_filecontent.indexof(starttoken), end = jsp_filecontent.indexof(endtoken);

		try {
			jsp_filecontent = jsp_filecontent.substring(start + starttoken.length(), end);
		} catch (stringindexoutofboundsexception e) {
			jsp_filecontent = null;

			string msg = "页面文件" + fullfilepath + "中没有标记可编辑区域之标识。请参考:" + starttoken + "/" + endtoken;
			throw new ioexception(msg);
		}

		return jsp_filecontent;
	}

	/**
	 * 请求附带文件参数,将其转换真实的磁盘文件路径
	 * 
	 * @param rawfullfilepath
	 *            url 提交过来的磁盘文件路径,可能未包含文件名或加了很多 url 参数
	 * @return 完整的磁盘文件路径
	 */
	static string getfullpathbyrequesturl(string rawfullfilepath) {
		if (rawfullfilepath.indexof(".jsp") == -1)
			rawfullfilepath += "/index.jsp"; // 加上 扩展名

		if (rawfullfilepath.indexof("?") != -1) // 去掉 url 参数
			rawfullfilepath = rawfullfilepath.replaceall("\\?.*$", "");

		return rawfullfilepath;
	}

	/**
	 * 保存要修改的页面
	 * 
	 * @param rawfullfilepath
	 *            真实的磁盘文件路径
	 * @param newcontent
	 *            新提交的内容
	 * @throws ioexception
	 */
	public static void save_jsp_filecontent(string rawfullfilepath, string newcontent) throws ioexception {
		string fullfilepath = getfullpathbyrequesturl(rawfullfilepath); // 真实的磁盘文件路径
		string jsp_filecontent = readfile(fullfilepath), todel_filecontent = read_jsp_filecontent(fullfilepath);// 读取旧内容
//system.out.println(jsp_filecontent);
//system.out.println(todel_filecontent);
		if (todel_filecontent != null) {
			jsp_filecontent = jsp_filecontent.replace(todel_filecontent, newcontent);
			save2file(fullfilepath, jsp_filecontent); // 保存新内容
		} else {
			throw new ioexception("页面文件中没有标记可编辑区域之标识。请参考: starttoken/endtpoken");
		}
	}

	/**
	 * 读取文件
	 * 
	 * @param filename
	 * @return
	 * @throws ioexception
	 */
	public static string readfile(string filename) throws ioexception {
		file file = new file(filename);
		if (!file.exists())
			throw new filenotfoundexception(filename + " 不存在!");

		try (fileinputstream is = new fileinputstream(file);) {
			string line = null;
			stringbuilder result = new stringbuilder();

			try (inputstreamreader isreader = new inputstreamreader(is, "utf-8");
					bufferedreader reader = new bufferedreader(isreader);) {
				while ((line = reader.readline()) != null) {
					result.append(line);
					result.append('\n');
				}
			} catch (ioexception e) {
				system.err.println(e);
			}

			return result.tostring();
		} catch (ioexception e) {
			system.err.println("讀取文件流出錯!" + filename);
			throw e;
		}
	}

	/**
	 * 写文件不能用 filewriter,原因是会中文乱码
	 * 
	 * @param filename
	 * @param content
	 * @throws ioexception
	 */
	public static void save2file(string filename, string content) throws ioexception {
		try (fileoutputstream out = new fileoutputstream(filename);
				// outputstreramwriter将输出的字符流转化为字节流输出(字符流已带缓冲)
				outputstreamwriter writer = new outputstreamwriter(out, "utf8");) {
			writer.write(content);
		} catch (ioexception e) {
			system.err.println("写入文件" + filename + "失败");
			throw e;
		}
	}
	
	/**
	 * 输入一个相对地址,补充成为绝对地址 相对地址转换为绝对地址,并转换斜杠
	 * 
	 * @param relativepath
	 *            相对地址
	 * @return 绝对地址
	 */
	public string mappath(string relativepath) {
		string absoluteaddress = getservletcontext().getrealpath(relativepath); // 绝对地址
		
		if (absoluteaddress != null)
			absoluteaddress = absoluteaddress.replace('\\', '/');
		return absoluteaddress;
	}
	
	public string geteditjsp(httpservletrequest request) {
		string uri = request.getrequesturi().replaceall("admin/\\w+", "index");
		uri = uri.replace(request.getcontextpath(), "");
		return uri;
	}
%>

用户凭账号密码登入简易的后台,通过可视化编辑器即可修改页面内容,立刻修改,立刻产生效果,简单快捷——把页面开放出来允许自主编辑这样会提高效率——减少来回修改的次数。

不足之处,还请大家指出。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网