1.概述
在本文中,我们将介绍如何在Spring Boot中使用CKEditor 。 在本教程中,我们将导入一个包含大量数据的XML文档,对使用GET请求将一组数据加载到CKEditor实例的能力进行编程,并执行POST请求以保存CKEditor的数据。
我们将使用的技术包括MongoDB,Thymeleaf和Spring Batch。
Github上提供了本教程的完整源代码。
2.什么是CKEditor?
CKEditor是一个基于浏览器的“所见即所得”(WYSIWYG)内容编辑器 。 CKEditor旨在将Web编辑器(如Microsoft Word和OpenOffice)中常见的文字处理器功能引入Web界面。
CKEditor在用户界面,插入内容,创作内容等方面为最终用户提供了许多功能。
有不同版本的CKEditor,但在本教程中,我们使用CKEditor4。要查看演示,请访问: https : //ckeditor.com/ckeditor-4/
3. XML文档
如前所述,我们正在此应用程序中上载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>
4.型号
对于上面的XML代码,我们可以像这样对Song进行建模:
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;
}
}
5.文件上传和处理
由于本文的重点是CKEditor和AJAX,因此我们不会详细介绍使用Spring Batch进行文件上传和处理。 我们在之前的帖子中对这个过程进行了深入的审查,但是:
6.将数据设置为CKEditor – GET请求
我们的目标是检索单个歌曲的数据并在CKEditor中显示该数据。 有两个问题要解决:检索单个歌曲的数据并将其显示在CKEditor中。
6.1客户端代码
在view.html中,我们使用Thymeleaf中的一个表来迭代 Song存储库中的每首 Song。 为了能够从服务器检索特定歌曲的数据,我们将Song的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函数中,我们使用延迟的Promise来确保在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);
};
6.2服务器端代码
getSong接受一个名为sid的参数,该参数代表Song id。 sid也是@GetMapping中的路径变量。 我们将sid视为字符串,因为这是MongoDB中Song的ID 。
我们检查Song是否已被修改,如果是,我们将检索关联的UpdatedSong实体。 如果没有,我们将以不同的方式对待歌曲。 最终,我们返回一个带有String的简单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;
}
}
7.保存CKEditor数据– POST请求
发布数据并不是很大的挑战。 但是,可以确保正确处理数据。
7.1客户端代码
由于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是“ text / html”
- dataType是“文本”
内容类型或数据类型不正确会导致错误或数据格式错误。
7.2服务器端代码
我们在POST请求的contentType中声明媒体类型为“ text / html” 。 我们需要在映射中指定将使用此映射。 因此,我们在@PostMapping中添加消耗= MediaType.TEXT_HTML_VALUE 。
我们需要注意的领域包括:
- @RequestBody字符串主体负责将变量主体设置为我们请求的内容
- 我们再次返回ResponseModel ,它是前面描述的包含数据的简单POJO
- 我们将先前修改过的SongModel与之前未修改过的SongModel区别对待
同样,像GET请求一样, sid允许我们处理正确的Song:
@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;
}
8.演示
我们访问localhost:8080 :
我们上传提供的music-example.xml文件:
我们单击“加载”以查看歌曲:
我们添加内容,然后单击“保存”:
如果返回保存的内容,则换行符可能会显示“ \ n”。 目前,对此进行讨论超出了本教程的范围。
9.结论
在本教程中,我们介绍了如何使用带有对象ID的GET请求加载数据,如何将数据设置为CKEditor实例以及如何通过POST请求将CKEditor的数据保存回数据库。 还有一些额外的代码,例如不必为数据使用两个不同的实体(原始版本和修改版本),但这希望是有启发性的。
完整的代码可以在Github上找到。
翻译自: https://www.javacodegeeks.com/2017/11/ajax-ckeditor-spring-boot.html