亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JSP > 正文

JSP實用教程之簡易頁面編輯器的實現方法(附源碼)

2024-09-05 00:23:13
字體:
來源:轉載
供稿:網友

前言

實現一個簡易的頁面編輯器是大家在學習jsp的時候經常會遇到的一個需求,發現網上這方便的資料不多,所以想著自己總結下,本文詳細介紹了JSP簡易頁面編輯器的實現方法,下面話不多說,來一起看看詳細的介紹:

需求

提供一頁面,放置“幫助”、“版權”文字內容,特點:靜態頁面,無須讀數據庫,只是應付字眼上頻繁的修改;沒有復雜的交互,無須 JavaScript;沒有圖片,不需要文件上傳。

給出的方案:提供一頁面和簡易的后臺管理,功能單一,只是編輯頁面(只是修改字體、大小、粗體、斜體等的功能)。
實現思路:純 JSP 展示,管理界面用 HTTP Basic 登入,通過一個 js 寫成 HTML 編輯器修改頁面內容。直接修改服務器磁盤文件。

界面如下,右圖是后臺編輯。

jsp頁面編輯器,jsp頁面文本編輯器,jsp,文本編輯器

值得一提的是,Tomcat 7 下 JSP 默認的 Java 語法仍舊是 1.6 的。在 JSP 里面嵌入 Java 1.7 特性的代碼會拋出“Resource specification not allowed here for source level below 1.7”的異常。于是需要修改 Tomcat/conf/web.xml 里面的配置文件,找到 <servlet> 節點( <servlet-name>jsp</servlet-name>  的才是),加入下面最后兩個 init-param 節點部分。注意是 <servlet-name>jsp</servlet-name> 節點才可以,不是 default 節點(很相似)。

<servlet>   <servlet-name>jsp</servlet-name>   <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>   <init-param>    <param-name>fork</param-name>    <param-value>false</param-value>   </init-param>   <init-param>    <param-name>xpoweredBy</param-name>    <param-value>false</param-value>   </init-param>     <init-param>    <param-name>compilerSourceVM</param-name>    <param-value>1.7</param-value>   </init-param>   <init-param>    <param-name>compilerTargetVM</param-name>    <param-value>1.7</param-value>   </init-param>     <load-on-startup>3</load-on-startup>  </servlet> 

訪問的 jsp 其實只有兩個 /index.jsp 和 /admin/index.jsp,分別是靜態頁面和后臺編輯頁面。/admin/action.jsp 用于接收保存的 action,數據由表單 POST 過來。functions.jsp 就是全部的業務邏輯代碼,通過 %@include file="functions.jsp"% ,它不能單獨給外界 url 訪問。

我們先看看 /index.jsp。

<%@page pageEncoding="UTF-8"%> <html>  <head>   <title>幫助</title>   <meta charset="utf-8" />    <!--寬度 320px -->   <meta name="viewport" content="width=320,user-scalable=0,initial-scale=1.0,maximum-scale=1.0, minimum-scale=1.0" />   <style> 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%; } </style>  </head>  <body>   <!-- Editable AREA|START -->  <h1>幫助</h1>   <div class="text">常見問題</div>   <ol>    <li>     <h2>Power TV的資費是怎樣收取的?</h2>     <p>12元Power TV手機電視包月,產品代碼88888888,12元/月;省內用戶省內使用配送3G/月定向流量,流量僅用于使用Power TV,超過定向流量部分按標準資費收??; </p>    </li>    <li>     <h2>Power TV的資費是怎樣收取的?</h2>     <p>12元Power TV手機電視包月,產品代碼88888888,12元/月;省內用戶省內使用配送3G/月定向流量,流量僅用于使用Power TV,超過定向流量部分按標準資費收??; </p>    </li>    <li>     <h2>Power TV的資費是怎樣收取的?</h2>     <p>12元Power TV手機電視包月,產品代碼88888888,12元/月;省內用戶省內使用配送3G/月定向流量,流量僅用于使用Power TV,超過定向流量部分按標準資費收??; </p>    </li>    <li>     <h2>Power TV的資費是怎樣收取的?</h2>     <p>12元Power TV手機電視包月,產品代碼88888888,12元/月;省內用戶省內使用配送3G/月定向流量,流量僅用于使用Power TV,超過定向流量部分按標準資費收?。?</p>    </li>    <li>     <h2>Power TV的資費是怎樣收取的?</h2>     <p>12元Power TV手機電視包月,產品代碼88888888,12元/月;省內用戶省內使用配送3G/月定向流量,流量僅用于使用Power TV,超過定向流量部分按標準資費收??; </p>    </li>    <li>     <h2>Power TV的資費是怎樣收取的?</h2>     <p>12元Power TV手機電視包月,產品代碼88888888,12元/月;省內用戶省內使用配送3G/月定向流量,流量僅用于使用Power TV,超過定向流量部分按標準資費收取; </p>    </li>    <li>     <h2>Power TV的資費是怎樣收取的?</h2>     <p>12元Power TV手機電視包月,產品代碼88888888,12元/月;省內用戶省內使用配送3G/月定向流量,流量僅用于使用Power TV,超過定向流量部分按標準資費收?。?</p>    </li>   </ol>   <!-- Editable AREA|END -->  </body> </html> 

