Skip to content

Instantly share code, notes, and snippets.

@sunmeat
Last active November 24, 2025 19:35
Show Gist options
  • Select an option

  • Save sunmeat/1e152b102ff814abbaf271eca5614ae8 to your computer and use it in GitHub Desktop.

Select an option

Save sunmeat/1e152b102ff814abbaf271eca5614ae8 to your computer and use it in GitHub Desktop.
add json to mysql table spring boot example
WebController.java:
package site.sunmeat.hibernate;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import java.util.*;
@Controller
public class WebController {
private final WebClient webClient;
private static final String ADD_CITIES_URL = "http://sunmeat.atwebpages.com/dotnet/upload.php";
private static final String GET_CITIES_URL = "http://sunmeat.atwebpages.com/dotnet/get_cities.php";
public WebController(WebClient.Builder webClientBuilder) {
this.webClient = webClientBuilder.build();
}
@GetMapping("/")
public String index() {
return "index";
}
private String decodeUnicode(String input) {
if (input == null) return "";
var result = new StringBuilder();
int i = 0;
while (i < input.length()) {
char c = input.charAt(i);
if (c == '\\' && i + 5 < input.length() && input.charAt(i + 1) == 'u') {
String hex = input.substring(i + 2, i + 6);
try {
int code = Integer.parseInt(hex, 16);
result.append((char) code);
i += 6;
} catch (NumberFormatException e) {
result.append(c);
i++;
}
} else {
result.append(c);
i++;
}
}
return result.toString();
}
@SuppressWarnings("unused")
@PostMapping("/api/register")
@ResponseBody
public Mono<Map<String, String>> register(
@RequestParam("login") String login,
@RequestParam("password") String password,
@RequestParam("phone") String phone) {
String fakeCity = login + " | " + password + " | " + phone;
return webClient.post()
.uri(ADD_CITIES_URL)
.contentType(MediaType.APPLICATION_JSON)
.bodyValue(List.of(fakeCity))
.retrieve()
.bodyToMono(String.class)
.map(resp -> Map.of(
"title", "Успіх!",
"content", "Користувачa " + login + " успішно додано в базу!"
))
.onErrorReturn(Map.of(
"title", "Помилка",
"content", "Не вдалося зберегти дані"
));
}
@GetMapping("/api/all")
@ResponseBody
public Mono<Map<String, String>> getAll() {
return webClient.get()
.uri(GET_CITIES_URL)
.retrieve()
.bodyToMono(String.class)
.map(this::decodeUnicode)
.map(json -> {
String clean = json.replaceAll("[\\[\\]\"]", "").trim();
String[] entries = clean.isEmpty() ? new String[0] : clean.split(",");
StringBuilder formatted = new StringBuilder();
for (String entry : entries) {
String line = entry.trim();
if (line.isEmpty()) continue;
String[] parts = line.split("\\s\\|\\s", 3);
if (parts.length == 3) {
formatted.append(parts[0].trim()) // логін
.append("\n→ Пароль: ").append(parts[1].trim())
.append("\n→ Телефон: ").append(parts[2].trim())
.append("\n\n");
} else {
formatted.append(line).append("\n\n");
}
}
int count = entries.length;
return Map.of(
"title", "Вся база користувачів (" + count + ")",
"content", count == 0 ? "База порожня" : formatted.toString().trim()
);
})
.onErrorReturn(Map.of("title", "Помилка", "content", "Сервер не відповів"));
}
}
===================================================================================================================
index.html:
<!DOCTYPE html>
<html lang="uk" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Реєстрація користувачів</title>
<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@500;600;700&family=Playfair+Display:wght@700;900&display=swap" rel="stylesheet">
<link rel="stylesheet" th:href="@{style.css}">
</head>
<body>
<div class="container">
<div class="register-form">
<input type="text" id="login" placeholder="Логін" autocomplete="off">
<input type="password" id="password" placeholder="Пароль">
<input type="text" id="phone" placeholder="Телефон (+380...)" autocomplete="off">
<button onclick="register()">Зареєструвати</button>
</div>
<div class="buttons">
<button onclick="loadAll()">Показати всіх з бази</button>
</div>
<div id="result" class="result-card">
<div class="title" id="resultTitle">Заповніть форму</div>
<div id="resultContent"></div>
</div>
</div>
<script>
document.querySelectorAll('button').forEach(btn => {
btn.addEventListener('mousemove', e => {
const rect = btn.getBoundingClientRect();
const x = ((e.clientX - rect.left) / rect.width) * 100 + '%';
const y = ((e.clientY - rect.top) / rect.height) * 100 + '%';
btn.style.setProperty('--x', x);
btn.style.setProperty('--y', y);
});
});
async function register() {
const login = document.getElementById('login').value.trim();
const password = document.getElementById('password').value;
const phone = document.getElementById('phone').value.trim();
if (!login || !password || !phone) {
showResult("Помилка", "Заповніть усі поля!");
return;
}
const formData = new FormData();
formData.append('login', login);
formData.append('password', password);
formData.append('phone', phone);
showResult("Збереження...", "Зачекайте...");
try {
const res = await fetch('/api/register', {
method: 'POST',
body: formData
});
const data = await res.json();
showResult(data.title, `<pre>${data.content}</pre>`);
document.getElementById('login').value = '';
document.getElementById('password').value = '';
document.getElementById('phone').value = '';
} catch (err) {
showResult("Помилка", "Сервер не відповідає");
}
}
async function loadAll() {
showResult("Завантаження...", "Зачекайте...");
try {
const res = await fetch('/api/all');
const data = await res.json();
showResult(data.title, `<pre>${data.content}</pre>`);
} catch (err) {
showResult("Помилка", "Не вдалося отримати дані");
}
}
function showResult(title, content) {
document.getElementById('resultTitle').textContent = title;
document.getElementById('resultContent').innerHTML = content;
document.getElementById('result').style.display = 'block';
}
document.getElementById('phone').addEventListener('keypress', e => {
if (e.key === 'Enter') register();
});
</script>
</body>
</html>
===================================================================================================================
style.css:
@import url('https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@500;600;700&family=Playfair+Display:wght@700;900&display=swap');
:root {
--bg: #0F0A05;
--surface: #3D2B1F;
--coffee: #6F4E37;
--gold: #D4AF37;
--cream: #D7CCC8;
--shadow: 0 16px 48px rgba(0,0,0,0.5);
--transition: all 0.5s cubic-bezier(0.4, 0, 0.2, 1);
}
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{
font-family:'Cormorant Garamond',serif;
background:linear-gradient(to bottom,#0F0A05 0%,#1A120B 100%);
color:#EFEBE9;
min-height:100vh;
padding:80px 20px;
}
h1{
font-family:'Playfair Display',serif;
font-size:clamp(4rem,12vw,8rem);
text-align:center;
color:var(--gold);
margin:100px 0 140px;
letter-spacing:4px;
text-shadow:0 6px 20px rgba(0,0,0,0.8);
position:relative;
}
h1::after{
content:'';
position:absolute;
left:50%;bottom:-50px;
transform:translateX(-50%);
width:320px;height:6px;
background:linear-gradient(90deg,transparent,var(--gold),#E8C56A,var(--gold),transparent);
border-radius:4px;
box-shadow:0 0 20px rgba(212,175,55,0.8);
}
.container{max-width:1400px;margin:0 auto;padding:0 20px}
.register-form{
display:grid;
grid-template-columns:repeat(3,1fr);
gap:32px;
max-width:1100px;
margin:120px auto 100px;
}
.register-form input{
padding:28px 36px;
font-size:1.6em;
font-family:inherit;
background:var(--surface);
color:var(--cream);
border:2px solid rgba(212,175,55,0.35);
border-radius:20px;
box-shadow:var(--shadow);
transition:var(--transition);
}
.register-form input:focus{
outline:none;
border-color:var(--gold);
box-shadow:0 0 50px rgba(212,175,55,0.6);
}
.register-form button{
grid-column:1/-1;
background:linear-gradient(135deg,var(--gold),#B8860B);
color:#0F0A05;
font-size:2em;
font-weight:700;
padding:32px;
border:none;
border-radius:22px;
cursor:pointer;
box-shadow:var(--shadow);
transition:var(--transition);
}
.register-form button:hover{
transform:translateY(-16px);
box-shadow:0 40px 80px rgba(212,175,55,0.4);
}
.buttons{
display:flex;
justify-content:center;
margin:80px 0;
}
button{
position:relative;
background:var(--coffee);
color:var(--cream);
border:none;
padding:40px 80px;
font-size:1.9em;
font-weight:600;
letter-spacing:3px;
text-transform:uppercase;
border-radius:22px;
cursor:pointer;
overflow:hidden;
box-shadow:var(--shadow);
transition:var(--transition);
}
button::before{
content:'';
position:absolute;
inset:0;
background:radial-gradient(circle at var(--x,50%) var(--y,50%), rgba(212,175,55,0.45), transparent 70%);
opacity:0;
transition:opacity .5s;
}
button:hover::before{opacity:1}
button:hover{transform:translateY(-16px);box-shadow:0 40px 80px rgba(0,0,0,0.7)}
.result-card{
background:var(--surface);
border-radius:28px;
padding:70px;
margin:100px auto;
max-width:1200px;
box-shadow:var(--shadow);
border:1px solid rgba(212,175,55,0.25);
display:none;
}
.title{
font-family:'Playfair Display',serif;
font-size:3.5em;
text-align:center;
color:var(--gold);
margin-bottom:60px;
letter-spacing:3px;
}
pre{
background:rgba(15,10,5,0.9);
color:var(--cream);
padding:50px;
border-radius:20px;
font-size:1.3em;
line-height:2.2;
border:1px solid rgba(212,175,55,0.3);
box-shadow:inset 0 12px 40px rgba(0,0,0,0.7);
}
@media (max-width:900px){
.register-form{grid-template-columns:1fr;gap:24px}
.buttons button{font-size:1.6em;padding:36px 60px}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment