在本文中,我们将介绍如何将 CKEditor 与 Spring Boot 结合使用。在本教程中,我们将导入一个包含大量数据的 XML 文档,编写使用 GET 请求将一组数据加载到 CKEditor 实例的能力,并执行 POST 请求以保存 CKEditor 的数据。
我们将使用的技术包括 MongoDB、Thymeleaf 和 Spring Batch。
Github 上提供了本教程的完整源代码。
CKEditor 是一个基于浏览器的所见即所得 (WYSIWYG) 内容编辑器。 CKEditor 旨在将桌面编辑应用程序(如 Microsoft Word 和 OpenOffice)中常见的文字处理器功能引入 Web 界面。
CKEditor 在用户界面、插入内容、创作内容等方面为最终用户提供了许多功能。
CKEditor 有不同的版本,但对于本教程,我们使用的是 CKEditor 4。要查看演示,请访问:https://ckeditor.com/ckeditor-4/
如前所述,我们将在此应用程序中上传 XML 文档。 XML 数据将被插入数据库并用于本教程的其余部分。
<?xml version="1.0"?> <Music xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="MUS-1" style="1.1"> <status date="2017-11-07">draft</status> <title xmlns:xhtml="http://www.w3.org/1999/xhtml" >Guide to Music I Like - No Specific Genre</title> <description xmlns:xhtml="http://www.w3.org/1999/xhtml" >This guide presents a catalog of music that can be found on Spotify. <html:br xmlns:html="http://www.w3.org/1999/xhtml"/> <html:br xmlns:html="http://www.w3.org/1999/xhtml"/> This is a very small sample of music found on Spotify and is no way to be considered comprehensive. </description> <songs> <song> <artist> Run the Jewels </artist> <song-title>Legend Has It</song-title> </song> <song> <artist> Kendrick Lamar </artist> <song-title>ELEMENT.</song-title> </song> <song> <artist> Weird Al Yankovic </artist> <song-title>NOW That's What I Call Polka!</song-title> </song> <song> <artist> Eiffel 65 </artist> <song-title>Blue (Da Ba Dee) - DJ Ponte Ice Pop Radio</song-title> </song> <song> <artist> YTCracker </artist> <song-title>Hacker Music</song-title> </song> <song> <artist> MAN WITH A MISSION </artist> <song-title> Raise Your Flag </song-title> </song> <song> <artist> GZA, Method Man </artist> <song-title> Shadowboxin' </song-title> </song> </songs> </Music>
对于上面的 XML 代码,我们可以像这样建模一首歌曲:
public class SongModel { @Id private String id; @Indexed private String artist; @Indexed private String songTitle; @Indexed private Boolean updated; public Boolean getUpdated() { return updated; } public void setUpdated(Boolean updated) { this.updated = updated; } public String getArtist() { return artist; } public void setArtist(String artist) { this.artist = artist; } public String getSongTitle() { return songTitle; } public void setSongTitle(String songTitle) { this.songTitle = songTitle; } public String getId() { return id; } public void setId(String id) { this.id = id; } @JsonCreator public SongModel( @JsonProperty("artist") String artist, @JsonProperty("song-title") String songTitle){ this.artist = artist; this.songTitle = songTitle; } @Override public String toString() { return "Person [id=" + id + ", artist=" + artist + ", song-title=" + songTitle + "]"; } }
对于我们的应用程序,我们将区分未修改的歌曲和已在 CKEditor 中使用单独的模型和存储库修改的歌曲。
现在让我们定义什么是更新的歌曲:
public class UpdatedSong { @Id private String id; @Indexed private String artist; @Indexed private String songTitle; @Indexed private String html; @Indexed private String sid; public String getSid() { return sid; } public void setSid(String sid) { this.sid = sid; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getArtist() { return artist; } public void setArtist(String artist) { this.artist = artist; } public String getSongTitle() { return songTitle; } public void setSongTitle(String songTitle) { this.songTitle = songTitle; } public String getHtml() { return html; } public void setHtml(String html) { this.html = html; } }
由于本文的重点是 CKEditor 和 AJAX,我们不会详细介绍使用 Spring Batch 进行文件上传和处理。我们已经在这些之前的帖子中深入回顾了这个过程,但是:
我们的目标是检索单个歌曲的数据并在 CKEditor 中显示该数据。有两个问题需要解决:检索单个歌曲的数据并将其显示在 CKEditor 中。
在 view.html 中,我们使用 Thymeleaf 中的一个表来迭代歌曲存储库中的每首歌曲。为了能够从服务器检索特定歌曲的数据,我们将歌曲的 id 传递给一个函数。
以下是负责调用从服务器检索数据并随后将数据设置到 CKEditor 实例的函数的代码片段:
<table class="table datatable"> <thead> <tr> <th>Artist</th> <th>Song Title</th> <th>Load</th> </tr> </thead> <tbody> <tr th:each="songList : ${songList}"> <td th:text="${songList.artist}">Text ...</td> <td th:text="${songList.songTitle}">Text ...</td> <td><button th:onclick="|getSong('${songList.id}')|" id="button" class="btn btn-primary btn-condensed"> <i class="glyphicon glyphicon-folder-open"></i> </button></td> </tr> </tbody> </table>
如我们所见,Song 的 id 对于我们能够检索数据至关重要。
在 getSong 函数中,我们使用延迟承诺来确保 data 在 GET 请求之后设置:
function getSong(song) { $.ajax({ url : "/api/show/?sid=" + song, type : 'GET', dataType : 'text' }).then(function(data) { var length = data.length-2; var datacut = data.slice(9,length); CKEDITOR.instances.content.setData(datacut); }); $("#form").attr("action", "/api/save/?sid=" + song); };
getSong 接受一个名为sid 的参数,它代表歌曲id。 sid 也是@GetMapping 中的一个路径变量。我们将 sid 视为字符串,因为这是来自 MongoDB 的歌曲的 id 。
我们检查 Song 是否已被修改,如果是,我们检索关联的 UpdatedSong 实体。如果不是,我们将以不同的方式对待这首歌。最终,我们返回一个带有字符串的简单 POJO,用于名为 ResponseModel 的数据,但是:
@GetMapping(value={"/show/","/show/{sid}"}) public ResponseEntity<?> getSong(@RequestParam String sid, Model model){ ResponseModel response = new ResponseModel(); System.out.println("SID :::::" + sid); ArrayList<String> musicText = new ArrayList<String>(); if(sid!=null){ String sidString = sid; SongModel songModel = songDAO.findOne(sidString); System.out.println("get status of boolean during get ::::::" + songModel.getUpdated()); if(songModel.getUpdated()==false ){ musicText.add(songModel.getArtist()); musicText.add(songModel.getSongTitle()); String filterText = format.changeJsonToHTML(musicText); response.setData(filterText); } else if(songModel.getUpdated()==true){ UpdatedSong updated = updatedDAO.findBysid(sidString); String text = updated.getHtml(); System.out.println("getting the updated text ::::::::" + text); response.setData(text); } } model.addAttribute("response", response); return ResponseEntity.ok(response); }
如前所述,ResponseModel 是一个非常简单的 POJO:
public class ResponseModel { private String data; public ResponseModel(){ } public ResponseModel(String data){ this.data = data; } public String getData() { return data; } public void setData(String data) { this.data = data; } }
发布数据不是什么大问题;但是,可以确保数据得到适当处理。
由于 CKEditor 实例是表单中的文本区域,我们可以在表单提交时触发一个函数:
$(document) .ready( function() { // SUBMIT FORM $("#form").submit(function(event) { // Prevent the form from submitting via the browser. event.preventDefault(); ajaxPost(); });
ajaxPost() 检索 CKEditor 中的当前数据并将其设置为变量 formData:
function ajaxPost() { // PREPARE FORM DATA var formData = CKEDITOR.instances.content .getData(); // DO POST $ .ajax({ type : "POST", contentType : "text/html", url : $("#form").attr("action"), data : formData, dataType : 'text', success : function(result) { $("#postResultDiv") .html( " " + "Post Successfully! " + " "); console.log(result); }, error : function(e) { alert("Error!") console.log("ERROR: ", e); } }); } })
重要的是要注意:
具有不正确的 contentType 或 dataType 会导致错误或格式错误的数据。
我们在 POST 请求的 contentType 中声明媒体类型是 “text/html”。我们需要在我们的映射中指定这将被消耗。因此,我们使用 @PostMapping 添加 consumes = MediaType.TEXT_HTML_VALUE 。
我们需要注意的领域包括:
此外,与 GET 请求一样,sid 允许我们处理正确的歌曲:
@PostMapping(value={"/save/","/save/[sid]"}, consumes = MediaType.TEXT_HTML_VALUE) public @ResponseBody ResponseModel saveSong( @RequestBody String body, @RequestParam String sid){ ResponseModel response = new ResponseModel(); response.setData(body); SongModel oldSong = songDAO.findOne(sid); String songTitle = oldSong.getSongTitle(); String artistName = oldSong.getArtist(); if(oldSong.getUpdated() == false){ UpdatedSong updatedSong = new UpdatedSong(); updatedSong.setArtist(artistName); updatedSong.setSongTitle(songTitle); updatedSong.setHtml(body); updatedSong.setSid(sid); oldSong.setUpdated(true); songDAO.save(oldSong); updatedDAO.insert(updatedSong); System.out.println("get status of boolean during post :::::" + oldSong.getUpdated()); }else{ UpdatedSong currentSong = updatedDAO.findBysid(sid); currentSong.setHtml(body); updatedDAO.save(currentSong); } return response; }
我们访问 localhost:8080:
我们上传提供的 music-example.xml 文件:
我们点击“加载”一首歌曲:
我们添加内容,点击“保存”:
如果您返回保存的内容,您可能会看到换行符“\n”。目前,讨论这超出了本教程的范围。
在本教程中,我们介绍了如何使用带有对象 ID 的 GET 请求加载数据,将数据设置到 CKEditor 实例,并使用 POST 请求将 CKEditor 的数据保存回数据库。还有额外的代码,例如对数据使用两个不同的实体(原始版本和修改后的版本),这不是必需的,但希望具有指导意义。
完整代码可以在 Github 上找到。
标签2: Java教程地址:https://www.cundage.com/article/jcg-ajax-ckeditor-spring-boot.html