這份 JSP 與一般 JSP 并無特異,只不過大家有沒有留意到兩段注釋: <!-- Editable AREA|START --> <!-- Editable AREA|END --> ——這就是我們約定的“可編輯”范圍。當然,使用自定義的 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 遇到了個小問題,就是瀏覽器彈出的對話框,不知怎么修改其中的提示文字,試過幾種方法,要么不顯示,要么亂碼。如果知道的童鞋還請告知一二!

jsp頁面編輯器,jsp頁面文本編輯器,jsp,文本編輯器

action.jsp 也要作認證的限制,不然等于是個漏洞可以讓別人 POST 任何數據到頁面。

<%@page pageEncoding="UTF-8"%> <%@include file="functions.jsp"%> <%  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>  <body>   非法登錄!  </body>  </html>  <% } %> 

修改下頁面,點擊保存就可以修改頁面了。

jsp頁面編輯器,jsp頁面文本編輯器,jsp,文本編輯器

至于 HTML 如何編輯?這個答案想必大家都清楚,使用 HTML 可視化編輯器即可,在線的哦,而不是什么 Dreamweaver、FrontPage、VS Web 之類啦。老人們用過的就是有 FCKEditror 呀、TinyMCE Editor,近幾年好像喜歡用國產了,我就不知道了?,F在這個用的是我自己寫,功能比較單一的。

核心邏輯是通過下面的代碼搞定的。

