JsTree — побудова простого дерева з допомогою JAVA

Привіт Хабр! Це мій перший пост, який розрахований на новачків у веб-програмуванні. Потрібні знання:

— Java;
— Знати як створювати сервлет;
— HTML;
— JavaScript;
— JQuery.

Завдання було така:

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

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

Весь код доступний на GitHub, а так розгорнутий варіант на Heroku.



Модель
В таблиці БД були записи типу {«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 Data interface {

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();
}
}

Тепер потрібно перевірити його працездатність, потрібно зібрати проект. На ділі виявляється, що це не проста справа, але не біда, є відмінна покрокова інструкція на російській мові.

Зібрали проект і при використанні нашого сервлета бачимо:



Непарний батько — немає дітей:



Парний — 9 штук:



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>

Спасибі за увагу, сподіваюся, хтось почерпне щось корисне.
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.