Как вы можете интегрировать пользовательский браузер / загрузчик файлов с CKEditor?

112

Официальная документация не совсем ясна - как правильно интегрировать пользовательский браузер / загрузчик файлов с CKEditor? (v3 - не FCKEditor)

Дон Джонс
источник

Ответы:

175

Начните с регистрации вашего пользовательского браузера / загрузчика при создании экземпляра CKEditor. Вы можете назначить разные URL-адреса для браузера изображений и обычного файлового браузера.

<script type="text/javascript">
CKEDITOR.replace('content', {
    filebrowserBrowseUrl : '/browser/browse/type/all',
    filebrowserUploadUrl : '/browser/upload/type/all',
    filebrowserImageBrowseUrl : '/browser/browse/type/image',
filebrowserImageUploadUrl : '/browser/upload/type/image',
    filebrowserWindowWidth  : 800,
    filebrowserWindowHeight : 500
});
</script>

Ваш пользовательский код получит параметр GET с именем CKEditorFuncNum. Сохраните это - это ваша функция обратного вызова. Допустим, вы положили это в $callback.

Когда кто-то выбирает файл, запустите этот JavaScript, чтобы сообщить CKEditor, какой файл был выбран:

window.opener.CKEDITOR.tools.callFunction(<?php echo $callback; ?>,url)

Где «url» - это URL-адрес выбранного файла. Необязательный третий параметр может быть текстом, который вы хотите отображать в стандартном диалоговом окне предупреждения, например «недопустимый файл» или что-то в этом роде. Задайте для url пустую строку, если третий параметр является сообщением об ошибке.

Вкладка «загрузка» CKEditor отправит файл в поле «загрузка» - в PHP это идет в $ _FILES ['upload']. CKEditor хочет, чтобы ваш сервер выводил полный блок JavaScript:

$output = '<html><body><script type="text/javascript">window.parent.CKEDITOR.tools.callFunction('.$callback.', "'.$url.'","'.$msg.'");</script></body></html>';
echo $output;

Опять же, вам нужно передать ему этот параметр обратного вызова, URL-адрес файла и, возможно, сообщение. Если сообщение представляет собой пустую строку, ничего не отображается; если сообщение является ошибкой, тогда url должен быть пустой строкой.

Официальная документация CKEditor по всему этому неполная, но если вы последуете вышесказанному, она будет работать как чемпион.