<%@page pageEncoding="UTF-8" import="sun.misc.BASE64Decoder, java.io.*"%> <%! 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 = "<!-- Editable AREA|START -->";   /**   * 可編輯標識結束   */  private final static String endToken = "<!-- Editable AREA|END -->";   /**   * 根據 頁面中可編輯區域之標識,取出來。   *   * @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;  } %> 

用戶憑賬號密碼登入簡易的后臺,通過可視化編輯器即可修改頁面內容,立刻修改,立刻產生效果,簡單快捷——把頁面開放出來允許自主編輯這樣會提高效率——減少來回修改的次數。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到JSP教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久亚洲精品国产亚洲老地址| 欧美视频在线免费| 91精品视频观看| 91久久国产精品| 亚洲性69xxxbbb| 91av在线国产| 中文字幕在线看视频国产欧美在线看完整| 亚洲第一av网站| 亚洲一级片在线看| 亚洲精品国精品久久99热一| 在线亚洲欧美视频| 日韩女优在线播放| 97久久超碰福利国产精品…| 亚洲午夜未满十八勿入免费观看全集| 久久久久久中文字幕| 国产亚洲精品久久久久久牛牛| 久久99久国产精品黄毛片入口| 伊人久久久久久久久久| 国产成+人+综合+亚洲欧洲| 日本国产高清不卡| 色噜噜狠狠狠综合曰曰曰88av| 毛片精品免费在线观看| 国产一区二区三区在线看| 欧美猛交免费看| 国产有码在线一区二区视频| 日韩有码在线播放| 欧美电影在线免费观看网站| 国产欧美一区二区白浆黑人| 欧美大片在线影院| 亚洲国产精品久久精品怡红院| 亚洲美女中文字幕| 久久视频精品在线| 亚洲精品电影网站| 黄网动漫久久久| 久久久久久久激情视频| 亚洲欧美中文在线视频| 国产精品成人国产乱一区| 日韩av成人在线观看| 欧美日在线观看| 91香蕉国产在线观看| 国产精欧美一区二区三区| 尤物九九久久国产精品的分类| 国产欧美日韩专区发布| 久久九九有精品国产23| 国产精品久久久久久久av大片| 欧美成人在线免费视频| 日本a级片电影一区二区| 亚洲激情在线观看视频免费| 亚洲精品97久久| 欧美日韩免费区域视频在线观看| 欧美夫妻性生活xx| 国产在线视频2019最新视频| 色噜噜狠狠狠综合曰曰曰88av| 日韩国产高清视频在线| 成人激情视频在线| 亚洲精品在线91| 一区二区日韩精品| 久久综合久久八八| 性色av一区二区三区| 欧美男插女视频| 午夜精品一区二区三区视频免费看| 中国日韩欧美久久久久久久久| 色偷偷888欧美精品久久久| 成人免费网站在线观看| 久久这里有精品| 国产97在线视频| 国产成人综合久久| 亚洲欧美日韩中文视频| 日本精品性网站在线观看| 精品国产依人香蕉在线精品| 91亚洲精品在线| 国产精品一区二区久久久| 亚洲第一福利视频| 国产精品jvid在线观看蜜臀| 69久久夜色精品国产69乱青草| 欧美高清无遮挡| 亚洲黄色在线观看| 欧美国产日韩免费| 国产精品偷伦一区二区| 6080yy精品一区二区三区| 欧美成人午夜激情视频| 国产成人鲁鲁免费视频a| 68精品久久久久久欧美| 91精品久久久久久综合乱菊| 国产xxx69麻豆国语对白| 久久亚洲综合国产精品99麻豆精品福利| 亚洲性视频网站| 亚洲日韩第一页| 国产精品精品视频一区二区三区| 青青草一区二区| 国产福利视频一区二区| 国产婷婷成人久久av免费高清| 亚洲精品二三区| 激情久久av一区av二区av三区| 欧美国产乱视频| 另类专区欧美制服同性| 美女福利精品视频| 欧美综合一区第一页| 精品久久中文字幕久久av| 久久久久久国产精品久久| 欧美激情啊啊啊| 亚洲第一视频网| 久久国产加勒比精品无码| 欧美一级高清免费播放| 97视频在线观看成人| 国产午夜精品免费一区二区三区| 日韩av在线电影网| 亚洲午夜久久久久久久| 色偷偷88888欧美精品久久久| 日韩福利伦理影院免费| 中文字幕亚洲图片| 欧美孕妇性xx| 国产精品久久久久久久久久东京| 亚洲欧美中文字幕| 中文字幕九色91在线| 欧美国产日韩一区二区在线观看| 国产精品午夜视频| 91牛牛免费视频| 国产日韩综合一区二区性色av| 欧美国产亚洲精品久久久8v| 欧美激情在线观看视频| 国产成人涩涩涩视频在线观看| 国产精品欧美日韩一区二区| 欧美人成在线视频| 亚洲奶大毛多的老太婆| 国产精品88a∨| 97在线视频一区| 国内精品中文字幕| 午夜免费久久久久| 欧美成人午夜影院| 欧美成人精品一区二区三区| 欧美天天综合色影久久精品| 久久久久久久久国产精品| 欧美寡妇偷汉性猛交| 91成人天堂久久成人| 91在线观看免费高清完整版在线观看| 亚洲色图综合网| 亚洲精品综合久久中文字幕| 欧美日韩国产综合视频在线观看中文| 亚洲色图13p| 日韩成人av一区| 91精品视频专区| 欧美日韩裸体免费视频| 中文字幕亚洲一区在线观看| 亚洲精品日韩久久久| 亚洲一区中文字幕| 欧美福利在线观看| 亚洲天天在线日亚洲洲精| 狠狠躁夜夜躁人人爽超碰91| 国产一区二区美女视频| 日韩欧美国产中文字幕| 精品日韩视频在线观看| 91色中文字幕| 国产精品视频男人的天堂| 亚洲精品按摩视频| 久久久久久国产精品久久| zzjj国产精品一区二区| 亚洲美女av在线| 欧美特级www| 日韩黄色在线免费观看| 日韩在线观看免费av| 中文字幕亚洲图片| 91精品国产综合久久香蕉的用户体验| 在线激情影院一区|