JsTree — построение простого дерева с помощью JAVA

в 16:33, , рубрики: Bootstrap, java, javascript, json, jstree, servlets, Разработка веб-сайтов

Привет! Это мой первый пост, который рассчитан на новичков в веб-программировании. Требуются знания:

— Java;
— Знать как создавать сервлет;
— HTML;
— JavaScript;
— JQuery.

Задача такова:

— На основе данных БД построить дерево на веб-странице, все дерево сразу грузить было нельзя так, как слишком много данных.

В своем посте я покажу маленький поэтапный пример того, как построить дерево с помощью сервлета и плагина JsTree, с использованием Ajax в формате JSON, данные будут генерироваться по простому алгоритму.

Весь код доступен на GitHub.

JsTree — построение простого дерева с помощью JAVA - 1

Модель

В таблице БД были записи типа {«id»,«parentId»,«text»}, для такого типа данных идеально подходит плагин JsTree. JsTree понимает данные в таком формате:

{
  id          : "string" // required
  parent      : "string" // required
  text        : "string" // node text
  icon        : "string" // string for custom
}

На деле оказалось, что нужно еще одно поле children. В него всегда надо ставить true, ничего страшного, если у элемента нет детей. После ajax запроса плагин это поймет и уберет стрелочку.

Для начала нам нужна модель:

public class Node {
  private String id;
  private String parent;
  private String text;
  private boolean children;   

    public Node(String id, String parent, String text) {
        this.id = id;
        this.parent = parent;
        this.text = text;
        this.children = true;
    }
}

Теперь стоит разобраться, как конвертировать данные в JSON, лично я использовал FasterXML/jackson-core. Для этого добавил зависимости в maven:

<dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.2.2</version>
        </dependency>

И сам метод для конвертирования:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.Map;

public class ConverterJSON {

    public static String toJSON_String(Map map) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.writeValueAsString(map.values());
    }

}

Чтобы работал метод, нужно расставить аннотации в Node:

import com.fasterxml.jackson.annotation.JsonProperty;

public class Node {
    @JsonProperty("id")
    private String id;
    @JsonProperty("parent")
    private String parent;
    @JsonProperty("text")
    private String text;
    @JsonProperty("children")
    private boolean children;

    public Node(String id, String parent, String text) {
        this.id = id;
        this.parent = parent;
        this.text = text;
        this.children = true;
    }

    public String getId() {
        return id;
    }
}

Замечательно, у нас есть модель, теперь нужны данные.

DAO

public interface Data {

    public Map getRoot();
    public Map getById(String parentId);

}

import java.util.HashMap;
import java.util.Map;
//Класс Синглтон 
public class LocalDataImpl implements Data  {
    public static final int MAX_ELEMENT = 10;

    private static LocalDataImpl ourInstance = new LocalDataImpl();

    public static LocalDataImpl getInstance() {
        return ourInstance;
    }

    private LocalDataImpl() {
    }

    @Override
    public Map getRoot() {         //Получем корень нашего дерева Это будет 10 элементов
        Map result = new HashMap();
        for (int i = 1; i < MAX_ELEMENT; i++) {
            Node node = new Node(Integer.toString(i),"#","Node "+i);      //В корне у JsTree элементы имеют родителя = "#"
            result.put(node.getId(),node);
        }
        return result;
    }

    @Override
    public Map getById(String parentId) {     //Получем детей нашего дерева Это будет тоже 10 элементов, при этом Если Родитель нечетный то у него не будей 
        Map result = new HashMap();
        if (Integer.parseInt(parentId)%2==0)
            for (int i = 1; i < MAX_ELEMENT; i++) {
                String newId = parentId+Integer.toString(i);
                Node node = new Node(newId, parentId,"Node "+newId);
                result.put(node.getId(),node);
            }
        return result;
    }
}

Controller

Теперь нужен сервлет, который будет принимать id узла родителя, и отдавать детей в формате JSON:

@WebServlet(urlPatterns = {"/ajax"})
public class AjaxTree extends HttpServlet {
    private Data data;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("application/json; charset=utf-8");
        String nodeId = request.getParameter("id");
        PrintWriter out = response.getWriter();
        try{
            if (nodeId.equals("root"))
                out.println(ConverterJSON.toJSON_String(data.getRoot()));
            else
                out.println(ConverterJSON.toJSON_String(data.getById(nodeId)));
        }catch (IOException e)
        {e.printStackTrace();}
        finally {
            out.close();
        }
    }

    @Override
    public void init() throws ServletException {
        super.init();
        data = LocalDataImpl.getInstance();
    }
}

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

Собрали проект и при использовании нашего сервлета видим:

JsTree — построение простого дерева с помощью JAVA - 2

Нечетный родитель — нет детей:

JsTree — построение простого дерева с помощью JAVA - 3

Четный — 9 штук:

JsTree — построение простого дерева с помощью JAVA - 4

Web

Теперь дело за малым, будем встраивать это чудо в страницу. Для этого нужно скачать Jquery и JsTree.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Только дерево</title>
    <link rel="stylesheet" href="themes/default/style.min.css" />
</head>
<body>
<!-- Подключаем Jquery -->
<script src="js/jquery-2.1.1.min.js"></script>
<!-- Подключаем JsTree-->
<script src="js/jstree.min.js"></script>
<!-- Плюс необходимый скрипт -->
<script>
    $(function () {
        $('#jstree')
                .jstree({
                    "plugins": [ "sort", "json_data" ],
                    'core': {
                        'data': {
                            'url': function (node) {
                                return node.id === '#' ? 'ajax?id=root' : 'ajax?id=' + node.id;  <!-- Первые адрес указывает откуда получить корень , Второй детей-->
                            },
                            'data': function (node) {
                                return { 'id': node.id };
                            }
                        }
                    }
                });
    });
</script>
<div id="jstree"></div>  <!-- Контейнер для расположения нашего дерева-->
</body>
</html>

Спасибо за внимание, надеюсь, кто-нибудь почерпнёт что-то полезное.

Автор: BioQwer

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js