Дон Джонс
источник
29
Я не могу поверить, что документация разработчика для этого процесса настолько скудна. Спасибо за подробности.
4
Это была отличная информация! Ваай лучше официальной документации.
Джон Ромеро
2
Большое спасибо! Но это CKEditorFunNum, а не Name = P
emzero
2
@emzero, я думаю, что это, вероятно, CKEditorFuncName, может быть, чем больше CKEditor сейчас использует CKEditorFuncNum. В любом случае ответ точен!
Росди Касим
1
Кроме того, если вам нужно скрыть «Вкладку загрузки», чтобы разрешить загрузку только изображения, вы можете использовать: CKEDITOR.on ('dialogDefinition', function (ev) {// Возьмите имя диалога и его определение из события / / data. var dialogName = ev.data.name; var dialogDefinition = ev.data.definition; // Проверяем, взято ли определение из того диалогового окна, которое // интересует (диалоговое окно Link and Image). if (dialogName = = 'link' || dialogName == 'image') {// удалить вкладку загрузки dialogDefinition.removeContents ('Загрузить');}});
Kristijan
14

Я опубликовал одно небольшое руководство по интеграции FileBrowser, доступного в старом FCKEditor, в CKEditor.

http://www.mixedwaves.com/2010/02/integrating-fckeditor-filemanager-in-ckeditor/

Он содержит пошаговые инструкции для этого, и это довольно просто. Я надеюсь, что любой, кто ищет это, найдет этот урок полезным.

Фенуил
источник
10

Я просто сам прошел через процесс обучения. Я понял это, но согласен, что документация написана таким образом, что меня это немного пугало. Большим моментом "ага" для меня было понимание того, что для просмотра все, что делает CKeditor, - это открывает новое окно и предоставляет несколько параметров в URL-адресе. Он позволяет вам добавлять дополнительные параметры, но имейте в виду, что вам нужно будет использовать encodeURIComponent () для ваших значений.

Я вызываю браузер и загрузчик с помощью

CKEDITOR.replace( 'body',  
{  
    filebrowserBrowseUrl: 'browse.php?type=Images&dir=' +  
        encodeURIComponent('content/images'),  
    filebrowserUploadUrl: 'upload.php?type=Files&dir=' +  
        encodeURIComponent('content/images')  
}

Для браузера в открытом окне (browse.php) вы используете php & js для предоставления списка вариантов, а затем после предоставленного обработчика onclick вы вызываете функцию CKeditor с двумя аргументами: URL / путь к выбранному изображению и CKEditorFuncNum, предоставленный CKeditor в URL:

function myOnclickHandler(){  
//..    
    window.opener.CKEDITOR.tools.callFunction(<?php echo $_GET['CKEditorFuncNum']; ?>, pathToImage);  
    window.close();
}       

Точно так же загрузчик просто вызывает указанный вами URL, например, upload.php , и снова предоставляет $ _GET ['CKEditorFuncNum']. Целью является iframe, поэтому после сохранения файла из $ _FILES вы передаете свой отзыв в CKeditor следующим образом:

$funcNum = $_GET['CKEditorFuncNum'];  
exit("<script>window.parent.CKEDITOR.tools.callFunction($funcNum, '$filePath', '$errorMessage');</script>");  

Ниже приведен простой для понимания сценарий настраиваемого браузера. Хотя он не позволяет пользователям перемещаться по серверу, он позволяет указать, из какого каталога извлекать файлы изображений при вызове браузера.

Это довольно простой код, поэтому он должен работать во всех относительно современных браузерах.

CKeditor просто открывает новое окно с предоставленным URL

/*          
    in CKeditor **use encodeURIComponent()** to add dir param to the filebrowserBrowseUrl property

    Replace content/images with directory where your images are housed.
*/          
        CKEDITOR.replace( 'editor1', {  
            filebrowserBrowseUrl: '**browse.php**?type=Images&dir=' + encodeURIComponent('content/images'),  
            filebrowserUploadUrl: 'upload.php?type=Files&dir=' + encodeURIComponent('content/images') 
        });   

// ========= ниже полный код для browse.php

<?php  
header("Content-Type: text/html; charset=utf-8\n");  
header("Cache-Control: no-cache, must-revalidate\n");  
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");  

// e-z params  
$dim = 150;         /* image displays proportionally within this square dimension ) */  
$cols = 4;          /* thumbnails per row */
$thumIndicator = '_th'; /* e.g., *image123_th.jpg*) -> if not using thumbNails then use empty string */  
?>  
<!DOCTYPE html>  
<html>  
<head>  
    <title>browse file</title>  
    <meta charset="utf-8">  

    <style>  
        html,  
        body {padding:0; margin:0; background:black; }  
        table {width:100%; border-spacing:15px; }  
        td {text-align:center; padding:5px; background:#181818; }  
        img {border:5px solid #303030; padding:0; verticle-align: middle;}  
        img:hover { border-color:blue; cursor:pointer; }  
    </style>  

</head>  


<body>  

<table>  

<?php  

$dir = $_GET['dir'];    

$dir = rtrim($dir, '/'); // the script will add the ending slash when appropriate  

$files = scandir($dir);  

$images = array();  

foreach($files as $file){  
    // filter for thumbNail image files (use an empty string for $thumIndicator if not using thumbnails )
    if( !preg_match('/'. $thumIndicator .'\.(jpg|jpeg|png|gif)$/i', $file) )  
        continue;  

    $thumbSrc = $dir . '/' . $file;  
    $fileBaseName = str_replace('_th.','.',$file);  

    $image_info = getimagesize($thumbSrc);  
    $_w = $image_info[0];  
    $_h = $image_info[1]; 

    if( $_w > $_h ) {       // $a is the longer side and $b is the shorter side
        $a = $_w;  
        $b = $_h;  
    } else {  
        $a = $_h;  
        $b = $_w;  
    }     

    $pct = $b / $a;     // the shorter sides relationship to the longer side

    if( $a > $dim )   
        $a = $dim;      // limit the longer side to the dimension specified

    $b = (int)($a * $pct);  // calculate the shorter side

    $width =    $_w > $_h ? $a : $b;  
    $height =   $_w > $_h ? $b : $a;  

    // produce an image tag
    $str = sprintf('<img src="%s" width="%d" height="%d" title="%s" alt="">',   
        $thumbSrc,  
        $width,  
        $height,  
        $fileBaseName  
    );  

    // save image tags in an array
    $images[] = str_replace("'", "\\'", $str); // an unescaped apostrophe would break js  

}

$numRows = floor( count($images) / $cols );  

// if there are any images left over then add another row
if( count($images) % $cols != 0 )  
    $numRows++;  


// produce the correct number of table rows with empty cells
for($i=0; $i<$numRows; $i++)   
    echo "\t<tr>" . implode('', array_fill(0, $cols, '<td></td>')) . "</tr>\n\n";  

?>  
</table>  


<script>  

// make a js array from the php array
images = [  
<?php   

foreach( $images as $v)  
    echo sprintf("\t'%s',\n", $v);  

?>];  

tbl = document.getElementsByTagName('table')[0];  

td = tbl.getElementsByTagName('td');  

// fill the empty table cells with data
for(var i=0; i < images.length; i++)  
    td[i].innerHTML = images[i];  


// event handler to place clicked image into CKeditor
tbl.onclick =   

    function(e) {  

        var tgt = e.target || event.srcElement,  
            url;  

        if( tgt.nodeName != 'IMG' )  
            return;  

        url = '<?php echo $dir;?>' + '/' + tgt.title;  

        this.onclick = null;  

        window.opener.CKEDITOR.tools.callFunction(<?php echo $_GET['CKEditorFuncNum']; ?>, url);  

        window.close();  
    }  
</script>  
</body>  
</html>            
Тим
источник
9

Я потратил некоторое время, пытаясь понять это, и вот что я сделал. Я разбил это очень просто, потому что это то, что мне нужно.

Непосредственно под текстовой областью ckeditor введите загружаемый файл следующим образом >>>>

<form action="welcomeeditupload.asp" method="post" name="deletechecked">
    <div align="center">
        <br />
        <br />
        <label></label>
        <textarea class="ckeditor" cols="80" id="editor1" name="editor1" rows="10"><%=(rslegschedule.Fields.Item("welcomevar").Value)%></textarea>
        <script type="text/javascript">
        //<![CDATA[
            CKEDITOR.replace( 'editor1',
            {
                filebrowserUploadUrl : 'updateimagedone.asp'
            });
        //]]>
        </script>
        <br />
        <br />
        <br />
        <input type="submit" value="Update">
    </div>
</form>

', а затем добавьте файл загрузки, вот мой, написанный на ASP. Если вы используете PHP и т. Д., Просто замените ASP своим сценарием загрузки, но убедитесь, что страница выводит то же самое.

<%@LANGUAGE="VBSCRIPT" CODEPAGE="65001"%>
<%
    if Request("CKEditorFuncNum")=1 then
        Set Upload = Server.CreateObject("Persits.Upload")
        Upload.OverwriteFiles = False
        Upload.SetMaxSize 5000000, True
        Upload.CodePage = 65001

        On Error Resume Next
        Upload.Save "d:\hosting\belaullach\senate\legislation"

        Dim picture
        For Each File in Upload.Files
            Ext = UCase(Right(File.Path, 3))
            If Ext <> "JPG" Then
                    If Ext <> "BMP" Then
                    Response.Write "File " & File.Path & " is not a .jpg or .bmp file." & "<BR>"
                    Response.write "You can only upload .jpg or .bmp files." & "<BR>" & "<BR>"
                    End if
            Else
                File.SaveAs Server.MapPath(("/senate/legislation") & "/" & File.fileName)
                f1=File.fileName
            End If
        Next
    End if

    fnm="/senate/legislation/"&f1
    imgop = "<html><body><script type=""text/javascript"">window.parent.CKEDITOR.tools.callFunction('1','"&fnm&"');</script></body></html>;"
    'imgop="callFunction('1','"&fnm&"',"");"
    Response.write imgop
%>
Эллиот Бензл
источник
8

Это тот подход, который я использовал. Это довольно просто и отлично работает.

В корневом каталоге редактора CK есть файл с именем config.js

Я добавил это (вам не нужны строки запроса, это только для нашего файлового менеджера). Я также добавил немного скинов и изменил показанные кнопки по умолчанию:

CKEDITOR.editorConfig = function(config) {

    config.skin = 'v2';
    config.startupFocus = false;
    config.filebrowserBrowseUrl = '/admin/content/filemanager.aspx?path=Userfiles/File&editor=FCK';
    config.filebrowserImageBrowseUrl = '/admin/content/filemanager.aspx?type=Image&path=Userfiles/Image&editor=FCK';
    config.toolbar_Full =
    [
        ['Source', '-', 'Preview', '-'],
        ['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Print', 'SpellChecker'], //, 'Scayt' 
        ['Undo', 'Redo', '-', 'Find', 'Replace', '-', 'SelectAll', 'RemoveFormat'],
        '/',
        ['Bold', 'Italic', 'Underline', 'Strike', '-', 'Subscript', 'Superscript'],
        ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', 'Blockquote'],
        ['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
        ['Link', 'Unlink', 'Anchor'],
        ['Image', 'Flash', 'Table', 'HorizontalRule', 'SpecialChar'],
        '/',
        ['Styles', 'Format', 'Templates'],
        ['Maximize', 'ShowBlocks']
    ];

};

Затем наш файловый менеджер вызывает это:

opener.SetUrl('somefilename');
ScottE
источник
7

Статья на zerokspot под названием « Пользовательские обратные вызовы файлового браузера в CKEditor 3.0» посвящена этому. Наиболее актуальный раздел цитируется ниже:

Итак, все, что вам нужно сделать из файлового браузера, когда у вас выбран файл, - это вызвать этот код с правильным номером обратного вызова (обычно 1) и URL-адресом выбранного файла:

window.opener.CKEDITOR.tools.callFunction(CKEditorFuncNum,url);

Для быстрой загрузки процесс очень похож. Сначала я подумал, что редактор может прослушивать код возврата HTTP 200 и, возможно, заглядывать в какое-то поле заголовка или что-то в этом роде, чтобы определить местоположение загруженного файла, но затем - через некоторый мониторинг Firebug - я заметил, что все, что происходит после загрузки следующий код:

<script type="text/javascript">
window.parent.CKEDITOR.tools.callFunction(CKEditorFuncNum,url, errorMessage); </script>

Если загрузка не удалась, установите errorMessageдля некоторой строки ненулевой длины и очистите URL-адрес, и наоборот в случае успеха.

тактов
источник
1
вы могли бы указать
Джон Ромеро
1
Насколько я ценю, что вы нашли мой блог, клакс, вы могли бы хотя бы связать его с ним или просто на него вообще, вместо того, чтобы копировать / вставлять мой пост в блоге.
Хорст Гутманн,
1
@Jon & @Horst: Спасибо, что указали на это. Если я вырезал что-нибудь важное, что нужно было вставить, просто дайте мне знать.
Bill the Lizard
4

Начните с регистрации вашего пользовательского браузера / загрузчика при создании экземпляра CKEditor.

<script type="text/javascript">
CKEDITOR.replace('content', {
    filebrowserUploadUrl: "Upload File Url",//http://localhost/phpwork/test/ckFileUpload.php
    filebrowserWindowWidth  : 800,
    filebrowserWindowHeight : 500
});
</script>

Код для загрузки файла (ckFileUpload.php) и поместите загружаемый файл в корневой каталог вашего проекта.

// HERE SET THE PATH TO THE FOLDERS FOR IMAGES AND AUDIO ON YOUR SERVER (RELATIVE TO THE ROOT OF YOUR WEBSITE ON SERVER)

$upload_dir = array(
 'img'=> '/phpwork/test/uploads/editor-images/',
 'audio'=> '/phpwork/ezcore_v1/uploads/editor-images/'
);

// HERE PERMISSIONS FOR IMAGE
$imgset = array(
 'maxsize' => 2000,     // maximum file size, in KiloBytes (2 MB)
 'maxwidth' => 900,     // maximum allowed width, in pixels
 'maxheight' => 800,    // maximum allowed height, in pixels
 'minwidth' => 10,      // minimum allowed width, in pixels
 'minheight' => 10,     // minimum allowed height, in pixels
 'type' => array('bmp', 'gif', 'jpg', 'jpeg', 'png'),  // allowed extensions
);

// HERE PERMISSIONS FOR AUDIO
$audioset = array(
 'maxsize' => 20000,    // maximum file size, in KiloBytes (20 MB)
 'type' => array('mp3', 'ogg', 'wav'),  // allowed extensions
);

// If 1 and filename exists, RENAME file, adding "_NR" to the end of filename (name_1.ext, name_2.ext, ..)
// If 0, will OVERWRITE the existing file
define('RENAME_F', 1);

$re = '';
if(isset($_FILES['upload']) && strlen($_FILES['upload']['name']) >1) {
  define('F_NAME', preg_replace('/\.(.+?)$/i', '', basename($_FILES['upload']['name'])));  //get filename without extension

  // get protocol and host name to send the absolute image path to CKEditor
  $protocol = !empty($_SERVER['HTTPS']) ? 'https://' : 'http://';
  $site = $protocol. $_SERVER['SERVER_NAME'] .'/';
  $sepext = explode('.', strtolower($_FILES['upload']['name']));
  $type = end($sepext);    // gets extension
  $upload_dir = in_array($type, $imgset['type']) ? $upload_dir['img'] : $upload_dir['audio'];
  $upload_dir = trim($upload_dir, '/') .'/';

  //checkings for image or audio
  if(in_array($type, $imgset['type'])){
    list($width, $height) = getimagesize($_FILES['upload']['tmp_name']);  // image width and height
    if(isset($width) && isset($height)) {
      if($width > $imgset['maxwidth'] || $height > $imgset['maxheight']) $re .= '\\n Width x Height = '. $width .' x '. $height .' \\n The maximum Width x Height must be: '. $imgset['maxwidth']. ' x '. $imgset['maxheight'];
      if($width < $imgset['minwidth'] || $height < $imgset['minheight']) $re .= '\\n Width x Height = '. $width .' x '. $height .'\\n The minimum Width x Height must be: '. $imgset['minwidth']. ' x '. $imgset['minheight'];
      if($_FILES['upload']['size'] > $imgset['maxsize']*1000) $re .= '\\n Maximum file size must be: '. $imgset['maxsize']. ' KB.';
    }
  }
  else if(in_array($type, $audioset['type'])){
    if($_FILES['upload']['size'] > $audioset['maxsize']*1000) $re .= '\\n Maximum file size must be: '. $audioset['maxsize']. ' KB.';
  }
  else $re .= 'The file: '. $_FILES['upload']['name']. ' has not the allowed extension type.';

  //set filename; if file exists, and RENAME_F is 1, set "img_name_I"
  // $p = dir-path, $fn=filename to check, $ex=extension $i=index to rename
  function setFName($p, $fn, $ex, $i){
    if(RENAME_F ==1 && file_exists($p .$fn .$ex)) return setFName($p, F_NAME .'_'. ($i +1), $ex, ($i +1));
    else return $fn .$ex;
  }

  $f_name = setFName($_SERVER['DOCUMENT_ROOT'] .'/'. $upload_dir, F_NAME, ".$type", 0);
  $uploadpath = $_SERVER['DOCUMENT_ROOT'] .'/'. $upload_dir . $f_name;  // full file path

  // If no errors, upload the image, else, output the errors
  if($re == '') {
    if(move_uploaded_file($_FILES['upload']['tmp_name'], $uploadpath)) {
      $CKEditorFuncNum = $_GET['CKEditorFuncNum'];
      $url = $site. $upload_dir . $f_name;
      $msg = F_NAME .'.'. $type .' successfully uploaded: \\n- Size: '. number_format($_FILES['upload']['size']/1024, 2, '.', '') .' KB';
      $re = in_array($type, $imgset['type']) ? "window.parent.CKEDITOR.tools.callFunction($CKEditorFuncNum, '$url', '$msg')"  //for img
       : 'var cke_ob = window.parent.CKEDITOR; for(var ckid in cke_ob.instances) { if(cke_ob.instances[ckid].focusManager.hasFocus) break;} cke_ob.instances[ckid].insertHtml(\'<audio src="'. $url .'" controls></audio>\', \'unfiltered_html\'); alert("'. $msg .'"); var dialog = cke_ob.dialog.getCurrent();  dialog.hide();';
    }
    else $re = 'alert("Unable to upload the file")';
  }
  else $re = 'alert("'. $re .'")';
}

@header('Content-type: text/html; charset=utf-8');
echo '<script>'. $re .';</script>';

Документация по Ck-редактору непонятна после большого количества исследований и разработок для пользовательской загрузки файлов, наконец, я нашел это решение. Это работает для меня, и я надеюсь, что это поможет и другим.

Рахул Шарма
источник
1

Для людей, интересующихся реализацией сервлета / JSP, вот как вы это делаете ... Я также объясню uploadimage ниже.

1) Сначала убедитесь , что вы добавили FileBrowser и uploadimage переменную в файл config.js. Сделайте так, чтобы в папке плагинов также были папки uploadimage и filebrowser .

2) В этой части меня это сбило с толку:

В документации веб-сайта Ckeditor говорится, что вам нужно использовать эти два метода:

function getUrlParam( paramName ) {
    var reParam = new RegExp( '(?:[\?&]|&)' + paramName + '=([^&]+)', 'i' );
    var match = window.location.search.match( reParam );
    return ( match && match.length > 1 ) ? match[1] : null;
}
function returnFileUrl() {
    var funcNum = getUrlParam( 'CKEditorFuncNum' );
    var fileUrl = 'https://patiliyo.com/wp-content/uploads/2017/07/ruyada-kedi-gormek.jpg';
    window.opener.CKEDITOR.tools.callFunction( funcNum, fileUrl );
    window.close();
}

Что они не упоминают, так это то, что эти методы должны быть на другой странице, а не на странице, с которой вы нажимаете кнопку просмотра сервера .

Итак, если у вас есть ckeditor, инициализированный на странице editor.jsp, вам необходимо создать файловый браузер (с базовым html / css / javascript) на странице filebrowser.jsp .

editor.jsp (все, что вам нужно, это в теге сценария) Эта страница откроет файл filebrowser.jsp в мини-окне, когда вы нажмете кнопку просмотра сервера.

CKEDITOR.replace( 'editor', {
    filebrowserBrowseUrl: '../filebrowser.jsp', //jsp page with jquery to call servlet and get image files to view
    filebrowserUploadUrl: '../UploadImage', //servlet

});

filebrowser.jsp (это созданный вами пользовательский файловый браузер, который будет содержать методы, упомянутые выше)

<head>
<script src="../../ckeditor/ckeditor.js"></script>
</head>
<body>
<script>


function getUrlParam( paramName ) {
    var reParam = new RegExp( '(?:[\?&]|&)' + paramName + '=([^&]+)', 'i' );
    var match = window.location.search.match( reParam );
    return ( match && match.length > 1 ) ? match[1] : null;
}

function returnFileUrl() {
    var funcNum = getUrlParam( 'CKEditorFuncNum' );
var fileUrl = 'https://patiliyo.com/wp-content/uploads/2017/07/ruyada-kedi-gormek.jpg';
    window.opener.CKEDITOR.tools.callFunction( funcNum, fileUrl );
    window.close();
}


//when this window opens it will load all the images which you send from the FileBrowser Servlet. 
getImages();
function getImages(){
    $.get("../FileBrowser", function(responseJson) {    
        //do something with responseJson (like create <img> tags and update the src attributes) 
    });
}

   //you call this function and pass 'fileUrl' when user clicks on an image that you loaded into this window from a servlet
returnFileUrl();
</script>
</body>

3) Сервлет FileBrowser

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Images i = new Images();
    List<ImageObject> images = i.getImages(); //get images from your database or some cloud service or whatever (easier if they are in a url ready format)
    String json = new Gson().toJson(images);
    response.setContentType("application/json");
    response.setCharacterEncoding("UTF-8");
    response.getWriter().write(json);
}

4) Сервлет UploadImage

Вернитесь в файл config.js для ckeditor и добавьте следующую строку:

//https://docs.ckeditor.com/ckeditor4/latest/guide/dev_file_upload.html
config.uploadUrl = '/UploadImage';

Затем вы также можете перетаскивать файлы:

   protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


                Images i = new Images();

   //do whatever you usually do to upload your image to your server (in my case i uploaded to google cloud storage and saved the url in a database. 

   //Now this part is important. You need to return the response in json format. And it has to look like this:

//      https://docs.ckeditor.com/ckeditor4/latest/guide/dev_file_upload.html
//      response must be in this format:
//      {
//          "uploaded": 1,
//          "fileName": "example.png",
//          "url": "https://www.cats.com/example.png"
//      }

                    String image = "https://www.cats.com/example.png";
                        ImageObject objResponse = i.getCkEditorObjectResponse(image);
                        String json = new Gson().toJson(objResponse);
                        response.setContentType("application/json");
                        response.setCharacterEncoding("UTF-8");
                        response.getWriter().write(json);
                    }
                }

И это все, ребята. Надеюсь, это кому-то поможет.

Джонатан Лалиберте
источник